Browse Source

开发播放功能

v4
langhuihui 4 years ago
parent
commit
4922863211
  1. 154
      main.go
  2. 106
      ui/dist/plugin-webrtc.common.js
  3. 2
      ui/dist/plugin-webrtc.common.js.map
  4. 2
      ui/dist/plugin-webrtc.css
  5. 106
      ui/dist/plugin-webrtc.umd.js
  6. 2
      ui/dist/plugin-webrtc.umd.js.map
  7. 2
      ui/dist/plugin-webrtc.umd.min.js
  8. 2
      ui/dist/plugin-webrtc.umd.min.js.map
  9. 60
      ui/src/App.vue

154
main.go

@ -55,6 +55,7 @@ var api *API
var SSRC uint32 var SSRC uint32
var SSRCMap = make(map[string]uint32) var SSRCMap = make(map[string]uint32)
var ssrcLock sync.Mutex var ssrcLock sync.Mutex
var playWaitList sync.Map
func init() { func init() {
m.RegisterCodec(NewRTPH264Codec(DefaultPayloadTypeH264, 90000)) m.RegisterCodec(NewRTPH264Codec(DefaultPayloadTypeH264, 90000))
@ -72,45 +73,18 @@ type WebRTC struct {
RTP RTP
*PeerConnection *PeerConnection
RemoteAddr string RemoteAddr string
videoTrack *Track
} }
func (rtc *WebRTC) Play(streamPath string) bool { func (rtc *WebRTC) Play(streamPath string) bool {
peerConnection, err := api.NewPeerConnection(Configuration{ rtc.OnICEConnectionStateChange(func(connectionState ICEConnectionState) {
ICEServers: []ICEServer{ Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
{ switch connectionState {
URLs: config.ICEServers, case ICEConnectionStateDisconnected:
}, if rtc.Stream != nil {
}, rtc.Stream.Close()
})
if _, err = peerConnection.AddTransceiverFromKind(RTPCodecTypeVideo); err != nil {
if err != nil {
Println(err)
return false
}
}
if err != nil {
return false
}
rtc.PeerConnection = peerConnection
// Create a video track, using the same SSRC as the incoming RTP Packet
ssrcLock.Lock()
ssrc, ok := SSRCMap[streamPath]
if !ok {
SSRC++
ssrc = SSRC
SSRCMap[streamPath] = SSRC
}
ssrcLock.Unlock()
videoTrack, err := peerConnection.NewTrack(DefaultPayloadTypeH264, ssrc, "video", "monibuca")
if err != nil {
Println(err)
return false
}
if _, err = peerConnection.AddTrack(videoTrack); err != nil {
Println(err)
return false
} }
case ICEConnectionStateConnected:
var sequence uint16 var sequence uint16
var sub Subscriber var sub Subscriber
var sps []byte var sps []byte
@ -121,7 +95,7 @@ func (rtc *WebRTC) Play(streamPath string) bool {
sequence++ sequence++
return rtp.Header{ return rtp.Header{
Version: 2, Version: 2,
SSRC: ssrc, SSRC: SSRC,
PayloadType: DefaultPayloadTypeH264, PayloadType: DefaultPayloadTypeH264,
SequenceNumber: sequence, SequenceNumber: sequence,
Timestamp: ts, Timestamp: ts,
@ -154,8 +128,8 @@ func (rtc *WebRTC) Play(streamPath string) bool {
pps = payload[2:ppsLen] pps = payload[2:ppsLen]
} else { } else {
if packet.IsKeyFrame { if packet.IsKeyFrame {
if err := videoTrack.WriteRTP(&rtp.Packet{ if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(0, true), Header: nextHeader(packet.Timestamp*90, true),
Payload: stapA(sps, pps), Payload: stapA(sps, pps),
}); err != nil { }); err != nil {
return err return err
@ -167,14 +141,13 @@ func (rtc *WebRTC) Play(streamPath string) bool {
payload = payload[4:] payload = payload[4:]
_payload := payload[:naulLen] _payload := payload[:naulLen]
if naulLen > 1000 { if naulLen > 1000 {
part := _payload[:1000] indicator := (_payload[0] & 224) | 28
indicator := ((part[0] >> 5) << 5) | 28 nalutype := _payload[0] & 31
nalutype := part[0] & 31
header := 128 | nalutype header := 128 | nalutype
part = part[1:] part := _payload[1:1000]
marker := false marker := false
for { for {
if err := videoTrack.WriteRTP(&rtp.Packet{ if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, marker), Header: nextHeader(packet.Timestamp*90, marker),
Payload: append([]byte{indicator, header}, part...), Payload: append([]byte{indicator, header}, part...),
}); err != nil { }); err != nil {
@ -183,19 +156,19 @@ func (rtc *WebRTC) Play(streamPath string) bool {
if _payload == nil { if _payload == nil {
break break
} }
if len(_payload[1000:]) <= 1000 { _payload = _payload[1000:]
if len(_payload) <= 1000 {
header = 64 | nalutype header = 64 | nalutype
part = _payload[1000:] part = _payload
_payload = nil _payload = nil
marker = true marker = true
} else { } else {
header = nalutype header = nalutype
part = _payload[1000:] part = _payload[:1000]
_payload = part
} }
} }
} else { } else {
if err := videoTrack.WriteRTP(&rtp.Packet{ if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, true), Header: nextHeader(packet.Timestamp*90, true),
Payload: _payload, Payload: _payload,
}); err != nil { }); err != nil {
@ -217,17 +190,8 @@ func (rtc *WebRTC) Play(streamPath string) bool {
return nil return nil
} }
go 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 return true
} }
func (rtc *WebRTC) Publish(streamPath string) bool { func (rtc *WebRTC) Publish(streamPath string) bool {
@ -310,16 +274,68 @@ func (rtc *WebRTC) GetAnswer(localSdp SessionDescription) ([]byte, error) {
func run() { func run() {
http.HandleFunc("/webrtc/play", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/webrtc/play", func(w http.ResponseWriter, r *http.Request) {
streamPath := r.URL.Query().Get("streamPath") streamPath := r.URL.Query().Get("streamPath")
// offer := SessionDescription{} offer := SessionDescription{}
// bytes, err := ioutil.ReadAll(r.Body) bytes, err := ioutil.ReadAll(r.Body)
// err = json.Unmarshal(bytes, &offer) err = json.Unmarshal(bytes, &offer)
// if err != nil { if err != nil {
// Println(err) Println(err)
// return return
// } }
if value, ok := playWaitList.Load(streamPath); ok {
rtc := value.(*WebRTC)
if err := rtc.SetRemoteDescription(offer); err != nil {
Println(err)
return
}
if rtc.Play(streamPath) {
w.Write([]byte(`success`))
} else {
w.Write([]byte(`{"errmsg":"bad name"}`))
}
} else {
w.Write([]byte(`{"errmsg":"bad name"}`))
}
})
http.HandleFunc("/webrtc/preparePlay", func(w http.ResponseWriter, r *http.Request) {
streamPath := r.URL.Query().Get("streamPath")
rtc := new(WebRTC) rtc := new(WebRTC)
peerConnection, err := api.NewPeerConnection(Configuration{
ICEServers: []ICEServer{
{
URLs: config.ICEServers,
},
},
})
if _, err = peerConnection.AddTransceiverFromKind(RTPCodecTypeVideo); err != nil {
if err != nil {
Println(err)
return
}
}
if err != nil {
return
}
rtc.PeerConnection = peerConnection
// Create a video track, using the same SSRC as the incoming RTP Packet
ssrcLock.Lock()
if _, ok := SSRCMap[streamPath]; !ok {
SSRC++
SSRCMap[streamPath] = SSRC
}
ssrcLock.Unlock()
videoTrack, err := rtc.NewTrack(DefaultPayloadTypeH264, SSRC, "video", "monibuca")
if err != nil {
Println(err)
return
}
if _, err = rtc.AddTrack(videoTrack); err != nil {
Println(err)
return
}
rtc.videoTrack = videoTrack
playWaitList.Store(streamPath, rtc)
rtc.RemoteAddr = r.RemoteAddr rtc.RemoteAddr = r.RemoteAddr
if rtc.Play(streamPath) {
offer, err := rtc.CreateOffer(nil) offer, err := rtc.CreateOffer(nil)
if err != nil { if err != nil {
Println(err) Println(err)
@ -332,9 +348,6 @@ func run() {
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
} else {
w.Write([]byte(`{"errmsg":"bad name"}`))
}
}) })
http.HandleFunc("/webrtc/publish", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/webrtc/publish", func(w http.ResponseWriter, r *http.Request) {
streamPath := r.URL.Query().Get("streamPath") streamPath := r.URL.Query().Get("streamPath")
@ -364,6 +377,7 @@ func run() {
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
w.Write([]byte(`success`))
} else { } else {
w.Write([]byte(`{"errmsg":"bad name"}`)) w.Write([]byte(`{"errmsg":"bad name"}`))
} }

106
ui/dist/plugin-webrtc.common.js

@ -87,6 +87,24 @@ module.exports =
/************************************************************************/ /************************************************************************/
/******/ ({ /******/ ({
/***/ "11a1":
/***/ (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_09aaef78_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("30b5");
/* 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_09aaef78_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_09aaef78_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_09aaef78_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ "30b5":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "8875": /***/ "8875":
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
@ -163,24 +181,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
})); }));
/***/ }),
/***/ "8e55":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "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_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_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }), /***/ }),
/***/ "fb15": /***/ "fb15":
@ -214,12 +214,12 @@ if (typeof window !== 'undefined') {
// Indicate to webpack that this file can be concatenated // Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null); /* 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=03ea1df8&scoped=true& // 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=09aaef78&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 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 = [] var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=03ea1df8&scoped=true& // CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=09aaef78&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& // 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&
// //
@ -287,32 +287,52 @@ var streamPath = "live/rtc";
async startSession(type) { async startSession(type) {
this.type = type; this.type = type;
this.ask = true; this.ask = true;
if (type == "play") {
const result = await this.ajax({ const result = await this.ajax({
type: "POST", url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json" dataType: "json"
}); });
this.ask = false;
if (result.errmsg) { if (result.errmsg) {
this.$toast.error(result.errmsg); this.$toast.error(result.errmsg);
return;
} else { } else {
streamPath = this.streamPath; streamPath = this.streamPath;
this.remoteSDP = result.sdp; this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
).sdp;
} else {
pc.ontrack = event => { pc.ontrack = event => {
console.log(event)
if (event.streams[0].id == "monibuca") if (event.streams[0].id == "monibuca")
this.stream = stream = event.streams[0]; this.stream = stream = event.streams[0];
}; };
await pc.setRemoteDescription(
new RTCSessionDescription(result)
);
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
} else {
pc.addStream(stream);
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
}
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!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
}
if (type == "play") {
} else {
this.remoteSDP = result.sdp;
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
}, },
stopSession() { stopSession() {
@ -332,17 +352,8 @@ var streamPath = "live/rtc";
this.$toast.info(pc.iceConnectionState); this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => { pc.onicecandidate = event => {};
if (event.candidate === null) { this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
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 { try {
if (!this.stream) if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia( this.stream = stream = await navigator.mediaDevices.getUserMedia(
@ -352,13 +363,12 @@ var streamPath = "live/rtc";
this.$toast.error(err.message); this.$toast.error(err.message);
} }
} }
}
}); });
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js& // 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_); /* 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=03ea1df8&scoped=true&lang=css& // EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=09aaef78&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a"); var Appvue_type_style_index_0_id_09aaef78_scoped_true_lang_css_ = __webpack_require__("11a1");
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */ /* globals __VUE_SSR_CONTEXT__ */
@ -475,7 +485,7 @@ var component = normalizeComponent(
staticRenderFns, staticRenderFns,
false, false,
null, null,
"03ea1df8", "09aaef78",
null null
) )

2
ui/dist/plugin-webrtc.common.js.map

File diff suppressed because one or more lines are too long

2
ui/dist/plugin-webrtc.css

@ -1 +1 @@
@-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} @-webkit-keyframes blink-data-v-09aaef78{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes blink-data-v-09aaef78{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.blink[data-v-09aaef78]{-webkit-animation:blink-data-v-09aaef78 1s infinite;animation:blink-data-v-09aaef78 1s infinite}

106
ui/dist/plugin-webrtc.umd.js

@ -96,6 +96,24 @@ return /******/ (function(modules) { // webpackBootstrap
/************************************************************************/ /************************************************************************/
/******/ ({ /******/ ({
/***/ "11a1":
/***/ (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_09aaef78_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("30b5");
/* 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_09aaef78_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_09aaef78_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_09aaef78_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ "30b5":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "8875": /***/ "8875":
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
@ -172,24 +190,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
})); }));
/***/ }),
/***/ "8e55":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "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_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_03ea1df8_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }), /***/ }),
/***/ "fb15": /***/ "fb15":
@ -223,12 +223,12 @@ if (typeof window !== 'undefined') {
// Indicate to webpack that this file can be concatenated // Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null); /* 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=03ea1df8&scoped=true& // 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=09aaef78&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 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 = [] var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=03ea1df8&scoped=true& // CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=09aaef78&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& // 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&
// //
@ -296,32 +296,52 @@ var streamPath = "live/rtc";
async startSession(type) { async startSession(type) {
this.type = type; this.type = type;
this.ask = true; this.ask = true;
if (type == "play") {
const result = await this.ajax({ const result = await this.ajax({
type: "POST", url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json" dataType: "json"
}); });
this.ask = false;
if (result.errmsg) { if (result.errmsg) {
this.$toast.error(result.errmsg); this.$toast.error(result.errmsg);
return;
} else { } else {
streamPath = this.streamPath; streamPath = this.streamPath;
this.remoteSDP = result.sdp; this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
).sdp;
} else {
pc.ontrack = event => { pc.ontrack = event => {
console.log(event)
if (event.streams[0].id == "monibuca") if (event.streams[0].id == "monibuca")
this.stream = stream = event.streams[0]; this.stream = stream = event.streams[0];
}; };
await pc.setRemoteDescription(
new RTCSessionDescription(result)
);
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
} else {
pc.addStream(stream);
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
}
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!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
}
if (type == "play") {
} else {
this.remoteSDP = result.sdp;
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
}, },
stopSession() { stopSession() {
@ -341,17 +361,8 @@ var streamPath = "live/rtc";
this.$toast.info(pc.iceConnectionState); this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => { pc.onicecandidate = event => {};
if (event.candidate === null) { this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
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 { try {
if (!this.stream) if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia( this.stream = stream = await navigator.mediaDevices.getUserMedia(
@ -361,13 +372,12 @@ var streamPath = "live/rtc";
this.$toast.error(err.message); this.$toast.error(err.message);
} }
} }
}
}); });
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js& // 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_); /* 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=03ea1df8&scoped=true&lang=css& // EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=09aaef78&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a"); var Appvue_type_style_index_0_id_09aaef78_scoped_true_lang_css_ = __webpack_require__("11a1");
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */ /* globals __VUE_SSR_CONTEXT__ */
@ -484,7 +494,7 @@ var component = normalizeComponent(
staticRenderFns, staticRenderFns,
false, false,
null, null,
"03ea1df8", "09aaef78",
null null
) )

2
ui/dist/plugin-webrtc.umd.js.map

File diff suppressed because one or more lines are too long

2
ui/dist/plugin-webrtc.umd.min.js

File diff suppressed because one or more lines are too long

2
ui/dist/plugin-webrtc.umd.min.js.map

File diff suppressed because one or more lines are too long

60
ui/src/App.vue

@ -63,32 +63,52 @@ export default {
async startSession(type) { async startSession(type) {
this.type = type; this.type = type;
this.ask = true; this.ask = true;
if (type == "play") {
const result = await this.ajax({ const result = await this.ajax({
type: "POST", url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath,
dataType: "json" dataType: "json"
}); });
this.ask = false;
if (result.errmsg) { if (result.errmsg) {
this.$toast.error(result.errmsg); this.$toast.error(result.errmsg);
return;
} else { } else {
streamPath = this.streamPath; streamPath = this.streamPath;
this.remoteSDP = result.sdp; this.remoteSDP = result.sdp;
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
if (type == "publish") {
pc.addStream(stream);
this.localSDP = (
await pc.setLocalDescription(await pc.createOffer())
).sdp;
} else {
pc.ontrack = event => { pc.ontrack = event => {
console.log(event)
if (event.streams[0].id == "monibuca") if (event.streams[0].id == "monibuca")
this.stream = stream = event.streams[0]; this.stream = stream = event.streams[0];
}; };
await pc.setRemoteDescription(
new RTCSessionDescription(result)
);
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
} else {
pc.addStream(stream);
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
}
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!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
}
if (type == "play") {
} else {
this.remoteSDP = result.sdp;
pc.setRemoteDescription(new RTCSessionDescription(result));
} }
}, },
stopSession() { stopSession() {
@ -108,17 +128,8 @@ export default {
this.$toast.info(pc.iceConnectionState); this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => { pc.onicecandidate = event => {};
if (event.candidate === null) { this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
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 { try {
if (!this.stream) if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia( this.stream = stream = await navigator.mediaDevices.getUserMedia(
@ -128,7 +139,6 @@ export default {
this.$toast.error(err.message); this.$toast.error(err.message);
} }
} }
}
}; };
</script> </script>

Loading…
Cancel
Save