Browse Source

添加直接支持切换多种开源播放器

648540858 3 years ago
parent
commit
3051fc82ee

+ 45 - 34
web_src/src/components/dialog/devicePlayer.vue

@@ -4,10 +4,22 @@
     <el-dialog title="视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" @close="close()">
         <!-- <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :message="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer> -->
       <div style="width: 100%; height: 100%">
-        <player ref="videoPlayer" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></player>
+        <el-tabs type="border-card" v-model="activePlayer" @tab-click="changePlayer" v-if="Object.keys(this.player).length > 1">
+          <el-tab-pane label="Jessibuca" name="jessibuca">
+            <jessibucaPlayer v-if="activePlayer === 'jessibuca'" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></jessibucaPlayer>
+          </el-tab-pane>
+          <el-tab-pane label="WebRTC" name="webRTC">
+            <rtc-player v-if="activePlayer === 'webRTC'" ref="webRTC" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player>
+          </el-tab-pane>
+          <el-tab-pane label="h265web">h265web敬请期待</el-tab-pane>
+          <el-tab-pane label="wsPlayer">wsPlayer 敬请期待</el-tab-pane>
+        </el-tabs>
+        <jessibucaPlayer v-if="Object.keys(this.player).length == 1 && this.player.jessibuca" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></jessibucaPlayer>
+        <rtc-player v-if="Object.keys(this.player).length == 1 && this.player.webRTC" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player>
+
       </div>
         <div id="shared" style="text-align: right; margin-top: 1rem;">
-            <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick">
+            <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" >
                 <el-tab-pane label="实时视频" name="media">
                     <div style="margin-bottom: 0.5rem;">
                         <!--		<el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>-->
@@ -273,16 +285,16 @@
 </template>
 
 <script>
-// import player from '../dialog/rtcPlayer.vue'
+import rtcPlayer from '../dialog/rtcPlayer.vue'
 // import LivePlayer from '@liveqing/liveplayer'
 // import player from '../dialog/easyPlayer.vue'
-import player from '../common/jessibuca.vue'
+import jessibucaPlayer from '../common/jessibuca.vue'
 import recordDownload from '../dialog/recordDownload.vue'
 export default {
     name: 'devicePlayer',
     props: {},
     components: {
-        player,recordDownload,
+        jessibucaPlayer, rtcPlayer, recordDownload,
     },
     computed: {
         getPlayerShared: function () {
@@ -298,6 +310,12 @@ export default {
         return {
             video: 'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',
             videoUrl: '',
+            activePlayer: "jessibuca",
+            // 如何你只是用一种播放器,直接注释掉不用的部分即可
+            player: {
+              // jessibuca : ["ws_flv", "wss_flv"],
+              webRTC: ["rtc", "rtc"],
+            },
             videoHistory: {
                 date: '',
                 searchHistoryResult: [] //媒体流历史记录搜索结果
@@ -364,6 +382,12 @@ export default {
                 }).catch(function (e) {});
             }
         },
+        changePlayer: function (tab) {
+            console.log(this.player[tab.name][0])
+            this.activePlayer = tab.name;
+            this.videoUrl = this.streamInfo[this.player[tab.name][0]]
+            console.log(this.videoUrl)
+        },
         openDialog: function (tab, deviceId, channelId, param) {
             this.tabActiveName = tab;
             this.channelId = channelId;
@@ -372,8 +396,8 @@ export default {
             this.mediaServerId = "";
             this.app = "";
             this.videoUrl = ""
-            if (!!this.$refs.videoPlayer) {
-                this.$refs.videoPlayer.pause();
+            if (!!this.$refs[this.activePlayer]) {
+              this.$refs[this.activePlayer].pause();
             }
             switch (tab) {
                 case "media":
@@ -402,38 +426,25 @@ export default {
             this.hasAudio = hasAudio;
             this.isLoging = false;
             // this.videoUrl = streamInfo.rtc;
-            this.videoUrl = this.getUrlByStreamInfo(streamInfo);
+            this.videoUrl = this.getUrlByStreamInfo();
             this.streamId = streamInfo.stream;
             this.app = streamInfo.app;
             this.mediaServerId = streamInfo.mediaServerId;
             this.playFromStreamInfo(false, streamInfo)
         },
-        getUrlByStreamInfo(streamInfo){
-            let baseZlmApi = process.env.NODE_ENV === 'development'?`${location.host}/debug/zlm`:`${location.host}/zlm`
-            // return `${baseZlmApi}/${streamInfo.app}/${streamInfo.streamId}.flv`;
-            // return `http://${baseZlmApi}/${streamInfo.app}/${streamInfo.streamId}.flv`;
+        getUrlByStreamInfo(){
             if (location.protocol === "https:") {
-              if (streamInfo.wss_flv === null) {
-                console.error("媒体服务器未配置ssl端口, 使用http端口")
-                // this.$message({
-                //   showClose: true,
-                //   message: '媒体服务器未配置ssl端口, ',
-                //   type: 'error'
-                // });
-                return streamInfo.ws_flv
-              }else {
-                return streamInfo.wss_flv;
-              }
-
+              this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]]
             }else {
-              return streamInfo.ws_flv;
+              this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]]
             }
+            return this.videoUrl;
 
         },
         coverPlay: function () {
             var that = this;
             this.coverPlaying = true;
-            this.$refs.videoPlayer.pause()
+            this.$refs[this.activePlayer].pause()
             that.$axios({
                 method: 'post',
                 url: '/api/gb_record/convert/' + that.streamId
@@ -465,7 +476,7 @@ export default {
         },
         convertStopClick: function() {
             this.convertStop(()=>{
-                this.$refs.videoPlayer.play(this.videoUrl)
+                this.$refs[this.activePlayer].play(this.videoUrl)
             });
         },
         convertStop: function(callback) {
@@ -490,12 +501,12 @@ export default {
         playFromStreamInfo: function (realHasAudio, streamInfo) {
           this.showVideoDialog = true;
           this.hasaudio = realHasAudio && this.hasaudio;
-          this.$refs.videoPlayer.play(this.getUrlByStreamInfo(streamInfo))
+          this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo))
         },
         close: function () {
             console.log('关闭视频');
-            if (!!this.$refs.videoPlayer){
-              this.$refs.videoPlayer.pause();
+            if (!!this.$refs[this.activePlayer]){
+              this.$refs[this.activePlayer].pause();
             }
             this.videoUrl = '';
             this.coverPlaying = false;
@@ -600,7 +611,7 @@ export default {
             }
         },
         stopPlayRecord: function (callback) {
-            this.$refs.videoPlayer.pause();
+          this.$refs[this.activePlayer].pause();
             this.videoUrl = '';
             this.$axios({
                 method: 'get',
@@ -646,7 +657,7 @@ export default {
             }
         },
         stopDownloadRecord: function (callback) {
-            this.$refs.videoPlayer.pause();
+            this.$refs[this.activePlayer].pause();
             this.videoUrl = '';
             this.$axios({
                 method: 'get',
@@ -753,7 +764,7 @@ export default {
             method: 'get',
             url: '/api/playback/resume/' + this.streamId
           }).then((res)=> {
-            this.$refs.videoPlayer.play(this.videoUrl)
+            this.$refs[this.activePlayer].play(this.videoUrl)
           });
         },
         gbPause(){
@@ -784,7 +795,7 @@ export default {
             url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000)
           }).then( (res)=> {
             setTimeout(()=>{
-              this.$refs.videoPlayer.play(this.videoUrl)
+              this.$refs[this.activePlayer].play(this.videoUrl)
             }, 600)
           });
         },

+ 199 - 27
web_src/static/js/ZLMRTCClient.js

@@ -6,11 +6,17 @@ var ZLMRTCClient = (function (exports) {
 	  WEBRTC_ICE_CANDIDATE_ERROR: 'WEBRTC_ICE_CANDIDATE_ERROR',
 	  WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED: 'WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED',
 	  WEBRTC_ON_REMOTE_STREAMS: 'WEBRTC_ON_REMOTE_STREAMS',
-	  WEBRTC_ON_LOCAL_STREAM: 'WEBRTC_ON_LOCAL_STREAM'
+	  WEBRTC_ON_LOCAL_STREAM: 'WEBRTC_ON_LOCAL_STREAM',
+	  WEBRTC_ON_CONNECTION_STATE_CHANGE: 'WEBRTC_ON_CONNECTION_STATE_CHANGE',
+	  WEBRTC_ON_DATA_CHANNEL_OPEN: 'WEBRTC_ON_DATA_CHANNEL_OPEN',
+	  WEBRTC_ON_DATA_CHANNEL_CLOSE: 'WEBRTC_ON_DATA_CHANNEL_CLOSE',
+	  WEBRTC_ON_DATA_CHANNEL_ERR: 'WEBRTC_ON_DATA_CHANNEL_ERR',
+	  WEBRTC_ON_DATA_CHANNEL_MSG: 'WEBRTC_ON_DATA_CHANNEL_MSG',
+	  CAPTURE_STREAM_FAILED: 'CAPTURE_STREAM_FAILED'
 	};
 
 	const VERSION = '1.0.1';
-	const BUILD_DATE = 'Mon Apr 05 2021 10:22:48 GMT+0800 (中国标准时间)';
+	const BUILD_DATE = 'Thu Mar 24 2022 17:42:57 GMT+0800 (China Standard Time)';
 
 	// Copyright (C) <2018> Intel Corporation
 	//
@@ -7284,11 +7290,16 @@ var ZLMRTCClient = (function (exports) {
 	      debug: false,
 	      // if output debug log
 	      zlmsdpUrl: '',
-	      simulecast: false,
+	      simulcast: false,
 	      useCamera: true,
 	      audioEnable: true,
 	      videoEnable: true,
-	      recvOnly: false
+	      recvOnly: false,
+	      resolution: {
+	        w: 0,
+	        h: 0
+	      },
+	      usedatachannel: false
 	    };
 	    this.options = Object.assign({}, defaults, options);
 
@@ -7299,7 +7310,12 @@ var ZLMRTCClient = (function (exports) {
 	    this.e = {
 	      onicecandidate: this._onIceCandidate.bind(this),
 	      ontrack: this._onTrack.bind(this),
-	      onicecandidateerror: this._onIceCandidateError.bind(this)
+	      onicecandidateerror: this._onIceCandidateError.bind(this),
+	      onconnectionstatechange: this._onconnectionstatechange.bind(this),
+	      ondatachannelopen: this._onDataChannelOpen.bind(this),
+	      ondatachannelmsg: this._onDataChannelMsg.bind(this),
+	      ondatachannelerr: this._onDataChannelErr.bind(this),
+	      ondatachannelclose: this._onDataChannelClose.bind(this)
 	    };
 	    this._remoteStream = null;
 	    this._localStream = null;
@@ -7307,6 +7323,17 @@ var ZLMRTCClient = (function (exports) {
 	    this.pc.onicecandidate = this.e.onicecandidate;
 	    this.pc.onicecandidateerror = this.e.onicecandidateerror;
 	    this.pc.ontrack = this.e.ontrack;
+	    this.pc.onconnectionstatechange = this.e.onconnectionstatechange;
+	    this.datachannel = null;
+
+	    if (this.options.usedatachannel) {
+	      this.datachannel = this.pc.createDataChannel('chat');
+	      this.datachannel.onclose = this.e.ondatachannelclose;
+	      this.datachannel.onerror = this.e.ondatachannelerr;
+	      this.datachannel.onmessage = this.e.ondatachannelmsg;
+	      this.datachannel.onopen = this.e.ondatachannelopen;
+	    }
+
 	    if (!this.options.recvOnly && (this.options.audioEnable || this.options.videoEnable)) this.start();else this.receive();
 	  }
 
@@ -7337,7 +7364,7 @@ var ZLMRTCClient = (function (exports) {
 	          let ret = response.data; //JSON.parse(response.data);
 
 	          if (ret.code != 0) {
-	            // mean failed for offer/anwser exchange
+	            // mean failed for offer/anwser exchange 
 	            this.dispatch(Events$1.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, ret);
 	            return;
 	          }
@@ -7347,7 +7374,7 @@ var ZLMRTCClient = (function (exports) {
 	          anwser.type = 'answer';
 	          log(this.TAG, 'answer:', ret.sdp);
 	          this.pc.setRemoteDescription(anwser).then(() => {
-	            log(this.TAG, 'set remote success');
+	            log(this.TAG, 'set remote sucess');
 	          }).catch(e => {
 	            error(this.TAG, e);
 	          });
@@ -7377,6 +7404,10 @@ var ZLMRTCClient = (function (exports) {
 	      }
 	    }
 
+	    if (this.options.resolution.w != 0 && this.options.resolution.h != 0 && typeof videoConstraints == 'object') {
+	      videoConstraints.resolution = new Resolution(this.options.resolution.w, this.options.resolution.h);
+	    }
+
 	    MediaStreamFactory.createMediaStream(new StreamConstraints(audioConstraints, videoConstraints)).then(stream => {
 	      this._localStream = stream;
 	      this.dispatch(Events$1.WEBRTC_ON_LOCAL_STREAM, stream);
@@ -7389,33 +7420,40 @@ var ZLMRTCClient = (function (exports) {
 	        sendEncodings: []
 	      };
 
-	      if (this.options.simulecast && stream.getVideoTracks().length > 0) {
+	      if (this.options.simulcast && stream.getVideoTracks().length > 0) {
 	        VideoTransceiverInit.sendEncodings = [{
-	          rid: 'q',
+	          rid: 'h',
 	          active: true,
-	          scaleResolutionDownBy: 4.0
+	          maxBitrate: 1000000
 	        }, {
-	          rid: 'h',
+	          rid: 'm',
 	          active: true,
-	          scaleResolutionDownBy: 2.0
+	          maxBitrate: 500000,
+	          scaleResolutionDownBy: 2
 	        }, {
-	          rid: 'f',
-	          active: true
+	          rid: 'l',
+	          active: true,
+	          maxBitrate: 200000,
+	          scaleResolutionDownBy: 4
 	        }];
 	      }
 
-	      if (stream.getAudioTracks().length > 0) {
-	        this.pc.addTransceiver(stream.getAudioTracks()[0], AudioTransceiverInit);
-	      } else {
-	        AudioTransceiverInit.direction = 'recvonly';
-	        this.pc.addTransceiver('audio', AudioTransceiverInit);
+	      if (this.options.audioEnable) {
+	        if (stream.getAudioTracks().length > 0) {
+	          this.pc.addTransceiver(stream.getAudioTracks()[0], AudioTransceiverInit);
+	        } else {
+	          AudioTransceiverInit.direction = 'recvonly';
+	          this.pc.addTransceiver('audio', AudioTransceiverInit);
+	        }
 	      }
 
-	      if (stream.getVideoTracks().length > 0) {
-	        this.pc.addTransceiver(stream.getVideoTracks()[0], VideoTransceiverInit);
-	      } else {
-	        VideoTransceiverInit.direction = 'recvonly';
-	        this.pc.addTransceiver('video', VideoTransceiverInit);
+	      if (this.options.videoEnable) {
+	        if (stream.getVideoTracks().length > 0) {
+	          this.pc.addTransceiver(stream.getVideoTracks()[0], VideoTransceiverInit);
+	        } else {
+	          VideoTransceiverInit.direction = 'recvonly';
+	          this.pc.addTransceiver('video', VideoTransceiverInit);
+	        }
 	      }
 	      /*
 	      stream.getTracks().forEach((track,idx)=>{
@@ -7440,7 +7478,7 @@ var ZLMRTCClient = (function (exports) {
 	            let ret = response.data; //JSON.parse(response.data);
 
 	            if (ret.code != 0) {
-	              // mean failed for offer/anwser exchange
+	              // mean failed for offer/anwser exchange 
 	              this.dispatch(Events$1.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, ret);
 	              return;
 	            }
@@ -7450,7 +7488,7 @@ var ZLMRTCClient = (function (exports) {
 	            anwser.type = 'answer';
 	            log(this.TAG, 'answer:', ret.sdp);
 	            this.pc.setRemoteDescription(anwser).then(() => {
-	              log(this.TAG, 'set remote success');
+	              log(this.TAG, 'set remote sucess');
 	            }).catch(e => {
 	              error(this.TAG, e);
 	            });
@@ -7460,7 +7498,7 @@ var ZLMRTCClient = (function (exports) {
 	        error(this.TAG, e);
 	      });
 	    }).catch(e => {
-	      error(this.TAG, e);
+	      this.dispatch(Events$1.CAPTURE_STREAM_FAILED); //debug.error(this.TAG,e);
 	    }); //const offerOptions = {};
 
 	    /*
@@ -7495,7 +7533,48 @@ var ZLMRTCClient = (function (exports) {
 	    this.dispatch(Events$1.WEBRTC_ICE_CANDIDATE_ERROR, event);
 	  }
 
+	  _onconnectionstatechange(event) {
+	    this.dispatch(Events$1.WEBRTC_ON_CONNECTION_STATE_CHANGE, this.pc.connectionState);
+	  }
+
+	  _onDataChannelOpen(event) {
+	    log(this.TAG, 'ondatachannel open:', event);
+	    this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_OPEN, event);
+	  }
+
+	  _onDataChannelMsg(event) {
+	    log(this.TAG, 'ondatachannel msg:', event);
+	    this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_MSG, event);
+	  }
+
+	  _onDataChannelErr(event) {
+	    log(this.TAG, 'ondatachannel err:', event);
+	    this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_ERR, event);
+	  }
+
+	  _onDataChannelClose(event) {
+	    log(this.TAG, 'ondatachannel close:', event);
+	    this.dispatch(Events$1.WEBRTC_ON_DATA_CHANNEL_CLOSE, event);
+	  }
+
+	  sendMsg(data) {
+	    if (this.datachannel != null) {
+	      this.datachannel.send(data);
+	    } else {
+	      error(this.TAG, 'data channel is null');
+	    }
+	  }
+
+	  closeDataChannel() {
+	    if (this.datachannel) {
+	      this.datachannel.close();
+	      this.datachannel = null;
+	    }
+	  }
+
 	  close() {
+	    this.closeDataChannel();
+
 	    if (this.pc) {
 	      this.pc.close();
 	      this.pc = null;
@@ -7528,15 +7607,108 @@ var ZLMRTCClient = (function (exports) {
 
 	}
 
+	const quickScan = [{
+	  'label': '4K(UHD)',
+	  'width': 3840,
+	  'height': 2160
+	}, {
+	  'label': '1080p(FHD)',
+	  'width': 1920,
+	  'height': 1080
+	}, {
+	  'label': 'UXGA',
+	  'width': 1600,
+	  'height': 1200,
+	  'ratio': '4:3'
+	}, {
+	  'label': '720p(HD)',
+	  'width': 1280,
+	  'height': 720
+	}, {
+	  'label': 'SVGA',
+	  'width': 800,
+	  'height': 600
+	}, {
+	  'label': 'VGA',
+	  'width': 640,
+	  'height': 480
+	}, {
+	  'label': '360p(nHD)',
+	  'width': 640,
+	  'height': 360
+	}, {
+	  'label': 'CIF',
+	  'width': 352,
+	  'height': 288
+	}, {
+	  'label': 'QVGA',
+	  'width': 320,
+	  'height': 240
+	}, {
+	  'label': 'QCIF',
+	  'width': 176,
+	  'height': 144
+	}, {
+	  'label': 'QQVGA',
+	  'width': 160,
+	  'height': 120
+	}];
+	function GetSupportCameraResolutions$1() {
+	  return new Promise(function (resolve, reject) {
+	    let resolutions = [];
+	    let ok = 0;
+	    let err = 0;
+
+	    for (let i = 0; i < quickScan.length; ++i) {
+	      let videoConstraints = new VideoTrackConstraints(VideoSourceInfo.CAMERA);
+	      videoConstraints.resolution = new Resolution(quickScan[i].width, quickScan[i].height);
+	      MediaStreamFactory.createMediaStream(new StreamConstraints(false, videoConstraints)).then(stream => {
+	        resolutions.push(quickScan[i]);
+	        ok++;
+
+	        if (ok + err == quickScan.length) {
+	          resolve(resolutions);
+	        }
+	      }).catch(e => {
+	        err++;
+
+	        if (ok + err == quickScan.length) {
+	          resolve(resolutions);
+	        }
+	      });
+	    }
+	  });
+	}
+	function GetAllScanResolution$1() {
+	  return quickScan;
+	}
+	function isSupportResolution$1(w, h) {
+	  return new Promise(function (resolve, reject) {
+	    let videoConstraints = new VideoTrackConstraints(VideoSourceInfo.CAMERA);
+	    videoConstraints.resolution = new Resolution(w, h);
+	    MediaStreamFactory.createMediaStream(new StreamConstraints(false, videoConstraints)).then(stream => {
+	      resolve();
+	    }).catch(e => {
+	      reject(e);
+	    });
+	  });
+	}
+
 	console.log('build date:', BUILD_DATE);
 	console.log('version:', VERSION);
 	const Events = Events$1;
 	const Media = media;
 	const Endpoint = RTCEndpoint;
+	const GetSupportCameraResolutions = GetSupportCameraResolutions$1;
+	const GetAllScanResolution = GetAllScanResolution$1;
+	const isSupportResolution = isSupportResolution$1;
 
 	exports.Endpoint = Endpoint;
 	exports.Events = Events;
+	exports.GetAllScanResolution = GetAllScanResolution;
+	exports.GetSupportCameraResolutions = GetSupportCameraResolutions;
 	exports.Media = Media;
+	exports.isSupportResolution = isSupportResolution;
 
 	Object.defineProperty(exports, '__esModule', { value: true });
 

File diff suppressed because it is too large
+ 0 - 0
web_src/static/js/ZLMRTCClient.js.map


Some files were not shown because too many files changed in this diff