Pārlūkot izejas kodu

修改了监控数量 8/9 添加了webRTC流监控

dedsudiyu 2 dienas atpakaļ
vecāks
revīzija
3559873285

+ 1 - 1
.env.production

@@ -5,7 +5,7 @@ NODE_ENV=production
 VUE_APP_TITLE=中国安全生产科学研究院实验室安全智慧化管控中心
 
 # 接口基础地址
-VUE_APP_BASE_API=http://192.168.166.11/api
+VUE_APP_BASE_API=https://192.168.166.11/api
 
 # 接口超时时间(毫秒)
 VUE_APP_TIMEOUT=15000

+ 10 - 1
src/components/SecurityMonitor.vue

@@ -14,6 +14,7 @@
       </div>
     </div>
     <div v-if="checkButton == 1" class="monitor-play-box">
+      <webRTC></webRTC>
       <videoForMod
           v-for="(item,index) in modList" :key="index"
           :deviceNo="item.deviceNo"
@@ -116,6 +117,7 @@ import { getCameraList,getMonitorTree,getRooms,getDeptDropList,
 import H5PlayerVideo from '@/components/H5PlayerVideo/H5PlayerVideo.vue'
 import videoForMod from '@/components/videoForMod/videoForMod.vue'
 import fullH5PlayerVideo from '@/components/fullH5PlayerVideo/fullH5PlayerVideo.vue'
+import webRTC from './webRTC.vue'
 const TreeNode = {
   name: 'TreeNode',
   props: {
@@ -189,6 +191,7 @@ export default {
     H5PlayerVideo,
     fullH5PlayerVideo,
     videoForMod,
+    webRTC
   },
   data() {
     return {
@@ -537,7 +540,13 @@ export default {
         const res = await laboratoryLabScreenScreenConfigGet({ screenType: 1 })
         if (res.code === 200) {
           this.$set(this,'effective',res.data.effective);
-          this.$set(this,'modList',res.data.items);
+          let list = [];
+          for(let i=0;i<res.data.items.length;i++){
+            if(i<8){
+              list.push(res.data.items[i])
+            }
+          }
+          this.$set(this,'modList',list);
           if(res.data.effective){
             this.$set(this,'checkButton',1);
           }else{

+ 4 - 3
src/components/alarmWindow/emergency.vue

@@ -370,6 +370,7 @@ export default {
     this.$set(this,'buildId',this.alarmData.buildId);
     this.$set(this,'floorId',this.alarmData.floorId);
     this.$set(this,'subId',this.alarmData.subId);
+    this.$set(this,'checkSubId',this.alarmData.subId);
     this.laboratoryBigViewGetFloorByBigView();
   },
   methods: {
@@ -429,7 +430,7 @@ export default {
                 subNum++
                 this.$set(this,'subName',list[x].subName);
                 this.$set(this,'roomNum',list[x].roomNum);
-                this.$set(this,'checkSubId',list[x].subId);
+                // this.$set(this,'checkSubId',list[x].subId);
                 this.$set(this,'subId',list[x].subId);
                 this.$set(this,'adminId',list[x].adminId);
                 break
@@ -438,7 +439,7 @@ export default {
             if(subNum == 0){
               this.$set(this,'subName','');
               this.$set(this,'roomNum','');
-              this.$set(this,'checkSubId','');
+              // this.$set(this,'checkSubId','');
               this.$set(this,'adminId','');
             }
             this.$set(this,'mapList',JSON.parse(JSON.stringify(list)));
@@ -538,7 +539,7 @@ export default {
                 if(self.planMapList[x].subId == self.mapList[o].subId){
                   this.$set(this,'subName',self.mapList[o].subName);
                   this.$set(this,'roomNum',self.mapList[o].roomNum);
-                  this.$set(this,'checkSubId',self.mapList[o].subId);
+                  // this.$set(this,'checkSubId',self.mapList[o].subId);
                   this.$set(this,'adminId',self.mapList[o].adminId);
                   checkNum++
                   break

+ 141 - 0
src/components/webRTC.vue

@@ -0,0 +1,141 @@
+<!-- rtc流组件 -->
+<template>
+    <div class="webRTC">
+      <video
+        ref="videoElement"
+        autoplay
+        muted
+        playsinline
+        style="width:1398px;height:810px;background-color: #000; display: block;"
+      ></video>
+      <p class="right-text">AI</p>
+    </div>
+</template>
+<script>
+  const OFFER_URL = 'https://192.168.166.11/offer'
+  const RETRY_INTERVAL = 5000 // 失败后 5 秒重连
+  export default {
+    name: 'webRTC',
+    data() {
+      return {
+        pc: null,
+        retryTimer: null
+      }
+    },
+    mounted() {
+      console.log('screenType',this.screenType);
+      this.connect()
+    },
+    beforeDestroy() {
+      this._clearRetry()
+      this._cleanup()
+    },
+    methods: {
+      async connect() {
+        this._cleanup()
+
+        try {
+          this.pc = new RTCPeerConnection({
+            iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
+            iceTransportPolicy: 'all'
+          })
+
+          this.pc.ontrack = (event) => {
+            this.$refs.videoElement.srcObject = event.streams[0]
+          }
+
+          this.pc.onconnectionstatechange = () => {
+            const state = this.pc && this.pc.connectionState
+            if (state === 'failed' || state === 'disconnected' || state === 'closed') {
+              this._scheduleRetry()
+            }
+          }
+
+          this.pc.addTransceiver('video', { direction: 'recvonly' })
+          this.pc.addTransceiver('audio', { direction: 'recvonly' })
+
+          const offer = await this.pc.createOffer()
+          await this.pc.setLocalDescription(offer)
+          await this._waitIceGathering()
+
+          const response = await fetch(OFFER_URL, {
+            method: 'POST',
+            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+            body: JSON.stringify({
+              sdp: this.pc.localDescription.sdp,
+              type: this.pc.localDescription.type
+            })
+          })
+
+          if (!response.ok) throw new Error(`HTTP ${response.status}`)
+
+          const answer = await response.json()
+          await this.pc.setRemoteDescription(new RTCSessionDescription(answer))
+
+        } catch (e) {
+          console.error('[WebRTC] 连接失败,准备重连:', e)
+          this._scheduleRetry()
+        }
+      },
+
+      _scheduleRetry() {
+        this._cleanup()
+        this._clearRetry()
+        this.retryTimer = setTimeout(() => this.connect(), RETRY_INTERVAL)
+      },
+
+      _clearRetry() {
+        if (this.retryTimer) {
+          clearTimeout(this.retryTimer)
+          this.retryTimer = null
+        }
+      },
+
+      _cleanup() {
+        if (this.pc) {
+          this.pc.ontrack = null
+          this.pc.onconnectionstatechange = null
+          this.pc.close()
+          this.pc = null
+        }
+        if (this.$refs.videoElement) {
+          this.$refs.videoElement.srcObject = null
+        }
+      },
+
+      _waitIceGathering() {
+        return new Promise((resolve) => {
+          if (this.pc.iceGatheringState === 'complete') return resolve()
+          const check = () => {
+            if (this.pc && this.pc.iceGatheringState === 'complete') {
+              this.pc.removeEventListener('icegatheringstatechange', check)
+              resolve()
+            }
+          }
+          this.pc.addEventListener('icegatheringstatechange', check)
+          setTimeout(resolve, 5000)
+        })
+      }
+    }
+  }
+</script>
+<style scoped lang="scss">
+    .webRTC {
+      width:1398px;
+      height:810px;
+      margin:20px 0 0 20px;
+      display: inline-block;
+      position: relative;
+      .right-text{
+        position: absolute;
+        top:25px;
+        right:25px;
+        background: rgba(255, 240, 200, 0.9);
+        color: #d48806;
+        border:1px solid #ffd591;
+        padding:0 25px;
+        border-radius:4px;
+        font-size:42px;
+      }
+    }
+</style>