Parcourir la source

增加了hls视频楼道查看

dedsudiyu il y a 2 semaines
Parent
commit
c7fa6b2074
3 fichiers modifiés avec 137 ajouts et 22 suppressions
  1. 21 2
      .env.development
  2. 1 1
      src/views/miniProgramVideo/index.vue
  3. 115 19
      src/views/miniProgramVideoHls/index.vue

+ 21 - 2
.env.development

@@ -23,6 +23,15 @@ VUE_APP_VERSION_DIFFERENCE_FIELD = 'kuangYeDaXue_nanHu'
 
 # ####################外网接口配置####################
 
+# 苏州城市学院
+VUE_APP_BASE_API = 'lab.zjznai.com/szcsxylabSystem'
+
+# 贵州大学
+# VUE_APP_BASE_API = 'lab.zjznai.com/gzdxlabSystem'
+
+# 矿大三期
+# VUE_APP_BASE_API = '10.103.75.81/api'
+
 # 展会
 # VUE_APP_BASE_API = 'lab.zjznai.com/zhlabSystem'
 
@@ -34,7 +43,7 @@ VUE_APP_VERSION_DIFFERENCE_FIELD = 'kuangYeDaXue_nanHu'
 
 # 1.8外网地址
 # VUE_APP_BASE_API = 'lab.zjznai.com/labTest'
-VUE_APP_BASE_API = '192.168.1.8/api'
+# VUE_APP_BASE_API = '192.168.1.8/api'
 
 # 1.88外网地址
 # VUE_APP_BASE_API = '192.168.1.88/labSystem'
@@ -47,6 +56,16 @@ VUE_APP_BASE_API = '192.168.1.8/api'
 
 # ####################内网接口配置####################
 
+# 苏州城市学院
+# VUE_APP_BASE_LOCAL_API = '192.168.8.2/api'
+VUE_APP_BASE_LOCAL_API = 'lab.zjznai.com/szcsxylabSystem'
+
+# 贵州大学
+# VUE_APP_BASE_LOCAL_API = '192.168.8.2/api'
+
+# 矿大三期
+# VUE_APP_BASE_LOCAL_API = '10.103.75.81/api'
+
 # 展会
 # VUE_APP_BASE_LOCAL_API = '192.168.1.12/api'
 
@@ -57,7 +76,7 @@ VUE_APP_BASE_API = '192.168.1.8/api'
 # VUE_APP_BASE_LOCAL_API = 'lasfl.sxau.edu.cn/api'
 
 # 1.8内网地址
-VUE_APP_BASE_LOCAL_API = '192.168.1.8/api'
+# VUE_APP_BASE_LOCAL_API = '192.168.1.8/api'
 
 # 1.88内网地址
 # VUE_APP_BASE_LOCAL_API = '192.168.1.88/labSystem'

+ 1 - 1
src/views/miniProgramVideo/index.vue

@@ -86,7 +86,7 @@
         // type 1.楼栋 2.楼层 3.楼道 4.实验室 5.楼道+实验室
         let obj = {
           page:'1',
-          pageSize:'4',
+          pageSize:'20',
           protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
           streamType:1,
         };

+ 115 - 19
src/views/miniProgramVideoHls/index.vue

@@ -1,5 +1,9 @@
 <template>
   <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>
     <div class="video-max-box" v-if="buttonType&&!fullVideoType">
       <video class="video-box" id="video" controls autoplay muted
@@ -7,17 +11,6 @@
              :width="item.width" :height="item.height"
              :id="item.cameraIndexCode" :ref="item.cameraIndexCode"
       ></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>
 </template>
@@ -28,6 +21,7 @@
     name: 'index',
     data () {
       return {
+        checkType:1,
         buttonType: false,
         width: null,
         height: null,
@@ -53,7 +47,22 @@
     mounted(){
       this.getUrl();
     },
+    beforeDestroy() {
+      // 组件销毁前清理所有HLS实例
+      this.destroyAllHlsPlayers();
+    },
     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() {
         let text = decodeURIComponent(window.location.href);
         if(text.indexOf('touken') != -1){
@@ -85,7 +94,7 @@
         // type 1.楼栋 2.楼层 3.楼道 4.实验室 5.楼道+实验室
         let obj = {
           page:'1',
-          pageSize:'10',
+          pageSize:'20',
           // protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
           protocol:'wss',
           streamType:1,
@@ -97,11 +106,12 @@
           obj.floorId = urlData.floorId;
         }else  if(urlData.type == 3){
           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'){
           obj.source = 2;
@@ -143,25 +153,95 @@
       },
       initVideoPlayers() {
         let self = this;
+        // 先清理之前的HLS实例
+        self.destroyAllHlsPlayers();
+
         for(let i=0;i<self.videoList.length;i++){
           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()) {
-            let hls = new Hls();
+            let hls = new Hls({
+              enableWorker: true,
+              lowLatencyMode: true,
+              backBufferLength: 90
+            });
+
             hls.loadSource(url);
             hls.attachMedia(video);
+
             hls.on(Hls.Events.MANIFEST_PARSED, function () {
               console.log('m3u8 加载成功,可以播放');
+              video.play().catch(e => {
+                console.warn('自动播放被阻止:', e);
+              });
             });
+
             hls.on(Hls.Events.ERROR, function (e, 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')) {
             // iOS 原生支持
             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) {
         var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
@@ -184,6 +264,22 @@
     display: flex;
     flex-direction: column;
     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{
       text-align: center;
       font-size:16px;