开发播放功能

This commit is contained in:
langhuihui
2020-06-30 07:27:26 +08:00
parent 59788b0c84
commit bf56ea418a
9 changed files with 497 additions and 457 deletions

86
main.go
View File

@@ -111,16 +111,10 @@ func (rtc *WebRTC) Play(streamPath string) bool {
Println(err)
return false
}
peerConnection.OnICEConnectionStateChange(func(connectionState ICEConnectionState) {
Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
switch connectionState {
case ICEConnectionStateDisconnected:
if rtc.Stream != nil {
rtc.Stream.Close()
}
case ICEConnectionStateConnected:
var sequence uint16
var sub Subscriber
var sps []byte
var pps []byte
sub.ID = rtc.RemoteAddr
sub.Type = "WebRTC"
nextHeader := func(ts uint32, marker bool) rtp.Header {
@@ -154,17 +148,19 @@ func (rtc *WebRTC) Play(streamPath string) bool {
if packet.IsSequence {
payload := packet.Payload[11:]
spsLen := int(payload[0])<<8 + int(payload[1])
sps := payload[2:spsLen]
sps = payload[2:spsLen]
payload = payload[3+spsLen:]
ppsLen := int(payload[0])<<8 + int(payload[1])
pps := payload[2:ppsLen]
pps = payload[2:ppsLen]
} else {
if packet.IsKeyFrame {
if err := videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(0, false),
Header: nextHeader(0, true),
Payload: stapA(sps, pps),
}); err != nil {
return err
}
} else {
}
payload := packet.Payload[5:]
for {
var naulLen = int(util.BigEndian.Uint32(payload))
@@ -184,7 +180,6 @@ func (rtc *WebRTC) Play(streamPath string) bool {
}); err != nil {
return err
}
marker = true
if _payload == nil {
break
}
@@ -192,6 +187,7 @@ func (rtc *WebRTC) Play(streamPath string) bool {
header = 64 | nalutype
part = _payload[1000:]
_payload = nil
marker = true
} else {
header = nalutype
part = _payload[1000:]
@@ -200,7 +196,7 @@ func (rtc *WebRTC) Play(streamPath string) bool {
}
} else {
if err := videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, false),
Header: nextHeader(packet.Timestamp*90, true),
Payload: _payload,
}); err != nil {
return err
@@ -220,9 +216,18 @@ func (rtc *WebRTC) Play(streamPath string) bool {
}
return nil
}
sub.Subscribe(streamPath)
}
})
go sub.Subscribe(streamPath)
// peerConnection.OnICEConnectionStateChange(func(connectionState ICEConnectionState) {
// Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
// switch connectionState {
// case ICEConnectionStateDisconnected:
// if rtc.Stream != nil {
// rtc.Stream.Close()
// }
// case ICEConnectionStateConnected:
// }
// })
return true
}
func (rtc *WebRTC) Publish(streamPath string) bool {
@@ -289,24 +294,13 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
}
return true
}
func (rtc *WebRTC) GetAnswer(offer SessionDescription) ([]byte, error) {
if err := rtc.SetRemoteDescription(offer); err != nil {
Println(err)
return nil, err
}
// Create answer
answer, err := rtc.CreateAnswer(nil)
if err != nil {
Println(err)
return nil, err
}
func (rtc *WebRTC) GetAnswer(localSdp SessionDescription) ([]byte, error) {
// Sets the LocalDescription, and starts our UDP listeners
if err = rtc.SetLocalDescription(answer); err != nil {
if err := rtc.SetLocalDescription(localSdp); err != nil {
Println(err)
return nil, err
}
if bytes, err := json.Marshal(answer); err != nil {
if bytes, err := json.Marshal(localSdp); err != nil {
Println(err)
return bytes, err
} else {
@@ -316,17 +310,22 @@ func (rtc *WebRTC) GetAnswer(offer SessionDescription) ([]byte, error) {
func run() {
http.HandleFunc("/webrtc/play", func(w http.ResponseWriter, r *http.Request) {
streamPath := r.URL.Query().Get("streamPath")
offer := SessionDescription{}
bytes, err := ioutil.ReadAll(r.Body)
err = json.Unmarshal(bytes, &offer)
// offer := SessionDescription{}
// bytes, err := ioutil.ReadAll(r.Body)
// err = json.Unmarshal(bytes, &offer)
// if err != nil {
// Println(err)
// return
// }
rtc := new(WebRTC)
rtc.RemoteAddr = r.RemoteAddr
if rtc.Play(streamPath) {
offer, err := rtc.CreateOffer(nil)
if err != nil {
Println(err)
return
}
rtc := new(WebRTC)
rtc.RemoteAddr = r.RemoteAddr
if rtc.Play(streamPath) {
if bytes, err = rtc.GetAnswer(offer); err == nil {
if bytes, err := rtc.GetAnswer(offer); err == nil {
w.Write(bytes)
} else {
Println(err)
@@ -349,7 +348,16 @@ func run() {
rtc := new(WebRTC)
rtc.RemoteAddr = r.RemoteAddr
if rtc.Publish(streamPath) {
if bytes, err = rtc.GetAnswer(offer); err == nil {
if err := rtc.SetRemoteDescription(offer); err != nil {
Println(err)
return
}
answer, err := rtc.CreateAnswer(nil)
if err != nil {
Println(err)
return
}
if bytes, err = rtc.GetAnswer(answer); err == nil {
w.Write(bytes)
} else {
Println(err)

View File

@@ -165,21 +165,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
/***/ }),
/***/ "8dc9":
/***/ "8e55":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "c857":
/***/ "e91a":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("8dc9");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("8e55");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
@@ -214,12 +214,12 @@ if (typeof window !== 'undefined') {
// Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"7d106341-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=3d66f6b2&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 1)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.localSDP || _vm.ask)?_c('span',{staticClass:"blink"},[_vm._v("Connecting")]):(_vm.iceConnectionState!='connected')?[_c('m-button',{on:{"click":function($event){return _vm.startSession('publish')}}},[_vm._v("Publish")]),_c('m-button',{on:{"click":function($event){return _vm.startSession('play')}}},[_vm._v("Play")])]:(_vm.iceConnectionState=='connected')?_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],2)])}
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"7d106341-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=03ea1df8&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 1)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.localSDP || _vm.ask)?_c('span',{staticClass:"blink"},[_vm._v("Connecting")]):_vm._e(),[_c('m-button',{on:{"click":function($event){return _vm.startSession('publish')}}},[_vm._v("Publish")]),_c('m-button',{on:{"click":function($event){return _vm.startSession('play')}}},[_vm._v("Play")])],_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],2)])}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=3d66f6b2&scoped=true&
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=03ea1df8&scoped=true&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
//
@@ -242,7 +242,7 @@ var staticRenderFns = []
//
const config = {
iceServers:[
iceServers: [
// {
// urls:[
// "stun:stun.ekiga.net",
@@ -267,78 +267,89 @@ const config = {
// ]
// }
]
}
};
let pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc"
var stream = null;
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
data() {
return {
localSDP: pc&&pc.localDescription&&pc.localDescription.sdp,
remoteSDP: pc&&pc.remoteDescription&&pc.remoteDescription.sdp,
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState:pc&&pc.iceConnectionState,
iceConnectionState: pc && pc.iceConnectionState,
stream,
type:"",
ask:false
type: "",
ask: false
};
},
methods: {
startSession(type) {
this.type = type
this.ask = true
this.ajax({type: 'POST',processData:false,data: JSON.stringify(pc.localDescription),url:"/webrtc/"+type+"?streamPath="+this.streamPath,dataType:"json"}).then(result => {
this.ask = false
if (result.errmsg){
this.$toast.error(result.errmsg)
}else{
streamPath = this.streamPath
async startSession(type) {
this.type = type;
this.ask = true;
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json"
});
this.ask = false;
if (result.errmsg) {
this.$toast.error(result.errmsg);
} else {
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP","remoteSDP"];
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
}
});
},
stopSession(){
pc.close()
pc = new RTCPeerConnection(config)
this.remoteSDP = ""
this.localSDP = ""
this.connectICE().catch(err=> this.$toast.error(err.message))
},
async connectICE(){
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState)
this.iceConnectionState = pc.iceConnectionState
).sdp;
} else {
pc.ontrack = event => {
if(event.streams[0].id=="monibuca")
this.stream = stream = event.streams[0];
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.localSDP = pc.localDescription.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
pc.ontrack = event=>{
if(this.type=="play" && event.streams[0]){
this.stream = stream = event.streams[0]
}
}
},
stopSession() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
}
},
async mounted() {
if (this.localSDP){
let tabs = ["摄像头"]
if(this.localSDP)tabs.push("localSDP")
if(this.remoteSDP)tabs.push("remoteSDP")
pc.onsignalingstatechange = e => {
console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
if (this.localSDP) {
let tabs = ["摄像头"];
if (this.localSDP) tabs.push("localSDP");
if (this.remoteSDP) tabs.push("remoteSDP");
this.$parent.titleTabs = tabs;
} else {
try{
if(!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
await this.connectICE()
}catch(err){
this.$toast.error(err.message)
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
}
@@ -346,8 +357,8 @@ var streamPath = "live/rtc"
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js&
/* harmony default export */ var src_Appvue_type_script_lang_js_ = (Appvue_type_script_lang_js_);
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=3d66f6b2&scoped=true&lang=css&
var Appvue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css_ = __webpack_require__("c857");
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=03ea1df8&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a");
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */
@@ -464,7 +475,7 @@ var component = normalizeComponent(
staticRenderFns,
false,
null,
"3d66f6b2",
"03ea1df8",
null
)

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
@-webkit-keyframes blink-data-v-3d66f6b2{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes blink-data-v-3d66f6b2{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.blink[data-v-3d66f6b2]{-webkit-animation:blink-data-v-3d66f6b2 1s infinite;animation:blink-data-v-3d66f6b2 1s infinite}
@-webkit-keyframes blink-data-v-03ea1df8{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes blink-data-v-03ea1df8{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.blink[data-v-03ea1df8]{-webkit-animation:blink-data-v-03ea1df8 1s infinite;animation:blink-data-v-03ea1df8 1s infinite}

View File

@@ -174,21 +174,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
/***/ }),
/***/ "8dc9":
/***/ "8e55":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "c857":
/***/ "e91a":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("8dc9");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("8e55");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
@@ -223,12 +223,12 @@ if (typeof window !== 'undefined') {
// Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"7d106341-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=3d66f6b2&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 1)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.localSDP || _vm.ask)?_c('span',{staticClass:"blink"},[_vm._v("Connecting")]):(_vm.iceConnectionState!='connected')?[_c('m-button',{on:{"click":function($event){return _vm.startSession('publish')}}},[_vm._v("Publish")]),_c('m-button',{on:{"click":function($event){return _vm.startSession('play')}}},[_vm._v("Play")])]:(_vm.iceConnectionState=='connected')?_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],2)])}
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"7d106341-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=03ea1df8&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 1)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.localSDP || _vm.ask)?_c('span',{staticClass:"blink"},[_vm._v("Connecting")]):_vm._e(),[_c('m-button',{on:{"click":function($event){return _vm.startSession('publish')}}},[_vm._v("Publish")]),_c('m-button',{on:{"click":function($event){return _vm.startSession('play')}}},[_vm._v("Play")])],_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],2)])}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=3d66f6b2&scoped=true&
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=03ea1df8&scoped=true&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
//
@@ -251,7 +251,7 @@ var staticRenderFns = []
//
const config = {
iceServers:[
iceServers: [
// {
// urls:[
// "stun:stun.ekiga.net",
@@ -276,78 +276,89 @@ const config = {
// ]
// }
]
}
};
let pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc"
var stream = null;
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
data() {
return {
localSDP: pc&&pc.localDescription&&pc.localDescription.sdp,
remoteSDP: pc&&pc.remoteDescription&&pc.remoteDescription.sdp,
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState:pc&&pc.iceConnectionState,
iceConnectionState: pc && pc.iceConnectionState,
stream,
type:"",
ask:false
type: "",
ask: false
};
},
methods: {
startSession(type) {
this.type = type
this.ask = true
this.ajax({type: 'POST',processData:false,data: JSON.stringify(pc.localDescription),url:"/webrtc/"+type+"?streamPath="+this.streamPath,dataType:"json"}).then(result => {
this.ask = false
if (result.errmsg){
this.$toast.error(result.errmsg)
}else{
streamPath = this.streamPath
async startSession(type) {
this.type = type;
this.ask = true;
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json"
});
this.ask = false;
if (result.errmsg) {
this.$toast.error(result.errmsg);
} else {
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP","remoteSDP"];
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
}
});
},
stopSession(){
pc.close()
pc = new RTCPeerConnection(config)
this.remoteSDP = ""
this.localSDP = ""
this.connectICE().catch(err=> this.$toast.error(err.message))
},
async connectICE(){
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState)
this.iceConnectionState = pc.iceConnectionState
).sdp;
} else {
pc.ontrack = event => {
if(event.streams[0].id=="monibuca")
this.stream = stream = event.streams[0];
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.localSDP = pc.localDescription.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
pc.ontrack = event=>{
if(this.type=="play" && event.streams[0]){
this.stream = stream = event.streams[0]
}
}
},
stopSession() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
}
},
async mounted() {
if (this.localSDP){
let tabs = ["摄像头"]
if(this.localSDP)tabs.push("localSDP")
if(this.remoteSDP)tabs.push("remoteSDP")
pc.onsignalingstatechange = e => {
console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
if (this.localSDP) {
let tabs = ["摄像头"];
if (this.localSDP) tabs.push("localSDP");
if (this.remoteSDP) tabs.push("remoteSDP");
this.$parent.titleTabs = tabs;
} else {
try{
if(!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
await this.connectICE()
}catch(err){
this.$toast.error(err.message)
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
}
@@ -355,8 +366,8 @@ var streamPath = "live/rtc"
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js&
/* harmony default export */ var src_Appvue_type_script_lang_js_ = (Appvue_type_script_lang_js_);
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=3d66f6b2&scoped=true&lang=css&
var Appvue_type_style_index_0_id_3d66f6b2_scoped_true_lang_css_ = __webpack_require__("c857");
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=03ea1df8&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a");
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */
@@ -473,7 +484,7 @@ var component = normalizeComponent(
staticRenderFns,
false,
null,
"3d66f6b2",
"03ea1df8",
null
)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,11 +5,11 @@
<div v-else>
<mu-text-field v-model="streamPath" label="streamPath"></mu-text-field>
<span class="blink" v-if="!localSDP || ask">Connecting</span>
<template v-else-if="iceConnectionState!='connected'">
<template>
<m-button @click="startSession('publish')">Publish</m-button>
<m-button @click="startSession('play')">Play</m-button>
</template>
<m-button @click="stopSession" v-else-if="iceConnectionState=='connected'">Stop</m-button>
<m-button @click="stopSession">Stop</m-button>
<br />
<video ref="video1" :srcObject.prop="stream" width="640" height="480" autoplay muted></video>
</div>
@@ -18,7 +18,7 @@
<script>
const config = {
iceServers:[
iceServers: [
// {
// urls:[
// "stun:stun.ekiga.net",
@@ -43,78 +43,89 @@ const config = {
// ]
// }
]
}
};
let pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc"
var stream = null;
var streamPath = "live/rtc";
export default {
data() {
return {
localSDP: pc&&pc.localDescription&&pc.localDescription.sdp,
remoteSDP: pc&&pc.remoteDescription&&pc.remoteDescription.sdp,
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState:pc&&pc.iceConnectionState,
iceConnectionState: pc && pc.iceConnectionState,
stream,
type:"",
ask:false
type: "",
ask: false
};
},
methods: {
startSession(type) {
this.type = type
this.ask = true
this.ajax({type: 'POST',processData:false,data: JSON.stringify(pc.localDescription),url:"/webrtc/"+type+"?streamPath="+this.streamPath,dataType:"json"}).then(result => {
this.ask = false
if (result.errmsg){
this.$toast.error(result.errmsg)
}else{
streamPath = this.streamPath
async startSession(type) {
this.type = type;
this.ask = true;
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json"
});
this.ask = false;
if (result.errmsg) {
this.$toast.error(result.errmsg);
} else {
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP","remoteSDP"];
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
}
});
},
stopSession(){
pc.close()
pc = new RTCPeerConnection(config)
this.remoteSDP = ""
this.localSDP = ""
this.connectICE().catch(err=> this.$toast.error(err.message))
},
async connectICE(){
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState)
this.iceConnectionState = pc.iceConnectionState
).sdp;
} else {
pc.ontrack = event => {
if(event.streams[0].id=="monibuca")
this.stream = stream = event.streams[0];
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.localSDP = pc.localDescription.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
pc.ontrack = event=>{
if(this.type=="play" && event.streams[0]){
this.stream = stream = event.streams[0]
}
}
},
stopSession() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
}
},
async mounted() {
if (this.localSDP){
let tabs = ["摄像头"]
if(this.localSDP)tabs.push("localSDP")
if(this.remoteSDP)tabs.push("remoteSDP")
pc.onsignalingstatechange = e => {
console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
if (event.candidate === null) {
this.$parent.titleTabs = ["摄像头", "localSDP"];
}
};
if (this.localSDP) {
let tabs = ["摄像头"];
if (this.localSDP) tabs.push("localSDP");
if (this.remoteSDP) tabs.push("remoteSDP");
this.$parent.titleTabs = tabs;
} else {
try{
if(!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
await this.connectICE()
}catch(err){
this.$toast.error(err.message)
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
}
@@ -122,7 +133,7 @@ export default {
</script>
<style scoped>
@keyframes blink {
@keyframes blink {
0% {
opacity: 0.2;
}
@@ -132,9 +143,8 @@ export default {
100% {
opacity: 0.2;
}
}
.blink {
}
.blink {
animation: blink 1s infinite;
}
}
</style>