yanghao 6 päivää sitten
vanhempi
commit
5834aa6cbd
1 muutettua tiedostoa jossa 39 lisäystä ja 50 poistoa
  1. 39 50
      src/views/pms/video_center/sip/splitview.vue

+ 39 - 50
src/views/pms/video_center/sip/splitview.vue

@@ -52,23 +52,25 @@
             </el-button>
           </div>
           <div style="height: 85vh; display: flex; flex-wrap: wrap">
-            <!-- 只渲染实际可用的通道数量,不超过当前分屏数量 -->
+            <!-- 渲染所有分屏数量的播放框 -->
             <div
-              v-for="i in Math.min(spilt, availableChannels.length || spilt)"
+              v-for="i in spilt"
               :key="i"
               class="play-box"
               :style="liveStyle"
               :class="{ redborder: playerIdx == i - 1 }"
               @click="playerIdx = i - 1"
             >
+              <!-- 显示序号,如果该位置没有视频或不在可用通道范围内 -->
               <div
-                v-if="!videoUrl[i - 1]"
+                v-if="!videoUrl[i - 1] || i - 1 >= availableChannels.length"
                 style="color: #ffffff; font-size: 30px; font-weight: bold"
               >
                 {{ i }}
               </div>
+              <!-- 只有当有视频URL时才渲染播放器 -->
               <player
-                v-else
+                v-if="videoUrl[i - 1]"
                 :ref="(el) => setPlayerRef(el, i - 1)"
                 :videourl="videoUrl[i - 1]"
                 :playerInfo="
@@ -84,30 +86,6 @@
                 @destroy="destroy"
               />
             </div>
-
-            <!-- 如果通道数少于分屏数,显示空白占位 -->
-            <div
-              v-for="i in Math.max(0, spilt - availableChannels.length)"
-              :key="`empty-${i}`"
-              :class="availableChannels.length > 0 ? 'play-box' : ''"
-              :style="availableChannels.length > 0 ? liveStyle : ''"
-              @click="handleEmpty(i)"
-            >
-              <div
-                v-if="availableChannels.length > 0"
-                style="
-                  color: #ffffff;
-                  font-size: 30px;
-                  font-weight: bold;
-                  display: flex;
-                  align-items: center;
-                  justify-content: center;
-                  height: 100%;
-                "
-              >
-                {{ availableChannels.length + i }}
-              </div>
-            </div>
           </div>
         </el-main>
       </el-container>
@@ -323,24 +301,23 @@ let playerInfo = ref([])
 const clickEvent = async (data) => {
   // 情况1:点击的是设备节点 (type === 0)
   if (data.type === 0) {
+    // 重置选中的空闲槽位
+    selectedEmptySlot.value = -1
+
     currentDevice.value = {
       id: data.userData?.serialNumber,
       name: data.name,
       data: data
     }
-    const deviceId = data.userData?.serialNumber // 从树节点数据中提取设备ID
+    const deviceId = data.userData?.serialNumber
     if (!deviceId) return
 
     loading.value = true
     try {
-      // 1. 获取该设备下的所有通道
       const channels = await getDeviceChannels(deviceId)
-
-      // 只保留摄像头类型的通道
       const cameraChannels = channels.filter((channel) => channel.basicData.model === 'Camera')
       availableChannels.value = cameraChannels
 
-      // 清空之前的数据
       playerInfo.value = []
       cameraChannels.forEach((channel) => {
         playerInfo.value.push(channel)
@@ -348,13 +325,11 @@ const clickEvent = async (data) => {
 
       if (!cameraChannels || cameraChannels.length === 0) {
         console.warn('该设备下没有可用的摄像头通道')
-        // 清空所有播放器
         const newVideoUrls = Array(spilt.value).fill('')
         videoUrl.value = newVideoUrls
         return
       }
 
-      // 2. 将通道智能分配给播放器
       await assignChannelsToPlayers(cameraChannels)
     } catch (error) {
       console.error('处理设备通道时出错:', error)
@@ -362,10 +337,20 @@ const clickEvent = async (data) => {
       loading.value = false
     }
   }
-  // 情况2:点击的是具体的通道节点,保持原有逻辑不变
+  // 情况2:点击的是具体的通道节点
   else if (data.userData?.channelSipId) {
-    playerIdx.value = 0
-    await sendDevicePush(data.userData)
+    // 检查是否有选中的空闲槽位
+    let targetIndex = selectedEmptySlot.value !== -1 ? selectedEmptySlot.value : playerIdx.value
+
+    // 验证目标索引是否在有效范围内
+    if (targetIndex >= spilt.value) {
+      targetIndex = playerIdx.value // 回退到当前选中的播放器
+    }
+
+    // 重置选中的空闲槽位
+    selectedEmptySlot.value = -1
+
+    await sendDevicePush(data.userData, targetIndex)
   }
 }
 
@@ -383,17 +368,15 @@ const getDeviceChannels = async (deviceId) => {
 const assignChannelsToPlayers = async (channels) => {
   const currentSplit = spilt.value
   const actualChannels = Math.min(channels.length, currentSplit)
-  // 清空当前所有播放器
-  const newVideoUrls = Array(Math.max(currentSplit, channels.length)).fill('')
+  // 初始化所有播放器位置
+  const newVideoUrls = Array(currentSplit).fill('')
   videoUrl.value = newVideoUrls
 
   // 为每个可用通道分配播放器
   for (let i = 0; i < actualChannels; i++) {
-    // 延迟执行,避免同时发起大量请求
     await new Promise((resolve) => setTimeout(resolve, 50))
 
     const channelData = channels[i]
-    // 构建符合 sendDevicePush 要求的参数格式
     const playData = {
       deviceSipId: channelData.deviceId,
       channelSipId: channelData.basicData?.channelSipId || channelData.id,
@@ -403,8 +386,6 @@ const assignChannelsToPlayers = async (channels) => {
 
     await sendDevicePush(playData, i)
   }
-
-  // 如果通道数少于当前分屏数,不需要做额外处理,因为已经清空了超出部分
 }
 
 // 通知设备上传媒体流
@@ -412,7 +393,10 @@ const sendDevicePush = async (itemData, targetIndex = null) => {
   // 关键修改:允许从外部传入 targetIndex,默认使用当前激活的 playerIdx
   const playIndex = targetIndex !== null ? targetIndex : playerIdx.value
 
-  save(itemData, playIndex) // 保存数据也要使用正确的索引
+  // 确保索引在有效范围内
+  const validIndex = Math.min(playIndex, spilt.value - 1)
+
+  save(itemData, validIndex) // 保存数据也要使用正确的索引
 
   let deviceId = itemData.deviceSipId
   let channelId = itemData.channelSipId
@@ -427,7 +411,7 @@ const sendDevicePush = async (itemData, targetIndex = null) => {
         itemData.playUrl = res.playurl
       }
       itemData.streamId = res.streamId
-      setPlayUrl(itemData.playUrl, playIndex) // 播放URL设置到指定位置
+      setPlayUrl(itemData.playUrl, validIndex) // 播放URL设置到指定位置
     })
     .finally(() => {
       loading.value = false
@@ -460,11 +444,16 @@ const checkPlayByParam = () => {
   }
 }
 
+// 存储当前选中的空闲槽位
+const selectedEmptySlot = ref(-1)
+
 const handleEmpty = (i) => {
-  // playerIdx.value = availableChannels.value.length + i - 1
-  // if (availableChannels.value.length > 0) {
-  //   playerIdx.value = 0 // 设置为第一个播放器
-  // }
+  // 计算当前点击的空闲槽位的实际索引
+  const slotIndex = availableChannels.value.length + i - 1
+  selectedEmptySlot.value = slotIndex
+  playerIdx.value = slotIndex
+
+  console.log('选中空闲槽位:', slotIndex)
 }
 
 // 截图处理