You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
8.5 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div id="camera-box" class="camera-box">
<!-- 视口区域 -->
<div :id="'playWnd'" class="playWnd"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, watch, defineProps, defineExpose, ref, computed } from 'vue';
import { JSEncrypt } from 'jsencrypt';
const props = defineProps(['serialNumberValue', 'width', 'height']);
//声明公用变量
let initCount = 0;
let pubKey = '';
let oWebControl: any = null;
// 创建播放实例
const initPlugin = () => {
oWebControl = new window.WebControl({
szPluginContainer: 'playWnd', // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
// 创建WebControl实例成功后的回调函数
oWebControl
.JS_StartService('window', {
// WebControl实例创建成功后需要启动VideoPluginPlugin.exe服务
dllPath: './VideoPluginConnect.dll', // 值"./VideoPluginConnect.dll"写死
})
.then(
function () {
// 启动插件服务成功
oWebControl.JS_SetWindowControlCallback({
// 设置消息回调
cbIntegrationCallBack: cbIntegrationCallBack,
});
// 实际宽高
let width = props.width;
let height = props.height;
const divElement = document.getElementById('camera-box');
if (divElement) {
const rect = divElement.getBoundingClientRect();
const rectWidth = rect.width;
const rectHeight = rect.height;
if (rectWidth < width) {
width = rectWidth;
}
if (rectHeight < height) {
height = rectHeight;
}
}
oWebControl.JS_CreateWnd('playWnd', width, height).then(function () {
init(); // 创建播放实例成功后初始化
});
},
function () {
// 创建播放实例失败回调
console.log('创建播放实例失败!!!');
},
);
},
cbConnectError: function () {
// 创建WebControl实例失败
oWebControl = null;
let d = document.getElementById('playWnd');
if (d) {
d.innerHTML = '插件未启动,正在尝试启动,请稍候...';
}
window.WebControl.JS_WakeUp('VideoWebPlugin://'); // 程序未启动时执行error函数采用wakeup来启动程序
initCount++;
if (initCount < 3) {
setTimeout(function () {
initPlugin();
}, 3000);
} else {
let d = document.getElementById('playWnd');
if (d) {
d.innerHTML = '插件启动失败,请检查插件是否安装!';
}
}
},
cbConnectClose: function (bNormalClose) {
// 异常断开bNormalClose = false
// JS_Disconnect正常断开bNormalClose = true
oWebControl = null;
},
});
};
// 初始化播放内容
function init() {
getPubKey(function () {
let appkey = '23604396'; //综合安防管理平台提供的appkey必填
let ip = '221.2.83.54'; //综合安防管理平台IP地址必填
let port = 1443;
let appSecret = 'NZJ8L3bxCOOV6rtTFjsx';
let secret = setEncrypt(appSecret); //综合安防管理平台提供的secret必填
let layerOut = '1x1';
let playMode = 0; //初始播放模式0-预览1-回放
let snapDir = 'D:\\SnapDir'; //抓图存储路径
let videoDir = 'D:\\VideoDir'; //紧急录像或录像剪辑存储路径
let layout = layerOut; //playMode指定模式的布局 默认1*1
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互这里总是填1
let encryptedFields = 'secret'; //加密字段默认加密领域为secret
let showToolbar = 1; //是否显示工具栏0-不显示非0-显示
let showSmart = 1; //是否显示智能信息如配置移动侦测后画面上的线框0-不显示非0-显示
let buttonIDs = ''; //自定义工具条按钮
oWebControl
.JS_RequestInterface({
funcName: 'init',
argument: JSON.stringify({
appkey: appkey, //API网关提供的appkey
secret: secret, //API网关提供的secret
ip: ip, //API网关IP地址
playMode: playMode, //播放模式(决定显示预览还是回放界面)
port: port, //端口
snapDir: snapDir, //抓图存储路径
videoDir: videoDir, //紧急录像或录像剪辑存储路径
layout: layout, //布局
enableHTTPS: enableHTTPS, //是否启用HTTPS协议
encryptedFields: encryptedFields, //加密字段
showToolbar: showToolbar, //是否显示工具栏
showSmart: showSmart, //是否显示智能信息
buttonIDs: buttonIDs, //自定义工具条按钮
}),
})
.then(function (oData) {
// 重定大小
reSizeVideo();
});
// 开始预览多个视频
oWebControl.JS_RequestInterface({
funcName: 'startPreview',
argument: {
cameraIndexCode: props.serialNumberValue,
streamMode: 0,
transMode: 1,
gpuMode: 0,
wndId: 1,
},
});
});
}
// 标签关闭
function closeHkVideo() {
if (oWebControl != null) {
// 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_HideWnd();
// 销毁当前播放的视频
oWebControl.JS_RequestInterface({ funcName: 'destroyWnd' });
// 断开与插件服务连接
oWebControl.JS_Disconnect();
}
}
// 重定大小
function reSizeVideo() {
// 实际宽高
let width = props.width;
let height = props.height;
const divElement = document.getElementById('camera-box');
if (divElement) {
const rect = divElement.getBoundingClientRect();
const rectWidth = rect.width;
const rectHeight = rect.height;
if (rectWidth < width) {
width = rectWidth;
}
if (rectHeight < height) {
height = rectHeight;
}
}
oWebControl.JS_Resize(width, height); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
}
watch(
() => props.serialNumberValue,
() => {
init();
},
);
// 获取公钥
function getPubKey(callback) {
oWebControl
.JS_RequestInterface({
funcName: 'getRSAPubKey',
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then(function (oData) {
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback();
}
});
}
// RSA加密
function setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 推送消息
function cbIntegrationCallBack(oData) {
// showCBInfo(JSON.stringify(oData.responseMsg));
}
onMounted(() => {
// 启动视频窗口
initPlugin();
// 添加监听滚动事件
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
if (elements.length > 0) {
// 遍历每个元素并绑定 scroll 事件
elements.forEach((element) => {
element.addEventListener('scroll', reSizeVideo);
});
}
});
onUnmounted(() => {
// 销毁视频窗口
closeHkVideo();
// 移除监听滚动事件
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
if (elements.length > 0) {
// 遍历每个元素并绑定 scroll 事件
elements.forEach((element) => {
element.removeEventListener('scroll', reSizeVideo);
});
}
});
defineExpose({
initPlugin,
init,
closeHkVideo,
});
</script>
<style scoped>
.camera-box {
width: v-bind('`${props.width}px`');
height: v-bind('`${props.height}px`');
border-radius: 5px;
position: relative;
z-index: 10 !important;
position: fixed;
left: 50%;
top: 50%;
z-index: 10;
transform: translate(-62%, -51%);
padding: 0px;
}
.playWnd {
width: v-bind('`${props.width}px`');
height: v-bind('`${props.height}px`');
}
</style>