<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; 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 => { console.log(res, '插件版本号'); if (res.responseMsg.code === 0 && res.responseMsg.data === 'V1.5.2') { //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>