增加播放功能

This commit is contained in:
langhuihui
2020-07-05 21:43:44 +08:00
parent 457c8ff185
commit 854907f332
12 changed files with 549 additions and 479 deletions

3
go.mod
View File

@@ -3,9 +3,8 @@ module github.com/Monibuca/plugin-webrtc
go 1.13 go 1.13
require ( require (
github.com/Monibuca/engine/v2 v2.1.0 github.com/Monibuca/engine/v2 v2.1.4
github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221 github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221
github.com/pion/rtcp v1.2.1 github.com/pion/rtcp v1.2.1
github.com/pion/rtp v1.5.4
github.com/pion/webrtc/v2 v2.2.14 github.com/pion/webrtc/v2 v2.2.14
) )

2
go.sum
View File

@@ -2,6 +2,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Monibuca/engine/v2 v2.1.0 h1:pHeDCEFDusKFsZLpconYj8U5LCaWApnjd+yQRHYgQsQ= github.com/Monibuca/engine/v2 v2.1.0 h1:pHeDCEFDusKFsZLpconYj8U5LCaWApnjd+yQRHYgQsQ=
github.com/Monibuca/engine/v2 v2.1.0/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc= github.com/Monibuca/engine/v2 v2.1.0/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.1.4 h1:TZK6o/8giu4Yzd9sqntAHZkirqxMahaak/TMiMCSAKg=
github.com/Monibuca/engine/v2 v2.1.4/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221 h1:WBC0eLB7J3PXWZiu4cr9kdcNAkR/74jf0+7zkYDzwZQ= github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221 h1:WBC0eLB7J3PXWZiu4cr9kdcNAkR/74jf0+7zkYDzwZQ=
github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221/go.mod h1:62NoacApn7++z5wQnr9ktSfn+vVZL0eSvbD/EqoSHoM= github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221/go.mod h1:62NoacApn7++z5wQnr9ktSfn+vVZL0eSvbD/EqoSHoM=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=

153
main.go
View File

@@ -1,12 +1,10 @@
package webrtc package webrtc
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"sync" "sync"
"time" "time"
@@ -15,8 +13,6 @@ import (
"github.com/Monibuca/engine/v2/util" "github.com/Monibuca/engine/v2/util"
. "github.com/Monibuca/plugin-rtp" . "github.com/Monibuca/plugin-rtp"
"github.com/pion/rtcp" "github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/rtp/codecs"
. "github.com/pion/webrtc/v2" . "github.com/pion/webrtc/v2"
"github.com/pion/webrtc/v2/pkg/media" "github.com/pion/webrtc/v2/pkg/media"
) )
@@ -60,7 +56,13 @@ var ssrcLock sync.Mutex
var playWaitList sync.Map var playWaitList sync.Map
func init() { func init() {
m.RegisterCodec(NewRTPH264Codec(DefaultPayloadTypeH264, 90000)) m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
H264,
90000,
0,
"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f",
DefaultPayloadTypeH264,
new(avformat.H264)))
//m.RegisterCodec(NewRTPPCMUCodec(DefaultPayloadTypePCMU, 8000)) //m.RegisterCodec(NewRTPPCMUCodec(DefaultPayloadTypePCMU, 8000))
api = NewAPI(WithMediaEngine(m)) api = NewAPI(WithMediaEngine(m))
InstallPlugin(&PluginConfig{ InstallPlugin(&PluginConfig{
@@ -76,26 +78,8 @@ type WebRTC struct {
*PeerConnection *PeerConnection
RemoteAddr string RemoteAddr string
videoTrack *Track videoTrack *Track
sequence uint16 // codecs.H264Packet
codecs.H264Packet // *os.File
*os.File
}
func (rtc *WebRTC) WriteVideo(ts uint32, marker bool, payload []byte) error {
rtc.sequence++
// bb, _ := rtc.Unmarshal(payload)
// rtc.Write(bb)
return rtc.videoTrack.WriteRTP(&rtp.Packet{
Header: rtp.Header{
Version: 2,
SSRC: SSRC,
PayloadType: DefaultPayloadTypeH264,
SequenceNumber: rtc.sequence,
Timestamp: ts,
Marker: marker,
},
Payload: payload,
})
} }
func (rtc *WebRTC) Play(streamPath string) bool { func (rtc *WebRTC) Play(streamPath string) bool {
@@ -108,138 +92,43 @@ func (rtc *WebRTC) Play(streamPath string) bool {
} }
case ICEConnectionStateConnected: case ICEConnectionStateConnected:
var sub Subscriber var sub Subscriber
var sps []byte
var pps []byte
sub.ID = rtc.RemoteAddr sub.ID = rtc.RemoteAddr
sub.Type = "WebRTC" sub.Type = "WebRTC"
var lastTimeStamp uint32 var lastTimeStamp uint32
var dataBuilder bytes.Buffer
sub.OnData = func(packet *avformat.SendPacket) error { sub.OnData = func(packet *avformat.SendPacket) error {
if packet.Type == avformat.FLV_TAG_TYPE_AUDIO { if packet.Type == avformat.FLV_TAG_TYPE_AUDIO {
return nil return nil
} }
if packet.IsSequence { if packet.IsSequence {
payload := packet.Payload[11:]
spsLen := int(payload[0])<<8 + int(payload[1])
payload = payload[2:]
sps = payload[:spsLen]
payload = payload[1+spsLen:]
ppsLen := int(payload[0])<<8 + int(payload[1])
payload = payload[2:]
pps = payload[:ppsLen]
} else { } else {
var s uint32 var s uint32
if lastTimeStamp > 0 { if lastTimeStamp > 0 {
s = packet.Timestamp - lastTimeStamp s = packet.Timestamp - lastTimeStamp
} }
if packet.IsKeyFrame { if packet.IsKeyFrame {
dataBuilder.Write(avformat.NALU_Delimiter2) rtc.videoTrack.WriteSample(media.Sample{
dataBuilder.Write(sps) Data: sub.SPS,
dataBuilder.Write(avformat.NALU_Delimiter2) Samples: 0,
dataBuilder.Write(pps) })
rtc.videoTrack.WriteSample(media.Sample{
Data: sub.PPS,
Samples: 0,
})
} }
payload := packet.Payload[5:] for payload := packet.Payload[5:]; len(payload) > 4; {
for {
var naulLen = int(util.BigEndian.Uint32(payload)) var naulLen = int(util.BigEndian.Uint32(payload))
payload = payload[4:] payload = payload[4:]
dataBuilder.Write(avformat.NALU_Delimiter2)
dataBuilder.Write(payload[:naulLen])
rtc.videoTrack.WriteSample(media.Sample{ rtc.videoTrack.WriteSample(media.Sample{
Data: dataBuilder.Bytes(), Data: payload[:naulLen],
Samples: s * 90, Samples: s * 90,
}) })
dataBuilder.Reset() s = 0
if len(payload) < naulLen+4 {
break
}
payload = payload[naulLen:] payload = payload[naulLen:]
} }
} }
lastTimeStamp = packet.Timestamp lastTimeStamp = packet.Timestamp
return nil return nil
} }
// stapA := func(naul ...[]byte) []byte {
// var buffer bytes.Buffer
// buffer.WriteByte((naul[0][0] & 224) | 24)
// for _, n := range naul {
// l := len(n)
// buffer.WriteByte(byte(l >> 8))
// buffer.WriteByte(byte(l))
// buffer.Write(n)
// }
// return buffer.Bytes()
// }
// //rtc.File, _ = os.OpenFile("webrtc.h264", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
// aud := []byte{0x09, 0x30}
// sub.OnData = func(packet *avformat.SendPacket) error {
// if packet.Type == avformat.FLV_TAG_TYPE_AUDIO {
// return nil
// }
// if packet.IsSequence {
// payload := packet.Payload[11:]
// spsLen := int(payload[0])<<8 + int(payload[1])
// sps = payload[2:spsLen]
// payload = payload[3+spsLen:]
// ppsLen := int(payload[0])<<8 + int(payload[1])
// pps = payload[2:ppsLen]
// } else {
// if packet.IsKeyFrame {
// if err := rtc.WriteVideo(packet.Timestamp*90, true, stapA([]byte{0x9, 0x10}, sps, pps)); err != nil {
// return err
// }
// } else {
// if err := rtc.WriteVideo(packet.Timestamp*90, true, aud); err != nil {
// return err
// }
// }
// payload := packet.Payload[5:]
// for {
// var naulLen = int(util.BigEndian.Uint32(payload))
// payload = payload[4:]
// _payload := payload[:naulLen]
// if naulLen > 1000 {
// indicator := (_payload[0] & 224) | 28
// nalutype := _payload[0] & 31
// header := 128 | nalutype
// part := _payload[1:1000]
// marker := false
// for {
// if err := rtc.WriteVideo(packet.Timestamp*90, marker, append([]byte{indicator, header}, part...)); err != nil {
// return err
// }
// if _payload == nil {
// break
// }
// _payload = _payload[1000:]
// if len(_payload) <= 1000 {
// header = 64 | nalutype
// part = _payload
// _payload = nil
// marker = true
// } else {
// header = nalutype
// part = _payload[:1000]
// }
// }
// } else {
// if err := rtc.WriteVideo(packet.Timestamp*90, true, _payload); err != nil {
// return err
// }
// }
// if len(payload) < naulLen+4 {
// break
// }
// payload = payload[naulLen:]
// }
// // if err := videoTrack.WriteRTP(&rtp.Packet{
// // Header: nextHeader(packet.Timestamp * 90),
// // Payload: aud,
// // }); err != nil {
// // return err
// // }
// }
// return nil
// }
go sub.Subscribe(streamPath) go sub.Subscribe(streamPath)
} }
}) })
@@ -299,7 +188,7 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
if err = pack.Unmarshal(b[:i]); err != nil { if err = pack.Unmarshal(b[:i]); err != nil {
return return
} }
rtc.Unmarshal(pack.Payload) // rtc.Unmarshal(pack.Payload)
// f.Write(bytes) // f.Write(bytes)
} }
}) })

View File

@@ -87,18 +87,7 @@ module.exports =
/************************************************************************/ /************************************************************************/
/******/ ({ /******/ ({
/***/ "11a1": /***/ "3f2c":
/***/ (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__) { /***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin // extracted by mini-css-extract-plugin
@@ -181,6 +170,17 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
})); }));
/***/ }),
/***/ "b2e7":
/***/ (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_b8166bc0_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("3f2c");
/* 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_b8166bc0_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_b8166bc0_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_b8166bc0_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }), /***/ }),
/***/ "fb15": /***/ "fb15":
@@ -214,15 +214,21 @@ 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=09aaef78&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=b8166bc0&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 == 0)?_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.remoteSDP)?_c('m-button',{on:{"click":_vm.publish}},[_vm._v("Publish")]):_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),(_vm.remoteSDP)?_c('a',{attrs:{"href":_vm.remoteSDPURL,"download":"remoteSDP.txt"}},[_vm._v("remoteSDP")]):_vm._e(),_c('span'),(_vm.localSDP)?_c('a',{attrs:{"href":_vm.localSDPURL,"download":"localSDP.txt"}},[_vm._v("localSDP")]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],1):(_vm.$parent.titleTabActive == 1)?_c('stream-table',{scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_c('m-button',{on:{"click":function($event){return _vm.preview(scope)}}},[_vm._v("Play")]),void 0]}}])}):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 3)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_vm._e(),_c('webrtc-player',{ref:"player",model:{value:(_vm.previewStreamPath),callback:function ($$v) {_vm.previewStreamPath=$$v},expression:"previewStreamPath"}})],1)}
var staticRenderFns = [] var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=09aaef78&scoped=true& // CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=b8166bc0&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?{"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/components/Player.vue?vue&type=template&id=213e71c4&
// var Playervue_type_template_id_213e71c4_render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Modal',_vm._g(_vm._b({attrs:{"draggable":"","title":_vm.streamPath},on:{"on-ok":_vm.onClosePreview,"on-cancel":_vm.onClosePreview}},'Modal',_vm.$attrs,false),_vm.$listeners),[_c('video',{ref:"webrtc",attrs:{"width":"488","height":"275","autoplay":"","muted":"","controls":""},domProps:{"srcObject":_vm.stream,"muted":true}}),_c('div',{attrs:{"slot":"footer"},slot:"footer"},[(_vm.remoteSDP)?_c('a',{attrs:{"href":_vm.remoteSDPURL,"download":"remoteSDP.txt"}},[_vm._v("remoteSDP")]):_vm._e(),_c('span'),(_vm.localSDP)?_c('a',{attrs:{"href":_vm.localSDPURL,"download":"localSDP.txt"}},[_vm._v("localSDP")]):_vm._e()])])}
var Playervue_type_template_id_213e71c4_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=template&id=213e71c4&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=script&lang=js&
// //
// //
// //
@@ -241,110 +247,23 @@ var staticRenderFns = []
// //
// //
const config = { let pc = null
iceServers: [ /* harmony default export */ var Playervue_type_script_lang_js_ = ({
// {
// urls:[
// "stun:stun.ekiga.net",
// "stun:stun.ideasip.com",
// "stun:stun.schlund.de",
// "stun:stun.stunprotocol.org:3478",
// "stun:stun.voiparound.com",
// "stun:stun.voipbuster.com",
// "stun:stun.voipstunt.com",
// "stun:stun.voxgratia.org",
// "stun:stun.services.mozilla.com",
// "stun:stun.xten.com",
// "stun:stun.softjoys.com",
// "stun:stunserver.org",
// "stun:stun.schlund.de",
// "stun:stun.rixtelecom.se",
// "stun:stun.iptel.org",
// "stun:stun.ideasip.com",
// "stun:stun.fwdnet.net",
// "stun:stun.ekiga.net",
// "stun:stun01.sipphone.com",
// ]
// }
]
};
let pc = new RTCPeerConnection(config);
var stream = null;
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
data() { data() {
return { return {
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState: pc && pc.iceConnectionState, iceConnectionState: pc && pc.iceConnectionState,
stream, stream: null,
type: "", localSDP: "",
ask: false remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
}; };
}, },
methods: { methods: {
async startSession(type) { async play(streamPath) {
this.type = type; pc = new RTCPeerConnection();
this.ask = true; this.streamPath = streamPath;
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,
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() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
}
},
async mounted() {
pc.onsignalingstatechange = e => { pc.onsignalingstatechange = e => {
console.log(e); console.log(e);
}; };
@@ -353,23 +272,47 @@ var streamPath = "live/rtc";
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => {}; pc.onicecandidate = event => {};
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"]; const result = await this.ajax({
try { url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
if (!this.stream) dataType: "json"
this.stream = stream = await navigator.mediaDevices.getUserMedia( });
{ video: true, audio: true } if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
pc.ontrack = event => {
console.log(event);
if (event.streams[0].id == "monibuca")
this.stream = event.streams[0];
};
await pc.setRemoteDescription(new RTCSessionDescription(result));
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
); );
} catch (err) { result = await this.ajax({
this.$toast.error(err.message); type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result != "success") {
this.$toast.error(result.errmsg || result);
}
},
onClosePreview() {
pc.close();
} }
} }
}); });
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js& // CONCATENATED MODULE: ./src/components/Player.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 components_Playervue_type_script_lang_js_ = (Playervue_type_script_lang_js_);
// 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 // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */ /* globals __VUE_SSR_CONTEXT__ */
@@ -470,6 +413,133 @@ function normalizeComponent (
} }
} }
// CONCATENATED MODULE: ./src/components/Player.vue
/* normalize component */
var component = normalizeComponent(
components_Playervue_type_script_lang_js_,
Playervue_type_template_id_213e71c4_render,
Playervue_type_template_id_213e71c4_staticRenderFns,
false,
null,
null,
null
)
/* harmony default export */ var Player = (component.exports);
// 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&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
const config = { iceServers: []};
let Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
components:{
WebrtcPlayer: Player
},
data() {
return {
localSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.localDescription && Appvue_type_script_lang_js_pc.localDescription.sdp,
remoteSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.remoteDescription && Appvue_type_script_lang_js_pc.remoteDescription.sdp,
streamPath,
iceConnectionState: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.iceConnectionState,
stream,
previewStreamPath:false,
localSDPURL:"",
remoteSDPURL:""
};
},
methods: {
async publish() {
Appvue_type_script_lang_js_pc.addStream(stream);
await Appvue_type_script_lang_js_pc.setLocalDescription(await Appvue_type_script_lang_js_pc.createOffer());
this.localSDP = Appvue_type_script_lang_js_pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(Appvue_type_script_lang_js_pc.localDescription),
url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json"
});
if (result!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
}
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
Appvue_type_script_lang_js_pc.setRemoteDescription(new RTCSessionDescription(result));
},
stopSession() {
Appvue_type_script_lang_js_pc.close();
Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
},
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
},
async mounted() {
Appvue_type_script_lang_js_pc.onsignalingstatechange = e => {
console.log(e);
};
Appvue_type_script_lang_js_pc.oniceconnectionstatechange = e => {
this.$toast.info(Appvue_type_script_lang_js_pc.iceConnectionState);
this.iceConnectionState = Appvue_type_script_lang_js_pc.iceConnectionState;
};
Appvue_type_script_lang_js_pc.onicecandidate = event => {};
this.$parent.titleTabs = ["publish","play"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
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=b8166bc0&scoped=true&lang=css&
var Appvue_type_style_index_0_id_b8166bc0_scoped_true_lang_css_ = __webpack_require__("b2e7");
// CONCATENATED MODULE: ./src/App.vue // CONCATENATED MODULE: ./src/App.vue
@@ -479,18 +549,18 @@ function normalizeComponent (
/* normalize component */ /* normalize component */
var component = normalizeComponent( var App_component = normalizeComponent(
src_Appvue_type_script_lang_js_, src_Appvue_type_script_lang_js_,
render, render,
staticRenderFns, staticRenderFns,
false, false,
null, null,
"09aaef78", "b8166bc0",
null null
) )
/* harmony default export */ var App = (component.exports); /* harmony default export */ var App = (App_component.exports);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js // CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -96,18 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/************************************************************************/ /************************************************************************/
/******/ ({ /******/ ({
/***/ "11a1": /***/ "3f2c":
/***/ (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__) { /***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin // extracted by mini-css-extract-plugin
@@ -190,6 +179,17 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
})); }));
/***/ }),
/***/ "b2e7":
/***/ (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_b8166bc0_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("3f2c");
/* 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_b8166bc0_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_b8166bc0_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_b8166bc0_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }), /***/ }),
/***/ "fb15": /***/ "fb15":
@@ -223,15 +223,21 @@ 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=09aaef78&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=b8166bc0&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 == 0)?_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.remoteSDP)?_c('m-button',{on:{"click":_vm.publish}},[_vm._v("Publish")]):_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),(_vm.remoteSDP)?_c('a',{attrs:{"href":_vm.remoteSDPURL,"download":"remoteSDP.txt"}},[_vm._v("remoteSDP")]):_vm._e(),_c('span'),(_vm.localSDP)?_c('a',{attrs:{"href":_vm.localSDPURL,"download":"localSDP.txt"}},[_vm._v("localSDP")]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],1):(_vm.$parent.titleTabActive == 1)?_c('stream-table',{scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_c('m-button',{on:{"click":function($event){return _vm.preview(scope)}}},[_vm._v("Play")]),void 0]}}])}):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 3)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_vm._e(),_c('webrtc-player',{ref:"player",model:{value:(_vm.previewStreamPath),callback:function ($$v) {_vm.previewStreamPath=$$v},expression:"previewStreamPath"}})],1)}
var staticRenderFns = [] var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=09aaef78&scoped=true& // CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=b8166bc0&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?{"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/components/Player.vue?vue&type=template&id=213e71c4&
// var Playervue_type_template_id_213e71c4_render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Modal',_vm._g(_vm._b({attrs:{"draggable":"","title":_vm.streamPath},on:{"on-ok":_vm.onClosePreview,"on-cancel":_vm.onClosePreview}},'Modal',_vm.$attrs,false),_vm.$listeners),[_c('video',{ref:"webrtc",attrs:{"width":"488","height":"275","autoplay":"","muted":"","controls":""},domProps:{"srcObject":_vm.stream,"muted":true}}),_c('div',{attrs:{"slot":"footer"},slot:"footer"},[(_vm.remoteSDP)?_c('a',{attrs:{"href":_vm.remoteSDPURL,"download":"remoteSDP.txt"}},[_vm._v("remoteSDP")]):_vm._e(),_c('span'),(_vm.localSDP)?_c('a',{attrs:{"href":_vm.localSDPURL,"download":"localSDP.txt"}},[_vm._v("localSDP")]):_vm._e()])])}
var Playervue_type_template_id_213e71c4_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=template&id=213e71c4&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=script&lang=js&
// //
// //
// //
@@ -250,110 +256,23 @@ var staticRenderFns = []
// //
// //
const config = { let pc = null
iceServers: [ /* harmony default export */ var Playervue_type_script_lang_js_ = ({
// {
// urls:[
// "stun:stun.ekiga.net",
// "stun:stun.ideasip.com",
// "stun:stun.schlund.de",
// "stun:stun.stunprotocol.org:3478",
// "stun:stun.voiparound.com",
// "stun:stun.voipbuster.com",
// "stun:stun.voipstunt.com",
// "stun:stun.voxgratia.org",
// "stun:stun.services.mozilla.com",
// "stun:stun.xten.com",
// "stun:stun.softjoys.com",
// "stun:stunserver.org",
// "stun:stun.schlund.de",
// "stun:stun.rixtelecom.se",
// "stun:stun.iptel.org",
// "stun:stun.ideasip.com",
// "stun:stun.fwdnet.net",
// "stun:stun.ekiga.net",
// "stun:stun01.sipphone.com",
// ]
// }
]
};
let pc = new RTCPeerConnection(config);
var stream = null;
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
data() { data() {
return { return {
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState: pc && pc.iceConnectionState, iceConnectionState: pc && pc.iceConnectionState,
stream, stream: null,
type: "", localSDP: "",
ask: false remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
}; };
}, },
methods: { methods: {
async startSession(type) { async play(streamPath) {
this.type = type; pc = new RTCPeerConnection();
this.ask = true; this.streamPath = streamPath;
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,
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() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
}
},
async mounted() {
pc.onsignalingstatechange = e => { pc.onsignalingstatechange = e => {
console.log(e); console.log(e);
}; };
@@ -362,23 +281,47 @@ var streamPath = "live/rtc";
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => {}; pc.onicecandidate = event => {};
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"]; const result = await this.ajax({
try { url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
if (!this.stream) dataType: "json"
this.stream = stream = await navigator.mediaDevices.getUserMedia( });
{ video: true, audio: true } if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
pc.ontrack = event => {
console.log(event);
if (event.streams[0].id == "monibuca")
this.stream = event.streams[0];
};
await pc.setRemoteDescription(new RTCSessionDescription(result));
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
); );
} catch (err) { result = await this.ajax({
this.$toast.error(err.message); type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result != "success") {
this.$toast.error(result.errmsg || result);
}
},
onClosePreview() {
pc.close();
} }
} }
}); });
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js& // CONCATENATED MODULE: ./src/components/Player.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 components_Playervue_type_script_lang_js_ = (Playervue_type_script_lang_js_);
// 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 // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */ /* globals __VUE_SSR_CONTEXT__ */
@@ -479,6 +422,133 @@ function normalizeComponent (
} }
} }
// CONCATENATED MODULE: ./src/components/Player.vue
/* normalize component */
var component = normalizeComponent(
components_Playervue_type_script_lang_js_,
Playervue_type_template_id_213e71c4_render,
Playervue_type_template_id_213e71c4_staticRenderFns,
false,
null,
null,
null
)
/* harmony default export */ var Player = (component.exports);
// 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&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
const config = { iceServers: []};
let Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
components:{
WebrtcPlayer: Player
},
data() {
return {
localSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.localDescription && Appvue_type_script_lang_js_pc.localDescription.sdp,
remoteSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.remoteDescription && Appvue_type_script_lang_js_pc.remoteDescription.sdp,
streamPath,
iceConnectionState: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.iceConnectionState,
stream,
previewStreamPath:false,
localSDPURL:"",
remoteSDPURL:""
};
},
methods: {
async publish() {
Appvue_type_script_lang_js_pc.addStream(stream);
await Appvue_type_script_lang_js_pc.setLocalDescription(await Appvue_type_script_lang_js_pc.createOffer());
this.localSDP = Appvue_type_script_lang_js_pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(Appvue_type_script_lang_js_pc.localDescription),
url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json"
});
if (result!="success") {
this.$toast.error(result.errmsg||result);
return;
} else {
streamPath = this.streamPath;
}
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
Appvue_type_script_lang_js_pc.setRemoteDescription(new RTCSessionDescription(result));
},
stopSession() {
Appvue_type_script_lang_js_pc.close();
Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
},
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
},
async mounted() {
Appvue_type_script_lang_js_pc.onsignalingstatechange = e => {
console.log(e);
};
Appvue_type_script_lang_js_pc.oniceconnectionstatechange = e => {
this.$toast.info(Appvue_type_script_lang_js_pc.iceConnectionState);
this.iceConnectionState = Appvue_type_script_lang_js_pc.iceConnectionState;
};
Appvue_type_script_lang_js_pc.onicecandidate = event => {};
this.$parent.titleTabs = ["publish","play"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
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=b8166bc0&scoped=true&lang=css&
var Appvue_type_style_index_0_id_b8166bc0_scoped_true_lang_css_ = __webpack_require__("b2e7");
// CONCATENATED MODULE: ./src/App.vue // CONCATENATED MODULE: ./src/App.vue
@@ -488,18 +558,18 @@ function normalizeComponent (
/* normalize component */ /* normalize component */
var component = normalizeComponent( var App_component = normalizeComponent(
src_Appvue_type_script_lang_js_, src_Appvue_type_script_lang_js_,
render, render,
staticRenderFns, staticRenderFns,
false, false,
null, null,
"09aaef78", "b8166bc0",
null null
) )
/* harmony default export */ var App = (component.exports); /* harmony default export */ var App = (App_component.exports);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js // CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js

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

@@ -1,53 +1,36 @@
<template> <template>
<div> <div>
<pre v-if="$parent.titleTabActive == 1">{{localSDP}}</pre> <div v-if="$parent.titleTabActive == 0">
<pre v-else-if="$parent.titleTabActive == 2">{{remoteSDP}}</pre>
<div v-else>
<mu-text-field v-model="streamPath" label="streamPath"></mu-text-field> <mu-text-field v-model="streamPath" label="streamPath"></mu-text-field>
<span class="blink" v-if="!localSDP || ask">Connecting</span> <m-button @click="publish" v-if="!remoteSDP">Publish</m-button>
<template> <m-button @click="stopSession" v-else>Stop</m-button>
<m-button @click="startSession('publish')">Publish</m-button> <a v-if="remoteSDP" :href="remoteSDPURL" download="remoteSDP.txt">remoteSDP</a>
<m-button @click="startSession('play')">Play</m-button> <span>&nbsp;&nbsp;</span>
</template> <a v-if="localSDP" :href="localSDPURL" download="localSDP.txt">localSDP</a>
<m-button @click="stopSession">Stop</m-button>
<br /> <br />
<video ref="video1" :srcObject.prop="stream" width="640" height="480" autoplay muted></video> <video ref="video1" :srcObject.prop="stream" width="640" height="480" autoplay muted></video>
</div> </div>
<stream-table v-else-if="$parent.titleTabActive == 1">
<template v-slot="scope">
<m-button @click="preview(scope)">Play</m-button>
<template>
</stream-table>
<pre v-else-if="$parent.titleTabActive == 2">{{localSDP}}</pre>
<pre v-else-if="$parent.titleTabActive == 3">{{remoteSDP}}</pre>
<webrtc-player ref="player" v-model="previewStreamPath"></webrtc-player>
</div> </div>
</template> </template>
<script> <script>
const config = { import WebrtcPlayer from "./components/Player"
iceServers: [ const config = { iceServers: []};
// {
// urls:[
// "stun:stun.ekiga.net",
// "stun:stun.ideasip.com",
// "stun:stun.schlund.de",
// "stun:stun.stunprotocol.org:3478",
// "stun:stun.voiparound.com",
// "stun:stun.voipbuster.com",
// "stun:stun.voipstunt.com",
// "stun:stun.voxgratia.org",
// "stun:stun.services.mozilla.com",
// "stun:stun.xten.com",
// "stun:stun.softjoys.com",
// "stun:stunserver.org",
// "stun:stun.schlund.de",
// "stun:stun.rixtelecom.se",
// "stun:stun.iptel.org",
// "stun:stun.ideasip.com",
// "stun:stun.fwdnet.net",
// "stun:stun.ekiga.net",
// "stun:stun01.sipphone.com",
// ]
// }
]
};
let pc = new RTCPeerConnection(config); let pc = new RTCPeerConnection(config);
var stream = null; var stream = null
var streamPath = "live/rtc"; var streamPath = "live/rtc";
export default { export default {
components:{
WebrtcPlayer
},
data() { data() {
return { return {
localSDP: pc && pc.localDescription && pc.localDescription.sdp, localSDP: pc && pc.localDescription && pc.localDescription.sdp,
@@ -55,70 +38,45 @@ export default {
streamPath, streamPath,
iceConnectionState: pc && pc.iceConnectionState, iceConnectionState: pc && pc.iceConnectionState,
stream, stream,
type: "", previewStreamPath:false,
ask: false localSDPURL:"",
remoteSDPURL:""
}; };
}, },
methods: { methods: {
async startSession(type) { async publish() {
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); pc.addStream(stream);
await pc.setLocalDescription(await pc.createOffer()); await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp; this.localSDP = pc.localDescription.sdp;
} this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({ const result = await this.ajax({
type: "POST", type: "POST",
processData: false, processData: false,
data: JSON.stringify(pc.localDescription), data: JSON.stringify(pc.localDescription),
url: "/webrtc/" + type + "?streamPath=" + this.streamPath, url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json" dataType: "json"
}); });
this.ask = false;
if (result!="success") { if (result!="success") {
this.$toast.error(result.errmsg||result); this.$toast.error(result.errmsg||result);
return; return;
} else { } else {
streamPath = this.streamPath; streamPath = this.streamPath;
} }
if (type == "play") {
} else {
this.remoteSDP = result.sdp; this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
pc.setRemoteDescription(new RTCSessionDescription(result)); pc.setRemoteDescription(new RTCSessionDescription(result));
}
}, },
stopSession() { stopSession() {
pc.close(); pc.close();
pc = new RTCPeerConnection(config); pc = new RTCPeerConnection(config);
this.remoteSDP = ""; this.remoteSDP = "";
this.localSDP = ""; this.localSDP = "";
this.type = "";
// this.connectICE().catch(err => this.$toast.error(err.message)); // this.connectICE().catch(err => this.$toast.error(err.message));
} },
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
}, },
async mounted() { async mounted() {
pc.onsignalingstatechange = e => { pc.onsignalingstatechange = e => {
@@ -129,7 +87,7 @@ export default {
this.iceConnectionState = pc.iceConnectionState; this.iceConnectionState = pc.iceConnectionState;
}; };
pc.onicecandidate = event => {}; pc.onicecandidate = event => {};
this.$parent.titleTabs = ["摄像头", "localSDP", "remoteSDP"]; this.$parent.titleTabs = ["publish","play"];
try { try {
if (!this.stream) if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia( this.stream = stream = await navigator.mediaDevices.getUserMedia(

View File

@@ -0,0 +1,82 @@
<template>
<Modal
v-bind="$attrs"
draggable
v-on="$listeners"
:title="streamPath"
@on-ok="onClosePreview"
@on-cancel="onClosePreview"
>
<video ref="webrtc" :srcObject.prop="stream" width="488" height="275" autoplay muted controls></video>
<div slot="footer">
<a v-if="remoteSDP" :href="remoteSDPURL" download="remoteSDP.txt">remoteSDP</a>
<span>&nbsp;&nbsp;</span>
<a v-if="localSDP" :href="localSDPURL" download="localSDP.txt">localSDP</a>
</div>
</Modal>
</template>
<script>
let pc = null
export default {
data() {
return {
iceConnectionState: pc && pc.iceConnectionState,
stream: null,
localSDP: "",
remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
};
},
methods: {
async play(streamPath) {
pc = new RTCPeerConnection();
this.streamPath = streamPath;
pc.onsignalingstatechange = e => {
console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {};
const result = await this.ajax({
url: "/webrtc/preparePlay?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
pc.ontrack = event => {
console.log(event);
if (event.streams[0].id == "monibuca")
this.stream = event.streams[0];
};
await pc.setRemoteDescription(new RTCSessionDescription(result));
await pc.setLocalDescription(await pc.createAnswer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
);
result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result != "success") {
this.$toast.error(result.errmsg || result);
}
},
onClosePreview() {
pc.close();
}
}
};
</script>