flx:视频监控新增码流切换

This commit is contained in:
Rain_ 2025-12-12 10:11:47 +08:00
parent 7c6692c5f5
commit 1f0e0c0a0b
3 changed files with 848 additions and 728 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -2,7 +2,13 @@
<div id="player-main">
<div id="player"></div>
<!-- 为每个窗口添加控制按钮容器 -->
<div class="video-controls" v-for="i in videoInfo.maxWindows" :key="i" :id="'controls-' + i" :style="{ display: 'none' }">
<div
class="video-controls"
v-for="i in videoInfo.maxWindows"
:key="i"
:id="'controls-' + i"
:style="{ display: 'none' }"
>
<div class="controls-top">
<div class="top-left">{{ videoNameUp(i - 1) }}</div>
<div @click="stopPlay(i)" class="top-close">
@ -13,10 +19,45 @@
<div class="controls-bottom">
<div></div>
<div>
<el-tooltip class="item" effect="dark" :content="`${videoInfo.talkbackBegin ? '结束' : '开始'}对讲`" placement="top">
<div class="bgImage talkback" :class="{ talkback_active: videoInfo.talkbackBegin }" @click="isTalkback(i)"></div>
<el-tooltip
class="item"
effect="dark"
:content="`${
videoInfo.devH5List[i - 1] &&
videoInfo.devH5List[i - 1].defaultStreamTypeCut
? '主'
: '子'
}码流`"
placement="top"
>
<div
class="bgImage codestream"
:class="{
codestream_active:
videoInfo.devH5List[i - 1] &&
videoInfo.devH5List[i - 1].defaultStreamTypeCut,
}"
@click="isCodeStream(i)"
></div>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="`${videoInfo.recordingBegin ? '结束' : '开始'}录制`" placement="top">
<el-tooltip
class="item"
effect="dark"
:content="`${videoInfo.talkbackBegin ? '结束' : '开始'}对讲`"
placement="top"
>
<div
class="bgImage talkback"
:class="{ talkback_active: videoInfo.talkbackBegin }"
@click="isTalkback(i)"
></div>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
:content="`${videoInfo.recordingBegin ? '结束' : '开始'}录制`"
placement="top"
>
<div class="bgImage transcribe" @click="isTranscribe(i)"></div>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="`抓图`" placement="top">
@ -24,10 +65,24 @@
</el-tooltip>
<!-- <div>流畅</div> -->
<el-tooltip class="item" effect="dark" :content="`${!videoInfo.muted ? '关闭' : '开启'}音量`" placement="top">
<div @click="handleVolume(i)" :class="!videoInfo.muted ? 'openVolume' : 'disableVolume'" class="bgImage"></div>
<el-tooltip
class="item"
effect="dark"
:content="`${!videoInfo.muted ? '关闭' : '开启'}音量`"
placement="top"
>
<div
@click="handleVolume(i)"
:class="!videoInfo.muted ? 'openVolume' : 'disableVolume'"
class="bgImage"
></div>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="`${videoInfo.isFullScreen ? '退出' : '进入'}全屏模式`" placement="top">
<el-tooltip
class="item"
effect="dark"
:content="`${videoInfo.isFullScreen ? '退出' : '进入'}全屏模式`"
placement="top"
>
<div
class="bgImage"
:class="videoInfo.isFullScreen ? 'exitFullScreen' : 'fullScreen'"
@ -50,8 +105,17 @@
<el-tooltip class="item" effect="dark" :content="`停止所有播放`" placement="top">
<div class="bgImage stopAll" @click="stopAllPlay"></div>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="`${videoInfo.isFullScreen ? '退出' : '进入'}全屏模式`" placement="top">
<div class="bgImage" :class="videoInfo.isFullScreen ? 'exitFullScreen' : 'fullScreen'" @click="wholeFullScreen(i)"></div>
<el-tooltip
class="item"
effect="dark"
:content="`${videoInfo.isFullScreen ? '退出' : '进入'}全屏模式`"
placement="top"
>
<div
class="bgImage"
:class="videoInfo.isFullScreen ? 'exitFullScreen' : 'fullScreen'"
@click="wholeFullScreen(i)"
></div>
</el-tooltip>
</div>
</div>
@ -72,8 +136,8 @@ import reloadImg from "@/assets/images/iscImage/reload.png";
const props = defineProps({
devList: {
type: Array,
default: () => []
}
default: () => [],
},
});
const emit = defineEmits(["selectPlayVideo"]);
const videoInfo = reactive({
@ -92,12 +156,18 @@ const videoInfo = reactive({
endTime: "2023-08-16T23:00:00",
valueFormat: moment.HTML5_FMT.DATETIME_LOCAL_SECONDS,
seekStart: "2023-08-16T10:00:00",
rate: ""
rate: "",
},
isFullScreen: false,
isFullScreenAll: false,
randomNumber: ""
randomNumber: "",
});
const isCodeStream = (i) => {
console.log("isCodeStream", videoInfo.devH5List[i]);
videoInfo.devH5List[i - 1].defaultStreamTypeCut =
videoInfo.devH5List[i - 1].defaultStreamTypeCut == 1 ? 0 : 1;
play(videoInfo.devH5List[i - 1], i - 1);
};
//
const stopAllPlay = () => {
videoInfo.player.JS_StopRealPlayAll().then(
@ -111,7 +181,9 @@ const stopAllPlay = () => {
if (controls) {
controls.classList.remove("video-controls_flex");
}
const findIndex = Array.from(wnd.childNodes).findIndex(item => item.localName == "img" || item.className == "classImg");
const findIndex = Array.from(wnd.childNodes).findIndex(
(item) => item.localName == "img" || item.className == "classImg"
);
if (findIndex !== -1) {
wnd.removeChild(wnd.childNodes[findIndex]);
}
@ -119,7 +191,7 @@ const stopAllPlay = () => {
});
videoInfo.devH5List = [];
},
e => {
(e) => {
console.error(e);
}
);
@ -130,13 +202,17 @@ const stopPlay = (currentWindowIndex, type) => {
() => {
videoInfo.playback.rate = 0;
console.log("stop realplay success");
const wnd = document.querySelector(`#player #player-container-${currentWindowIndex - 1}`);
const wnd = document.querySelector(
`#player #player-container-${currentWindowIndex - 1}`
);
if (wnd) {
const controls = document.getElementById(`controls-${currentWindowIndex}`);
if (controls) {
controls.classList.remove("video-controls_flex");
}
const findIndex = Array.from(wnd.childNodes).findIndex(item => item.localName == "img" || item.className == "classImg");
const findIndex = Array.from(wnd.childNodes).findIndex(
(item) => item.localName == "img" || item.className == "classImg"
);
if (findIndex !== -1) {
wnd.removeChild(wnd.childNodes[findIndex]);
}
@ -144,12 +220,12 @@ const stopPlay = (currentWindowIndex, type) => {
// videoInfo.devH5List.splice(currentWindowIndex - 1, 1);
}
},
e => {
(e) => {
console.error(e);
}
);
};
const handleVolume = currentWindowIndex => {
const handleVolume = (currentWindowIndex) => {
if (videoInfo.muted) {
openSound(currentWindowIndex);
} else {
@ -157,30 +233,30 @@ const handleVolume = currentWindowIndex => {
}
};
/* 声音、抓图、录像 */
const openSound = currentWindowIndex => {
const openSound = (currentWindowIndex) => {
videoInfo.player.JS_OpenSound(currentWindowIndex - 1).then(
() => {
console.log("openSound success");
videoInfo.muted = false;
},
e => {
(e) => {
console.error(e);
}
);
};
const closeSound = currentWindowIndex => {
const closeSound = (currentWindowIndex) => {
videoInfo.player.JS_CloseSound(currentWindowIndex - 1).then(
() => {
console.log("closeSound success");
videoInfo.muted = true;
},
e => {
(e) => {
console.error(e);
}
);
};
//
const singleFullScreen = currentWindowIndex => {
const singleFullScreen = (currentWindowIndex) => {
if (videoInfo.isFullScreenAll) {
videoInfo.wholeFullScreen();
return;
@ -189,7 +265,7 @@ const singleFullScreen = currentWindowIndex => {
() => {
console.log(`singleFullScreen success`);
},
e => {
(e) => {
console.error(e);
}
);
@ -201,12 +277,12 @@ const wholeFullScreen = () => {
console.log(`wholeFullScreen success`);
videoInfo.isFullScreenAll = !videoInfo.isFullScreenAll;
},
e => {
(e) => {
console.error(e);
}
);
};
const isTalkback = currentWindowIndex => {
const isTalkback = (currentWindowIndex) => {
if (videoInfo.talkbackBegin) {
talkbackStop(currentWindowIndex);
} else {
@ -214,14 +290,14 @@ const isTalkback = currentWindowIndex => {
}
};
//
const talkbackStart = currentWindowIndex => {
const talkbackStart = (currentWindowIndex) => {
let player = videoInfo.player,
index = currentWindowIndex - 1;
getTalkURLsApi({
protocol: "wss",
projectSn: videoInfo.devH5List[index].projectSn,
serialNumber: videoInfo.devH5List[index].serialNumber
}).then(res => {
serialNumber: videoInfo.devH5List[index].serialNumber,
}).then((res) => {
const res2 = JSON.parse(res.result);
if (!res2.data) {
ElMessage.warning("获取url失败");
@ -242,7 +318,7 @@ const talkbackStart = currentWindowIndex => {
openSound(currentWindowIndex);
console.log("record start ...");
},
e => {
(e) => {
console.error(e);
ElMessage.error("对讲连接失败");
}
@ -250,21 +326,21 @@ const talkbackStart = currentWindowIndex => {
});
};
//
const talkbackStop = currentWindowIndex => {
const talkbackStop = (currentWindowIndex) => {
let player = videoInfo.player;
player.JS_StopTalk().then(
res => {
(res) => {
console.log("record stoped, saving ...", res);
videoInfo.talkbackBegin = false;
closeSound(currentWindowIndex);
},
e => {
(e) => {
console.error(e);
}
);
};
const isTranscribe = currentWindowIndex => {
const isTranscribe = (currentWindowIndex) => {
if (videoInfo.recordingBegin) {
recordStop(currentWindowIndex);
} else {
@ -283,7 +359,7 @@ const recordStart = (type, currentWindowIndex) => {
player
.JS_StartSaveEx(index, fileName, typeCode, {
irecordType: 1,
cbStreamCB: videoInfo.streamcb
cbStreamCB: videoInfo.streamcb,
})
.then(
() => {
@ -291,22 +367,22 @@ const recordStart = (type, currentWindowIndex) => {
videoInfo.recordingBegin = true;
console.log("record start ...");
},
e => {
(e) => {
console.error(e);
}
);
};
//
const recordStop = currentWindowIndex => {
const recordStop = (currentWindowIndex) => {
let player = videoInfo.player,
index = currentWindowIndex - 1;
player.JS_StopSave(index).then(
res => {
(res) => {
console.log("record stoped, saving ...", res);
videoInfo.recordingBegin = false;
},
e => {
(e) => {
console.error(e);
}
);
@ -320,7 +396,7 @@ const capture = (imageType, currentWindowIndex) => {
() => {
console.log("capture success", imageType);
},
e => {
(e) => {
console.error(e);
}
);
@ -348,8 +424,8 @@ const initPlayer = () => {
oStyle: {
border: "#343434",
borderSelect: "#FFCC00",
background: "#000"
}
background: "#000",
},
});
//
videoInfo.player.JS_SetWindowControlCallback({
@ -383,10 +459,10 @@ const initPlayer = () => {
// if (iWndIndex > videoInfo.devH5List.length - 1) return;
// controls.classList.add("video-controls_flex");
const player_playVideo = wnd.querySelector(`#player_playVideo${iWndIndex}`);
const findFlag = Array.from(wnd.childNodes).find(item => {
const findFlag = Array.from(wnd.childNodes).find((item) => {
return item.id && item.id.includes("player_playVideo");
});
const findImg = Array.from(wnd.childNodes).some(item => {
const findImg = Array.from(wnd.childNodes).some((item) => {
return item.className == "classImg";
});
// console.log(8848, findFlag, findImg, player_playVideo);
@ -433,15 +509,24 @@ const initPlayer = () => {
console.log("recv StreamHeadChanged: ", iWndIndex);
},
ThumbnailsEvent: (iWndIndex, eventType, eventCode) => {
console.log("recv ThumbnailsEvent: " + iWndIndex + ", eventType:" + eventType + ", eventCode:" + eventCode);
console.log(
"recv ThumbnailsEvent: " +
iWndIndex +
", eventType:" +
eventType +
", eventCode:" +
eventCode
);
},
InterruptStream: (iWndIndex, iTime) => {
console.log("recv InterruptStream: " + iWndIndex + ", iTime:" + iTime);
},
ElementChanged: (iWndIndex, szElementType) => {
//videocanvas
console.log("recv ElementChanged: " + iWndIndex + ", szElementType:" + szElementType);
}
console.log(
"recv ElementChanged: " + iWndIndex + ", szElementType:" + szElementType
);
},
});
console.log(videoInfo.devH5List, 554455544);
videoInfo.devH5List.forEach((item, index) => {
@ -452,16 +537,24 @@ const initPlayer = () => {
* 获取取流连接
* @returns {*}
*/
const getPreviewUrl = row => {
const getPreviewUrl = (row) => {
let tempCode = row.serialNumber;
const param = {
cameraIndexCode: tempCode,
// streamType: row.defaultStreamType == 2 ? 0 : row.defaultStreamType,
streamType: row.defaultStreamType && row.eIndex < 4 ? row.defaultStreamType : "",
streamType:
row.defaultStreamType && row.eIndex < 4
? row.defaultStreamType == 1
? ""
: 2
: "",
type: window.location.protocol.includes("https") ? "wss" : "ws",
transmode: 1,
itemId: row.itemId
itemId: row.itemId,
};
if (row.defaultStreamTypeCut == 0) {
param.streamType = 2;
}
//
return getVideoItemInfo(param);
};
@ -471,20 +564,20 @@ const getPreviewUrl = row => {
const play = (row, index) => {
stopPlay(index + 1, "delete");
getPreviewUrl({
...row
}).then(res => {
...row,
}).then((res) => {
if (res.code !== 200 && !res.result.videoInfo) {
ElMessage.warning("获取视频流失败!");
return;
}
videoInfo.devH5List.splice(index, 1, {
...row,
url: res.result.videoInfo.url
url: res.result.videoInfo.url,
});
//
const id = "player-container-" + index;
var d1 = document.getElementById(id); //div
d1.childNodes.forEach(item => {
d1.childNodes.forEach((item) => {
if (item.nodeName == "" || item.nodeName == "IMG") {
d1.removeChild(item);
}
@ -508,13 +601,15 @@ const play = (row, index) => {
const param = {
playURL: preUrl,
// 1 0
mode: 0
mode: 0,
};
// 0
if (!index) {
index = 0;
}
const findIndex = Array.from(d1.childNodes).findIndex(item => item.localName == "img");
const findIndex = Array.from(d1.childNodes).findIndex(
(item) => item.localName == "img"
);
videoInfo.player.JS_Play(preUrl, param, index).then(
() => {
if (findIndex !== -1) {
@ -522,7 +617,7 @@ const play = (row, index) => {
console.log("播放成功", findIndex);
}
},
err => {
(err) => {
console.log("播放失败");
// im.src = errorPng;
// const imgHeightNum = 20;
@ -563,13 +658,15 @@ const play = (row, index) => {
}
);
videoInfo.iWndIndex =
videoInfo.iWndIndex >= videoInfo.numCount * videoInfo.numCount - 1 ? videoInfo.iWndIndex : videoInfo.iWndIndex + 1;
videoInfo.iWndIndex >= videoInfo.numCount * videoInfo.numCount - 1
? videoInfo.iWndIndex
: videoInfo.iWndIndex + 1;
videoInfo.player.JS_SelectWnd(videoInfo.iWndIndex).then(
() => {
console.info("JS_SelectWnd success");
// do you want...
},
err => {
(err) => {
console.info("JS_SelectWnd failed");
// do you want...
}
@ -579,7 +676,7 @@ const play = (row, index) => {
console.info("JS_SetConnectTimeOut success");
// do you want...
},
err => {
(err) => {
console.info("JS_SetConnectTimeOut failed", err);
// do you want...
}
@ -589,12 +686,12 @@ const play = (row, index) => {
const onReload = (id) => {
console.log("重新加载", id);
//
const findItem = videoInfo.devH5List.find(item => item.itemId === id);
const findItem = videoInfo.devH5List.find((item) => item.itemId === id);
if (findItem) {
play(findItem, findItem.eIndex);
}
};
const onTwoSubmit = num => {
const onTwoSubmit = (num) => {
// 24
videoInfo.numCount = num;
videoInfo.player.JS_ArrangeWindow(num).then(
@ -604,7 +701,7 @@ const onTwoSubmit = num => {
// videoInfo.play(i);
// }
},
e => {
(e) => {
console.error(e);
}
);
@ -621,21 +718,26 @@ watch(
videoInfo.devH5List = [
{
...item,
eIndex: videoInfo.iWndIndex
}
eIndex: videoInfo.iWndIndex,
defaultStreamTypeCut: item.defaultStreamType,
},
];
} else if (a.length == 1) {
play(item, videoInfo.iWndIndex);
const findIndex = videoInfo.devH5List.findIndex(item => item.eIndex == videoInfo.iWndIndex);
const findIndex = videoInfo.devH5List.findIndex(
(item) => item.eIndex == videoInfo.iWndIndex
);
if (findIndex != -1) {
videoInfo.devH5List.splice(findIndex, 1, {
...item,
eIndex: videoInfo.iWndIndex
eIndex: videoInfo.iWndIndex,
defaultStreamTypeCut: item.defaultStreamType,
});
} else {
videoInfo.devH5List.push({
...item,
eIndex: videoInfo.iWndIndex
eIndex: videoInfo.iWndIndex,
defaultStreamTypeCut: item.defaultStreamType,
});
console.log("视频播放", videoInfo.devH5List);
}
@ -643,14 +745,19 @@ watch(
play(
{
...item,
eIndex: index
eIndex: index,
defaultStreamTypeCut: index > 3 ? 0 : item.defaultStreamType,
},
index
);
}
});
if (a.length > 1) {
videoInfo.devH5List = a.map((item, index) => ({ ...item, eIndex: index }));
videoInfo.devH5List = a.map((item, index) => ({
...item,
eIndex: index,
defaultStreamTypeCut: index > 3 ? 0 : item.defaultStreamType,
}));
}
},
{ deep: true }
@ -659,16 +766,22 @@ watch(
() => videoInfo.randomNumber,
(a, b) => {
// 使
const wnd = document.querySelector(`#player #player-container-${videoInfo.iWndIndex}`);
const wnd = document.querySelector(
`#player #player-container-${videoInfo.iWndIndex}`
);
if (wnd) {
const controls = document.getElementById(`controls-${videoInfo.iWndIndex + 1}`);
if (controls) {
const player_playVideo = wnd.querySelector(`#player_playVideo${videoInfo.iWndIndex}`);
const player_playVideo = wnd.querySelector(
`#player_playVideo${videoInfo.iWndIndex}`
);
if (player_playVideo.src || player_playVideo.poster) {
const find = videoInfo.devH5List.find((item, eIndex) => videoInfo.iWndIndex == eIndex);
const find = videoInfo.devH5List.find(
(item, eIndex) => videoInfo.iWndIndex == eIndex
);
if (find) {
emit("selectPlayVideo", {
...find
...find,
});
}
}
@ -677,8 +790,8 @@ watch(
}
);
const videoNameUp = computed(() => {
return index => {
const find = videoInfo.devH5List.find(item => item.eIndex === index);
return (index) => {
const find = videoInfo.devH5List.find((item) => item.eIndex === index);
return find ? find.videoName : "";
};
});
@ -686,7 +799,8 @@ onMounted(() => {
nextTick(() => {
videoInfo.devH5List = props.devList.map((item, index) => ({
...item,
eIndex: index
eIndex: index,
defaultStreamTypeCut: index > 3 ? 0 : item.defaultStreamType,
}));
console.log("我进来了", props.devList);
// `
@ -730,11 +844,17 @@ onMounted(() => {
height: 20px;
background-image: url("@/assets/images/iscImage/transcribe.png");
}
.codestream {
background-image: url("@/assets/images/iscImage/codestream2.png");
}
.codestream_active {
background-image: url("@/assets/images/iscImage/codestream1.png");
}
.talkback {
background-image: url("@/assets/images/iscImage/talkback.png");
}
.talkback_active {
background-image: url("~@/assets/images/iscImage/talkback_active.png");
background-image: url("@/assets/images/iscImage/talkback_active.png");
}
.screenshot {
background-image: url("@/assets/images/iscImage/screenshot.png");