yanghao 1 هفته پیش
والد
کامیت
3cfea9f733
2فایلهای تغییر یافته به همراه124 افزوده شده و 44 حذف شده
  1. 1 1
      .env.local
  2. 123 43
      src/views/pms/video_center/sip/splitview.vue

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 
 # 请求路径  http://192.168.188.149:48080  https://iot.deepoil.cc  http://172.26.0.3:48080
-VITE_BASE_URL='https://iot.deepoil.cc'
+VITE_BASE_URL='https://aims.deepoil.cc'
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server

+ 123 - 43
src/views/pms/video_center/sip/splitview.vue

@@ -7,11 +7,7 @@
       :body-style="{ padding: '0px' }"
       class="border-none"
     >
-      <el-container
-        v-loading="loading"
-        style="height: 100%"
-        :element-loading-text="t('sip.splitview998531-0')"
-      >
+      <el-container style="height: 100%">
         <el-aside width="250px" style="background-color: #ffffff">
           <DeviceTree :click-event="clickEvent" />
         </el-aside>
@@ -93,10 +89,11 @@
             <div
               v-for="i in Math.max(0, spilt - availableChannels.length)"
               :key="`empty-${i}`"
-              class="play-box"
-              :style="liveStyle"
+              :class="availableChannels.length > 0 ? 'play-box' : ''"
+              :style="availableChannels.length > 0 ? liveStyle : ''"
             >
               <div
+                v-if="availableChannels.length > 0"
                 style="
                   color: #ffffff;
                   font-size: 30px;
@@ -178,42 +175,128 @@ const liveStyle = computed(() => {
   return style
 })
 
-// 监听分屏变化
+// const loadAdditionalChannelsForSplit = async (newSplit, oldSplit) => {
+//   loading.value = true
+//   try {
+//     // 获取当前已经加载的通道数量
+//     const currentlyLoaded = Math.min(oldSplit, availableChannels.value.length)
+//     const toBeLoaded = Math.min(newSplit, availableChannels.value.length)
+
+//     // 准备所有需要加载的通道
+//     const channelsToLoad = []
+//     for (let i = currentlyLoaded; i < toBeLoaded; i++) {
+//       const channelData = availableChannels.value[i]
+
+//       // 检查是否已有缓存的播放地址
+//       if (channelData._playUrl) {
+//         // 使用缓存的地址(立即设置,不需要等待)
+//         setPlayUrl(channelData._playUrl, i)
+//       } else {
+//         // 需要获取的通道
+//         channelsToLoad.push({
+//           index: i,
+//           channelData: channelData,
+//           playData: {
+//             deviceSipId: channelData.deviceId,
+//             channelSipId: channelData.basicData?.channelSipId || channelData.id,
+//             name: channelData.name || `通道${i + 1}`,
+//             ...channelData.basicData
+//           }
+//         })
+//       }
+//     }
+
+//     // 并发执行所有请求(使用 Promise.all)
+//     const requests = channelsToLoad.map(({ playData, index, channelData }) =>
+//       sendDevicePush(playData, index)
+//         .then(() => {
+//           // 缓存获取到的地址
+//           if (videoUrl.value[index]) {
+//             channelData._playUrl = videoUrl.value[index]
+//           }
+//         })
+//         .catch((error) => {
+//           console.error(`加载通道${index + 1}失败:`, error)
+//           // 标记该通道加载失败,可以在UI上显示错误状态
+//           channelData._loadError = true
+//         })
+//     )
+
+//     // 等待所有请求完成(或部分完成)
+//     await Promise.allSettled(requests)
+//   } catch (error) {
+//     console.error('加载新增通道出错:', error)
+//   } finally {
+//     loading.value = false
+//   }
+// }
+
+const loadAdditionalChannelsForSplit = async (newSplit, oldSplit) => {
+  loading.value = true
+  try {
+    const currentlyLoaded = Math.min(oldSplit, availableChannels.value.length)
+    const toBeLoaded = Math.min(newSplit, availableChannels.value.length)
+
+    // 使用数组存储所有要执行的异步操作
+    const operations = []
+
+    for (let i = currentlyLoaded; i < toBeLoaded; i++) {
+      const channelData = availableChannels.value[i]
+
+      if (channelData._playUrl) {
+        // 同步操作:立即设置URL
+        setPlayUrl(channelData._playUrl, i)
+      } else {
+        // 异步操作:稍后并行执行
+        operations.push({
+          index: i,
+          channelData,
+          playData: {
+            deviceSipId: channelData.deviceId,
+            channelSipId: channelData.basicData?.channelSipId || channelData.id,
+            name: channelData.name || `通道${i + 1}`,
+            ...channelData.basicData
+          }
+        })
+      }
+    }
+
+    // 并行执行所有sendDevicePush请求
+    if (operations.length > 0) {
+      const promises = operations.map(({ playData, index, channelData }) =>
+        sendDevicePush(playData, index)
+          .then(() => {
+            // 成功后的回调
+            if (videoUrl.value[index]) {
+              channelData._playUrl = videoUrl.value[index]
+            }
+            return { success: true, index }
+          })
+          .catch((error) => {
+            console.error(`通道${index + 1}加载失败:`, error)
+            return { success: false, index, error }
+          })
+      )
+
+      // 使用allSettled而不是all,这样即使有失败也不会中断其他请求
+      await Promise.allSettled(promises)
+    }
+  } catch (error) {
+    console.error('加载新增通道出错:', error)
+  } finally {
+    loading.value = false
+  }
+}
+
 watch(
   () => spilt.value,
   async (newSplit, oldSplit) => {
-    // 只有当分屏数增加(例如从1到4,或从4到9)且有当前选中设备时才执行
-    if (newSplit > oldSplit && currentDevice.value) {
-      console.log(
-        `分屏从 ${oldSplit} 变为 ${newSplit},自动填充设备 ${currentDevice.value.name} 的通道`
-      )
-
-      // 延迟执行,确保DOM更新完成
+    // 如果当前有选中的设备
+    if (currentDevice.value && availableChannels.value.length > 0) {
       await nextTick()
 
-      loading.value = true
-      try {
-        // 重新分配通道到所有播放器
-        await assignChannelsToPlayers(availableChannels.value)
-      } catch (error) {
-        console.error('分屏变化时填充通道出错:', error)
-        ElMessage.error('自动填充通道失败')
-      } finally {
-        loading.value = false
-      }
-    }
-    // 当分屏数减少时,清空超出当前通道数的播放器
-    else if (newSplit < oldSplit) {
-      // 清空超出当前分屏数或超出通道数的播放器
-      const maxVisible = Math.min(newSplit, availableChannels.value.length)
-      for (let i = maxVisible; i < Math.max(oldSplit, availableChannels.value.length); i++) {
-        const newVideoUrls = [...videoUrl.value]
-        if (newVideoUrls[i]) {
-          newVideoUrls[i] = ''
-          videoUrl.value = newVideoUrls
-          clear(i + 1) // 清理存储的数据
-        }
-      }
+      // 只加载新出现的播放器,不重新加载已有播放器
+      await loadAdditionalChannelsForSplit(newSplit, oldSplit)
     }
   },
   { immediate: false }
@@ -310,9 +393,6 @@ const getDeviceChannels = async (deviceId) => {
 const assignChannelsToPlayers = async (channels) => {
   const currentSplit = spilt.value
   const actualChannels = Math.min(channels.length, currentSplit)
-
-  console.log(`分配 ${actualChannels} 个通道到最多 ${currentSplit} 个播放窗口`)
-
   // 清空当前所有播放器
   const newVideoUrls = Array(Math.max(currentSplit, channels.length)).fill('')
   videoUrl.value = newVideoUrls
@@ -330,7 +410,7 @@ const assignChannelsToPlayers = async (channels) => {
       name: channelData.name || `通道${i + 1}`,
       ...channelData.basicData
     }
-    console.log(`将通道 ${playData.name} 分配给播放器 ${i}`)
+
     await sendDevicePush(playData, i)
   }
 
@@ -338,7 +418,7 @@ const assignChannelsToPlayers = async (channels) => {
 }
 
 // 通知设备上传媒体流
-const sendDevicePush = (itemData, targetIndex = null) => {
+const sendDevicePush = async (itemData, targetIndex = null) => {
   // 关键修改:允许从外部传入 targetIndex,默认使用当前激活的 playerIdx
   const playIndex = targetIndex !== null ? targetIndex : playerIdx.value