<template> <div id="index"> <div ref="playWnd" :id="containerId" class="playWnd" v-html="AllData.oWebControl === null ? AllData.playText : ''" ></div> </div> </template> <script setup name="index"> import { ref, reactive, toRefs, onMounted } from "vue"; const props = defineProps({ // 内网、公网 4个配置 appkey: { type: String, default: () => "25124952", }, secret: { type: String, default: () => "aJOYWAt8CJabjjA1Ekeq", }, ip: { type: String, default: () => "113.57.101.104", }, port: { type: Number, default: () => 8888, }, // 视频布局 layout: { type: String, default: () => "1x1", }, // 初始播放模式:0-预览,1-回放 playMode: { type: Number, default: () => 0, }, // 是否显示工具栏,0-不显示,非0-显示 showToolbar: { type: Number, default: () => 1, }, // 工具栏按钮 toolBarButtonIDs: { type: String, default: () => "4098,4097", }, // 是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示 showSmart: { type: Number, default: () => 1, }, // 自定义工具条按钮 buttonIDs: { type: String, default: () => "0,16,256,257,258,259,512,260,515,516,517,768,769", }, // 相机编号 cameraIndexCode: { type: [String, Number], }, // 视频播放容器id containerId: { type: String, default: () => "playWnd", }, // 默认打开的视频 defaultList: { type: Array, default: () => [], }, }); const AllData = reactive({ oWebControl: null, plugKey: "", // 视频相关参数 videoParams: { cameraIndexCode: "", //监控点编号 streamMode: 0, //主子码流标识:0-主码流,1-子码流 transMode: 1, //传输协议:0-UDP,1-TCP gpuMode: 0, //是否启用GPU硬解,0-不启用,1-启用 wndId: 1, //播放窗口序号 }, videoWidth: null, videoHeight: null, playText: "启动中...", initCount: 0, // 启动次数 href: "", }); // 视频容器的ref对象 const playWnd = ref(null); // 监听视频编码的改变(单个视频编码) watch( () => props.cameraIndexCode, (val) => { if (props.cameraIndexCode) { AllData.videoParams.cameraIndexCode = props.cameraIndexCode.trim(); AllData.videoParams.wndId = -1; // debugger; if (AllData.oWebControl) { previewVideo(); } else { createdVideo(); } } } ); // 监听视频编码数组的改变(批量视频编码) watch( () => props.defaultList, (val) => { if (props.defaultList.length > 0) { PiLiangpreviewVideo(); } } ); // 监听布局修改 watch( () => props.layout, (val) => { setLayoutFunc(); } ); // 创建播放实例 const initPlugin = (callback) => { AllData.oWebControl = new WebControl({ szPluginContainer: props.containerId, // 指定容器id iServicePortStart: 15900, iServicePortEnd: 15909, szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid // 创建WebControl实例成功 cbConnectSuccess: () => { AllData.oWebControl .JS_StartService("window", { // WebControl实例创建成功后需要启动服务 dllPath: "./VideoPluginConnect.dll", }) .then(() => { // 启动插件服务成功 AllData.oWebControl.JS_SetWindowControlCallback({ // 设置消息回调 cbIntegrationCallBack: cbIntegrationCallBack, }); AllData.oWebControl .JS_CreateWnd(props.containerId, AllData.videoWidth, AllData.videoHeight) .then(() => { getVersion(callback); }); }); }, cbConnectError: () => { // 创建WebControl实例失败 AllData.oWebControl = null; AllData.playText = "插件未启动,正在尝试启动,请稍候..."; WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序 AllData.initCount++; if (AllData.initCount < 3) { setTimeout(() => { initPlugin(); }, 3000); } else { AllData.playText = ` 插件启动失败,请检查插件是否安装! <a href=${AllData.href} type="primary" download="视频插件.exe" style='color:#4194fc'>下载地址</a>`; } }, cbConnectClose: () => { AllData.oWebControl = null; }, }); }; // HK插件控制监听的消息回调 const cbIntegrationCallBack = (oData) => { console.log(oData); if (oData.responseMsg.type == 6) { // 此时是当前画幅的数据 console.log( `当前画面的画幅是` + oData.responseMsg.msg.layout, oData.responseMsg.msg.wndNum ); localStorage.setItem("HKlayout", oData.responseMsg.msg.layout); localStorage.setItem("HKwndNum", oData.responseMsg.msg.wndNum); } }; // 初始化 const init = (callback) => { getPubKey(() => { AllData.oWebControl .JS_RequestInterface({ funcName: "init", argument: JSON.stringify({ appkey: props.appkey, //API网关提供的appkey secret: setEncrypt(props.secret), //API网关提供的secret ip: props.ip, //API网关IP地址z playMode: props.playMode, //播放模式(决定显示预览还是回放界面) port: props.port, //端口 snapDir: "C:\\SnapDir", //抓图存储路径 videoDir: "C:\\VideoDir", //紧急录像或录像剪辑存储路径 layout: props.layout, //布局 enableHTTPS: 1, //是否启用HTTPS协议 encryptedFields: "secret", //加密字段 showToolbar: props.showToolbar, //是否显示工具栏 toolBarButtonIDs: props.toolBarButtonIDs, showSmart: props.showSmart, //是否显示智能信息 buttonIDs: props.buttonIDs, //自定义工具条按钮 protocol: "hls", }), }) .then(() => { AllData.videoWidth = playWnd.value.offsetWidth; AllData.videoHeight = playWnd.value.offsetHeight; // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题 AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight); // 判断当前cameraIndexCode中是否有数据 有数据的话就直接进行播放 if (props.defaultList.length > 0) { // 批量渲染 PiLiangpreviewVideo(); } else if (props.cameraIndexCode.length > 0) { // 单独渲染 AllData.videoParams.cameraIndexCode = props.cameraIndexCode.trim(); previewVideo(); } if (callback) { callback(); } }); }); }; // 获取公钥 const getPubKey = (callback) => { const params = { funcName: "getRSAPubKey", argument: JSON.stringify({ keyLength: 1024 }), }; AllData.oWebControl.JS_RequestInterface(params).then((res) => { if (res.responseMsg.data) { AllData.plugKey = res.responseMsg.data; callback(); } }); }; // 视频流RSA加密 const setEncrypt = (value) => { const encrypt = new JSEncrypt(); encrypt.setPublicKey(AllData.plugKey); return encrypt.encrypt(value); }; // 视频预览 const previewVideo = () => { console.log(AllData.videoParams, "单个视频播放"); AllData.oWebControl.JS_RequestInterface({ funcName: "startPreview", argument: JSON.stringify(AllData.videoParams), }); }; // 批量预览 const PiLiangpreviewVideo = () => { console.log(props.defaultList, "批量批量批量"); AllData.oWebControl.JS_RequestInterface({ funcName: "startMultiPreviewByCameraIndexCode", argument: { list: props.defaultList, }, }); }; // 显示全屏 const showFullScreen = () => { AllData.oWebControl.JS_RequestInterface({ funcName: "setFullScreen", }); }; // 退出全屏 const exitFullScreen = () => { AllData.oWebControl.JS_RequestInterface({ funcName: "exitFullScreen", }); }; const windowScroll = () => { if (AllData.oWebControl != null) { AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight); } }; // 获取HK父节点的宽高 const windowResize = () => { AllData.videoWidth = playWnd.value.offsetWidth; AllData.videoHeight = playWnd.value.offsetHeight; if (AllData.oWebControl) { AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight); } }; // 销毁海康插件 const destroyeWnd = () => { if (AllData.oWebControl) { AllData.oWebControl.JS_HideWnd(); AllData.oWebControl.JS_Disconnect().then(() => {}); } }; // 获取海康插件版本号 const getVersion = (callback) => { if (AllData.oWebControl) { AllData.oWebControl .JS_RequestInterface({ funcName: "getVersion", }) .then((res) => { if (res.responseMsg.code === 0 && res.responseMsg.data === "V1.5.1") { //JS_CreateWnd创建视频播放窗口,宽高可设定 init(callback); // 创建播放实例成功后初始化 console.log("启动插件成功!"); } else { destroyeWnd(); AllData.playText = ` 插件版本不正确,请重新下载版本安装覆盖! <a href=${AllData.href} type="primary" download="视频插件.exe" style='color:#4194fc'>下载地址</a>`; } }); } }; // 切换布局 const setLayoutFunc = () => { AllData.oWebControl.JS_RequestInterface({ funcName: "setLayout", argument: { layout: props.layout, // 窗口布局 }, }); if (props.layout != "1x1") { // 先清除所有画面 clearShiPing(); } }; // 销毁当前正在播放的所有画面 const clearShiPing = () => { AllData.oWebControl.JS_RequestInterface({ funcName: "stopAllPreview", }); AllData.videoParams.wndId = 0; }; // 初始化 const createdVideo = () => { initPlugin(() => {}); }; onMounted(() => { // 创建实例 initPlugin(); // 监听resize事件,使插件窗口尺寸跟随DIV窗口变化 window.addEventListener("resize", windowResize()); // // 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动 window.addEventListener("scroll", windowResize()); }); onBeforeUnmount(() => { if (AllData.oWebControl) { AllData.oWebControl.JS_HideWnd(); AllData.oWebControl .JS_DestroyWnd({ funcName: "destroyeWnd", }) .then(() => {}); } document.removeEventListener("resize", windowResize()); document.removeEventListener("scroll", windowScroll()); }); </script> <style lang="scss" scoped> #index { width: 100%; height: 100%; .playWnd { width: 100%; height: 100%; } } </style>