开发播放功能

This commit is contained in:
langhuihui
2020-07-01 07:20:41 +08:00
parent bf56ea418a
commit 4922863211
9 changed files with 354 additions and 310 deletions

156
main.go
View File

@@ -55,6 +55,7 @@ var api *API
var SSRC uint32
var SSRCMap = make(map[string]uint32)
var ssrcLock sync.Mutex
var playWaitList sync.Map
func init() {
m.RegisterCodec(NewRTPH264Codec(DefaultPayloadTypeH264, 90000))
@@ -72,45 +73,18 @@ type WebRTC struct {
RTP
*PeerConnection
RemoteAddr string
videoTrack *Track
}
func (rtc *WebRTC) Play(streamPath string) bool {
peerConnection, err := api.NewPeerConnection(Configuration{
ICEServers: []ICEServer{
{
URLs: config.ICEServers,
},
},
})
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
rtc.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
@@ -121,7 +95,7 @@ func (rtc *WebRTC) Play(streamPath string) bool {
sequence++
return rtp.Header{
Version: 2,
SSRC: ssrc,
SSRC: SSRC,
PayloadType: DefaultPayloadTypeH264,
SequenceNumber: sequence,
Timestamp: ts,
@@ -154,8 +128,8 @@ func (rtc *WebRTC) Play(streamPath string) bool {
pps = payload[2:ppsLen]
} else {
if packet.IsKeyFrame {
if err := videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(0, true),
if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, true),
Payload: stapA(sps, pps),
}); err != nil {
return err
@@ -167,14 +141,13 @@ func (rtc *WebRTC) Play(streamPath string) bool {
payload = payload[4:]
_payload := payload[:naulLen]
if naulLen > 1000 {
part := _payload[:1000]
indicator := ((part[0] >> 5) << 5) | 28
nalutype := part[0] & 31
indicator := (_payload[0] & 224) | 28
nalutype := _payload[0] & 31
header := 128 | nalutype
part = part[1:]
part := _payload[1:1000]
marker := false
for {
if err := videoTrack.WriteRTP(&rtp.Packet{
if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, marker),
Payload: append([]byte{indicator, header}, part...),
}); err != nil {
@@ -183,19 +156,19 @@ func (rtc *WebRTC) Play(streamPath string) bool {
if _payload == nil {
break
}
if len(_payload[1000:]) <= 1000 {
_payload = _payload[1000:]
if len(_payload) <= 1000 {
header = 64 | nalutype
part = _payload[1000:]
part = _payload
_payload = nil
marker = true
} else {
header = nalutype
part = _payload[1000:]
_payload = part
part = _payload[:1000]
}
}
} else {
if err := videoTrack.WriteRTP(&rtp.Packet{
if err := rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: nextHeader(packet.Timestamp*90, true),
Payload: _payload,
}); err != nil {
@@ -217,17 +190,8 @@ func (rtc *WebRTC) Play(streamPath string) bool {
return nil
}
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 {
@@ -310,16 +274,68 @@ func (rtc *WebRTC) GetAnswer(localSdp 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)
// if err != nil {
// Println(err)
// return
// }
rtc := new(WebRTC)
rtc.RemoteAddr = r.RemoteAddr
offer := SessionDescription{}
bytes, err := ioutil.ReadAll(r.Body)
err = json.Unmarshal(bytes, &offer)
if err != nil {
Println(err)
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)
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
offer, err := rtc.CreateOffer(nil)
if err != nil {
Println(err)
@@ -332,9 +348,6 @@ func run() {
w.Write([]byte(err.Error()))
return
}
} else {
w.Write([]byte(`{"errmsg":"bad name"}`))
}
})
http.HandleFunc("/webrtc/publish", func(w http.ResponseWriter, r *http.Request) {
streamPath := r.URL.Query().Get("streamPath")
@@ -364,6 +377,7 @@ func run() {
w.Write([]byte(err.Error()))
return
}
w.Write([]byte(`success`))
} else {
w.Write([]byte(`{"errmsg":"bad name"}`))
}

View File

@@ -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":
/***/ (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":
@@ -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=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 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&
//
@@ -287,6 +287,33 @@ var streamPath = "live/rtc";
async startSession(type) {
this.type = type;
this.ask = true;
if (type == "play") {
const result = await this.ajax({
url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
}
pc.ontrack = event => {
console.log(event)
if (event.streams[0].id == "monibuca")
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,
@@ -295,24 +322,17 @@ var streamPath = "live/rtc";
dataType: "json"
});
this.ask = false;
if (result.errmsg) {
this.$toast.error(result.errmsg);
if (result!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
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;
if (type == "play") {
} else {
pc.ontrack = event => {
if(event.streams[0].id=="monibuca")
this.stream = stream = event.streams[0];
};
this.remoteSDP = result.sdp;
pc.setRemoteDescription(new RTCSessionDescription(result));
}
},
stopSession() {
@@ -332,17 +352,8 @@ var streamPath = "live/rtc";
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 {
pc.onicecandidate = event => {};
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
@@ -352,13 +363,12 @@ var streamPath = "live/rtc";
this.$toast.error(err.message);
}
}
}
});
// 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=03ea1df8&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a");
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=09aaef78&scoped=true&lang=css&
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
/* globals __VUE_SSR_CONTEXT__ */
@@ -475,7 +485,7 @@ var component = normalizeComponent(
staticRenderFns,
false,
null,
"03ea1df8",
"09aaef78",
null
)

File diff suppressed because one or more lines are too long

View File

@@ -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}

View File

@@ -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":
/***/ (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":
@@ -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=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 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&
//
@@ -296,6 +296,33 @@ var streamPath = "live/rtc";
async startSession(type) {
this.type = type;
this.ask = true;
if (type == "play") {
const result = await this.ajax({
url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
}
pc.ontrack = event => {
console.log(event)
if (event.streams[0].id == "monibuca")
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,
@@ -304,24 +331,17 @@ var streamPath = "live/rtc";
dataType: "json"
});
this.ask = false;
if (result.errmsg) {
this.$toast.error(result.errmsg);
if (result!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
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;
if (type == "play") {
} else {
pc.ontrack = event => {
if(event.streams[0].id=="monibuca")
this.stream = stream = event.streams[0];
};
this.remoteSDP = result.sdp;
pc.setRemoteDescription(new RTCSessionDescription(result));
}
},
stopSession() {
@@ -341,17 +361,8 @@ var streamPath = "live/rtc";
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 {
pc.onicecandidate = event => {};
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
@@ -361,13 +372,12 @@ var streamPath = "live/rtc";
this.$toast.error(err.message);
}
}
}
});
// 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=03ea1df8&scoped=true&lang=css&
var Appvue_type_style_index_0_id_03ea1df8_scoped_true_lang_css_ = __webpack_require__("e91a");
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=09aaef78&scoped=true&lang=css&
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
/* globals __VUE_SSR_CONTEXT__ */
@@ -484,7 +494,7 @@ var component = normalizeComponent(
staticRenderFns,
false,
null,
"03ea1df8",
"09aaef78",
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

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