diff --git a/apps/web-antd/src/api/sis/stream/index.ts b/apps/web-antd/src/api/sis/stream/index.ts index 0f07b406..65f08721 100644 --- a/apps/web-antd/src/api/sis/stream/index.ts +++ b/apps/web-antd/src/api/sis/stream/index.ts @@ -7,7 +7,14 @@ import { requestClient } from '#/api/request'; * @returns 人像信息列表 */ export function addStreamProxy(params?: any) { - return requestClient.post('sis/stream//realtime/add', { + return requestClient.post( + 'sis/stream/realtime/add', params, - }); + ); +} +export function addFFmpegStreamProxy(params?: any) { + return requestClient.post( + 'sis/stream/realtime/addFfmpeg', + params, + ); } diff --git a/apps/web-antd/src/views/sis/video/index.vue b/apps/web-antd/src/views/sis/video/index.vue index b19e42d2..b306d229 100644 --- a/apps/web-antd/src/views/sis/video/index.vue +++ b/apps/web-antd/src/views/sis/video/index.vue @@ -40,7 +40,6 @@ import ChannelTree from './channel-tree.vue'; import mpegts from 'mpegts.js'; import { message } from 'ant-design-vue'; import { addStreamProxy } from '#/api/sis/stream'; -import type { AddStreamProxyQuery } from '#/api/sis/stream/model'; const selected = 'selected'; @@ -78,12 +77,13 @@ function playerSelect(index: number) { */ function onPlayerNumChanged(val: number) { // 1个屏幕 + const changeBeforeNum = playerNum.value; + let changeNum = 1; if (val === 1) { playerStyle.value = { width: '100%', height: '100%', }; - playerNum.value = 1; } // 4个屏幕 2*2 else if (val === 2) { @@ -91,7 +91,7 @@ function onPlayerNumChanged(val: number) { width: '50%', height: '50%', }; - playerNum.value = 4; + changeNum = 4; } // 9个屏幕 3*3 else if (val === 3) { @@ -99,7 +99,7 @@ function onPlayerNumChanged(val: number) { width: '33.33%', height: '33.33%', }; - playerNum.value = 9; + changeNum = 9; } // 16个屏幕 4*4 else { @@ -107,7 +107,29 @@ function onPlayerNumChanged(val: number) { width: '25%', height: '25%', }; - playerNum.value = 16; + changeNum = 16; + } + playerNum.value = changeNum; + // 缩小布局 + if (changeBeforeNum > changeNum) { + debugger; + const playerArr = []; + for (let i = 0; i < playerList.length; i++) { + const playerBox = playerList[i]; + if (playerBox) { + playerArr.push(playerBox); + } + playerList[i] = null; + } + for (let i = 0; i < playerArr.length; i++) { + const play = playerArr[i]; + if (i < changeNum) { + // 获取播放元素 + changeElPlayer(play, i); + } else { + closePlayVieo(play.player); + } + } } } @@ -151,8 +173,12 @@ function onNodeChecked( } // 新增 if (checked) { - if (currentSelectPlayerIndex.value === -1 && checkNode.length == 0) { - doPlayer(checkNode[0], currentSelectPlayerIndex.value); + /** + * 如果当前页面有选择播放未知,并且播放视频只有一个,则播放到制定位置 + */ + debugger; + if (currentSelectPlayerIndex.value !== -1 && checkNode.length == 1) { + doPlayer(checkNode[0], currentSelectPlayerIndex.value - 1); } // 批量播放 currentSelectPlayerIndex 将不再生效 else { @@ -196,6 +222,42 @@ function onNodeChecked( } } +function changeElPlayer(playerInfo: any, index: number) { + const playerData = playerInfo.data; + const oldPlayer = playerInfo.player; + if (oldPlayer) { + closePlayVieo(oldPlayer); + } + const videoConfig = { + type: 'flv', + url: playerData.url, + isLive: true, + hasAudio: false, + hasVideo: true, + enableWorker: true, // 启用分离的线程进行转码 + enableStashBuffer: false, // 关闭IO隐藏缓冲区 + stashInitialSize: 256, // 减少首帧显示等待时长 + }; + const playerConfig = { + enableErrorRecover: true, // 启用错误恢复 + autoCleanupMaxBackwardDuration: 30, + autoCleanupMinBackwardDuration: 10, + }; + const player = mpegts.createPlayer(videoConfig, playerConfig); + const videoElement = itemRefs.value[index]; + if (videoElement) { + player.attachMediaElement(videoElement); + player.load(); + player.play(); + playerList[index] = { + player, + data: playerData, + }; + } else { + console.log('视频播放元素获取异常'); + } +} + /** * 开始播放视频流 * @param nodeData 播放的节点数据 @@ -213,16 +275,18 @@ function doPlayer(nodeData: any, index: number) { }; addStreamProxy(params).then((res) => { const url = res.wsFlv; + // 将url 绑定到 nodeData + nodeData.url = url; closePlayer(index); const videoConfig = { type: 'flv', url: url, isLive: true, - hasAudio: true, + hasAudio: false, hasVideo: true, enableWorker: true, // 启用分离的线程进行转码 enableStashBuffer: false, // 关闭IO隐藏缓冲区 - stashInitialSize: 128, // 减少首帧显示等待时长 + stashInitialSize: 256, // 减少首帧显示等待时长 }; const playerConfig = { enableErrorRecover: true, // 启用错误恢复 @@ -248,6 +312,18 @@ function doPlayer(nodeData: any, index: number) { } } +function closePlayVieo(plInfo: any) { + if (plInfo) { + try { + plInfo.pause(); // 暂停 + plInfo.unload(); // 卸载 + plInfo.destroy(); // 销毁 + } catch (e) { + console.log('播放器关闭失败,e=', e); + } + } +} + function closePlayer(index: number) { // 如果播放器存在,尝试关闭 const pData = playerList[index];