|
@@ -1,5 +1,9 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="miniProgramVideoHls">
|
|
<div class="miniProgramVideoHls">
|
|
|
|
|
+ <div class="top-button-box">
|
|
|
|
|
+ <p :class="checkType == 1?'checkP':''" @click="checkButton(1)">实验室监控</p>
|
|
|
|
|
+ <p :class="checkType == 2?'checkP':''" @click="checkButton(2)">楼道监控</p>
|
|
|
|
|
+ </div>
|
|
|
<p class="null-text" v-if="nullType">{{nullType}}</p>
|
|
<p class="null-text" v-if="nullType">{{nullType}}</p>
|
|
|
<div class="video-max-box" v-if="buttonType&&!fullVideoType">
|
|
<div class="video-max-box" v-if="buttonType&&!fullVideoType">
|
|
|
<video class="video-box" id="video" controls autoplay muted
|
|
<video class="video-box" id="video" controls autoplay muted
|
|
@@ -7,17 +11,6 @@
|
|
|
:width="item.width" :height="item.height"
|
|
:width="item.width" :height="item.height"
|
|
|
:id="item.cameraIndexCode" :ref="item.cameraIndexCode"
|
|
:id="item.cameraIndexCode" :ref="item.cameraIndexCode"
|
|
|
></video>
|
|
></video>
|
|
|
- <!--<video-->
|
|
|
|
|
- <!--ref="videoPlayer"-->
|
|
|
|
|
- <!--class="video-box"-->
|
|
|
|
|
- <!--v-for="(item,index) in videoList" :key="index"-->
|
|
|
|
|
- <!--:src="item.url"-->
|
|
|
|
|
- <!--:width="item.width" :height="item.height"-->
|
|
|
|
|
- <!--preload="metadata"-->
|
|
|
|
|
- <!--playsinline-->
|
|
|
|
|
- <!--webkit-playsinline-->
|
|
|
|
|
- <!--x5-playsinline>-->
|
|
|
|
|
- <!--</video>-->
|
|
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
@@ -28,6 +21,7 @@
|
|
|
name: 'index',
|
|
name: 'index',
|
|
|
data () {
|
|
data () {
|
|
|
return {
|
|
return {
|
|
|
|
|
+ checkType:1,
|
|
|
buttonType: false,
|
|
buttonType: false,
|
|
|
width: null,
|
|
width: null,
|
|
|
height: null,
|
|
height: null,
|
|
@@ -53,7 +47,22 @@
|
|
|
mounted(){
|
|
mounted(){
|
|
|
this.getUrl();
|
|
this.getUrl();
|
|
|
},
|
|
},
|
|
|
|
|
+ beforeDestroy() {
|
|
|
|
|
+ // 组件销毁前清理所有HLS实例
|
|
|
|
|
+ this.destroyAllHlsPlayers();
|
|
|
|
|
+ },
|
|
|
methods:{
|
|
methods:{
|
|
|
|
|
+ checkButton(type){
|
|
|
|
|
+ if(this.checkType != type){
|
|
|
|
|
+ // 切换类型前先清理之前的HLS流
|
|
|
|
|
+ this.destroyAllHlsPlayers();
|
|
|
|
|
+ this.$set(this,'checkType',type);
|
|
|
|
|
+ this.$set(this, 'nullType', false);
|
|
|
|
|
+ this.$set(this,'videoList',[]);
|
|
|
|
|
+ this.$set(this, 'buttonType', false);
|
|
|
|
|
+ this.getUrl();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
getUrl() {
|
|
getUrl() {
|
|
|
let text = decodeURIComponent(window.location.href);
|
|
let text = decodeURIComponent(window.location.href);
|
|
|
if(text.indexOf('touken') != -1){
|
|
if(text.indexOf('touken') != -1){
|
|
@@ -85,7 +94,7 @@
|
|
|
// type 1.楼栋 2.楼层 3.楼道 4.实验室 5.楼道+实验室
|
|
// type 1.楼栋 2.楼层 3.楼道 4.实验室 5.楼道+实验室
|
|
|
let obj = {
|
|
let obj = {
|
|
|
page:'1',
|
|
page:'1',
|
|
|
- pageSize:'10',
|
|
|
|
|
|
|
+ pageSize:'20',
|
|
|
// protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
|
|
// protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
|
|
|
protocol:'wss',
|
|
protocol:'wss',
|
|
|
streamType:1,
|
|
streamType:1,
|
|
@@ -97,11 +106,12 @@
|
|
|
obj.floorId = urlData.floorId;
|
|
obj.floorId = urlData.floorId;
|
|
|
}else if(urlData.type == 3){
|
|
}else if(urlData.type == 3){
|
|
|
obj.passageway = urlData.floorId;
|
|
obj.passageway = urlData.floorId;
|
|
|
- }else if(urlData.type == 4){
|
|
|
|
|
- obj.subIds = [urlData.subId];
|
|
|
|
|
- }else if(urlData.type == 5){
|
|
|
|
|
- obj.passageway = urlData.floorId;
|
|
|
|
|
- obj.subIds = [urlData.subId];
|
|
|
|
|
|
|
+ }else if(urlData.type == 4 || urlData.type == 5){
|
|
|
|
|
+ if(this.checkType == 1){
|
|
|
|
|
+ obj.subIds = [urlData.subId];
|
|
|
|
|
+ }else if(this.checkType == 2){
|
|
|
|
|
+ obj.passageway = urlData.floorId;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
if(urlData.source == '2'){
|
|
if(urlData.source == '2'){
|
|
|
obj.source = 2;
|
|
obj.source = 2;
|
|
@@ -143,25 +153,95 @@
|
|
|
},
|
|
},
|
|
|
initVideoPlayers() {
|
|
initVideoPlayers() {
|
|
|
let self = this;
|
|
let self = this;
|
|
|
|
|
+ // 先清理之前的HLS实例
|
|
|
|
|
+ self.destroyAllHlsPlayers();
|
|
|
|
|
+
|
|
|
for(let i=0;i<self.videoList.length;i++){
|
|
for(let i=0;i<self.videoList.length;i++){
|
|
|
let url = self.videoList[i].url;
|
|
let url = self.videoList[i].url;
|
|
|
- let video = document.getElementById(self.videoList[i].cameraIndexCode)
|
|
|
|
|
|
|
+ let videoId = self.videoList[i].cameraIndexCode;
|
|
|
|
|
+ let video = document.getElementById(videoId);
|
|
|
|
|
+
|
|
|
|
|
+ if (!video) continue;
|
|
|
|
|
+
|
|
|
|
|
+ // 先停止当前视频播放
|
|
|
|
|
+ video.pause();
|
|
|
|
|
+ video.src = '';
|
|
|
|
|
+ video.load();
|
|
|
|
|
+
|
|
|
if (Hls.isSupported()) {
|
|
if (Hls.isSupported()) {
|
|
|
- let hls = new Hls();
|
|
|
|
|
|
|
+ let hls = new Hls({
|
|
|
|
|
+ enableWorker: true,
|
|
|
|
|
+ lowLatencyMode: true,
|
|
|
|
|
+ backBufferLength: 90
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
hls.loadSource(url);
|
|
hls.loadSource(url);
|
|
|
hls.attachMedia(video);
|
|
hls.attachMedia(video);
|
|
|
|
|
+
|
|
|
hls.on(Hls.Events.MANIFEST_PARSED, function () {
|
|
hls.on(Hls.Events.MANIFEST_PARSED, function () {
|
|
|
console.log('m3u8 加载成功,可以播放');
|
|
console.log('m3u8 加载成功,可以播放');
|
|
|
|
|
+ video.play().catch(e => {
|
|
|
|
|
+ console.warn('自动播放被阻止:', e);
|
|
|
|
|
+ });
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
hls.on(Hls.Events.ERROR, function (e, data) {
|
|
hls.on(Hls.Events.ERROR, function (e, data) {
|
|
|
console.error('hls.js 报错:', data);
|
|
console.error('hls.js 报错:', data);
|
|
|
|
|
+ if (data.fatal) {
|
|
|
|
|
+ switch(data.type) {
|
|
|
|
|
+ case Hls.ErrorTypes.NETWORK_ERROR:
|
|
|
|
|
+ console.log('网络错误,尝试重新加载');
|
|
|
|
|
+ hls.startLoad();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case Hls.ErrorTypes.MEDIA_ERROR:
|
|
|
|
|
+ console.log('媒体错误,尝试恢复');
|
|
|
|
|
+ hls.recoverMediaError();
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ hls.destroy();
|
|
|
|
|
+ delete self.hlsPlayers[videoId];
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ // 保存HLS实例
|
|
|
|
|
+ self.hlsPlayers[videoId] = hls;
|
|
|
|
|
+
|
|
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
|
// iOS 原生支持
|
|
// iOS 原生支持
|
|
|
video.src = url;
|
|
video.src = url;
|
|
|
|
|
+ video.play().catch(e => {
|
|
|
|
|
+ console.warn('iOS自动播放被阻止:', e);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ // 清理指定视频的HLS实例
|
|
|
|
|
+ destroyHlsPlayer(videoId) {
|
|
|
|
|
+ if (this.hlsPlayers[videoId]) {
|
|
|
|
|
+ const hls = this.hlsPlayers[videoId];
|
|
|
|
|
+ hls.destroy();
|
|
|
|
|
+ delete this.hlsPlayers[videoId];
|
|
|
|
|
+
|
|
|
|
|
+ // 清理video元素
|
|
|
|
|
+ const video = document.getElementById(videoId);
|
|
|
|
|
+ if (video) {
|
|
|
|
|
+ video.pause();
|
|
|
|
|
+ video.src = '';
|
|
|
|
|
+ video.load();
|
|
|
}
|
|
}
|
|
|
|
|
+ console.log(`已销毁视频 ${videoId} 的HLS实例`);
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ // 清理所有HLS实例
|
|
|
|
|
+ destroyAllHlsPlayers() {
|
|
|
|
|
+ Object.keys(this.hlsPlayers).forEach(videoId => {
|
|
|
|
|
+ this.destroyHlsPlayer(videoId);
|
|
|
|
|
+ });
|
|
|
|
|
+ this.hlsPlayers = {};
|
|
|
|
|
+ console.log('已清理所有HLS实例');
|
|
|
|
|
+ },
|
|
|
//乘法
|
|
//乘法
|
|
|
accMul(arg1, arg2) {
|
|
accMul(arg1, arg2) {
|
|
|
var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
|
|
var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
|
|
@@ -184,6 +264,22 @@
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
|
|
+ .top-button-box{
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ border-bottom:1px solid #999;
|
|
|
|
|
+ p{
|
|
|
|
|
+ flex:1;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size:36px;
|
|
|
|
|
+ line-height:80px;
|
|
|
|
|
+ height:80px;
|
|
|
|
|
+ color:#999;
|
|
|
|
|
+ }
|
|
|
|
|
+ .checkP{
|
|
|
|
|
+ background-color: #0183FA;
|
|
|
|
|
+ color:#fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
.null-text{
|
|
.null-text{
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
font-size:16px;
|
|
font-size:16px;
|