共计 8727 个字符,预计需要花费 22 分钟才能阅读完成。
🌈个人主页:前端青山
🔥系列专栏:组件封装篇
🔖 人终将被年少不可得之物困其一生
依旧 青山, 本期给大家带来组件封装篇专栏内容:Vue 3 集成海康 Web 插件实现视频监控
引言
最近在项目中使用了 Vue 3 结合海康 Web 插件来实现视频监控功能,过程中遇到了一些挑战和解决方案。为了帮助开发小伙伴们更好地理解和应用这一技术栈,特此分享一下我们的经验和代码实现。
目录
项目背景
准备工作
1. 官网下载
2. 安装插件
3. 插件 js 文件引入 vue 项目
子组件结构
1. 模板部分
2. 脚本部分
2.1 导入依赖
2.2 定义属性和事件
2.3 定义变量
2.4 RSA 加密
2.5 初始化插件
2.6 获取公钥
2.7 初始化视频播放
2.8 播放视频
2.9 隐藏和显示窗口
2.10 监听窗口关闭和调整大小
2.11 处理节点点击事件
2.12 暴露方法
3. 样式部分
父组件调用
1. 模板部分
2. 脚本部分
3. 样式部分
项目背景
在当前的项目中,我们需要实现一个视频监控系统,能够展示多个监控点的实时视频流,并支持用户通过树形结构选择不同的监控点。为了实现这一需求,我们选择了 Vue 3 作为前端框架,并集成了海康 Web 插件来处理视频流的播放和管理。
准备工作
1. 官网下载
在官网海康开放平台下载视频 web 插件
2. 安装插件
3. 插件 js 文件引入 vue 项目
将这 3 个 js 文件引入 vue 项目中的 public
文件夹下新建文件夹放入
然后在 index.html
文件中根路径引入配置文件
前端青山
最后我们开始构建本次所需要调用的 组件封装
功能
子组件结构
1. 模板部分
{{data.name}}
-
: 主容器,包含视频树形结构和视频播放区域。
: Element Plus 的树形组件,用于展示视频监控点的层级结构。: 视频播放区域,包含一个id
为corpvideo
的div
,用于嵌入海康 Web 插件。2. 脚本部分
2.1 导入依赖
-
ref
: Vue 3 的响应式变量。 -
onMounted
: 生命周期钩子,组件挂载后执行。 -
nextTick
: 在 DOM 更新后执行。 -
defineProps
: 定义组件接收的属性。 -
defineEmits
: 定义组件触发的事件。 -
watch
: 监听数据变化。 -
onBeforeUnmount
: 组件卸载前执行。
2.2 定义属性和事件
const emit = defineEmits(["handleSpjkPOIClick"]); const props = defineProps({ playURL: String, // 视频 url splitNum: Number, // 分屏播放,默认最大分屏 4 *4 dataTree: Object, // 树 数据 defaultProps: Object });
2.3 定义变量
let dataTree = ref
(props.dataTree); let defaultProps = ref (props.defaultProps); let loading = ref (false); const corpvideo = ref (); const videosp = ref (null); let width: any = 0; let height: any = 0; let oWebControl: any = null; let initCount: any = 0; let pubKey: any = ''; -
dataTree
: 树形结构的数据。 -
defaultProps
: 树形组件的默认属性。 -
loading
: 加载状态。 -
corpvideo
: 视频播放容器的引用。 -
videosp
: 视频播放区域的引用。 -
width
和height
: 视频播放区域的宽度和高度。 -
oWebControl
: 海康 Web 插件的实例。 -
initCount
: 初始化计数器。 -
pubKey
: RSA 公钥。
2.4 RSA 加密
const setEncrypt = (value: any) => {let encrypt = new JSEncrypt(); encrypt.setPublicKey(pubKey); return encrypt.encrypt(value); }
2.5 初始化插件
const initPlugin = () => {nextTick(() => { width = videosp.value.offsetWidth; height = videosp.value.offsetHeight; oWebControl = new webControl({ szPluginContainer: "corpvideo", iServicePortStart: 15900, iServicePortEnd: 15900, szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", cbConnectSuccess: function () { oWebControl.JS_StartService("window", {dllPath: "./VideoPluginConnect.dll"}).then(function () {oWebControl.JS_CreateWnd("corpvideo", width, height).then(function () {init(); }); }, function () {}); }, cbConnectError: function () { oWebControl = null; webControl.JS_WakeUp("VideoWebPlugin://"); initCount++; if (initCount
-
initPlugin
: 创建海康 Web 插件实例,并设置连接成功、连接失败和连接关闭的回调函数。 -
cbConnectSuccess
: 连接成功后启动服务并创建视频播放窗口。 -
cbConnectError
: 连接失败后尝试重新连接。 -
cbConnectClose
: 连接关闭后尝试重新连接。
2.6 获取公钥
const getPubKey = (callback: any) => { oWebControl.JS_RequestInterface({ funcName: "funcName", argument: JSON.stringify({keyLength: 1024}) }).then((oData: any) => {if (oData.responseMsg.data) { pubKey = oData.responseMsg.data; callback();} }); }
2.7 初始化视频播放
const init = () => {getPubKey(() => { appkey = "appkey"; secret = setEncrypt("secret"); ip = "ip"; playMode = 0; port = 443; snapDir = "D:SnapDir"; videoDir = "D:VideoDir"; layout = "1x1"; enableHTTPS = 1; encryptedFields = 'secret'; showToolbar = 1; showSmart = 1; buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; oWebControl.JS_RequestInterface({ funcName: "init", argument: JSON.stringify({ appkey: appkey, secret: secret, ip: ip, playMode: playMode, port: port, snapDir: snapDir, videoDir: videoDir, layout: layout, enableHTTPS: enableHTTPS, encryptedFields: encryptedFields, showToolbar: showToolbar, showSmart: showSmart, buttonIDs: buttonIDs }) }).then((oData: any) => {oWebControl.JS_Resize(width, height); }); }); }
2.8 播放视频
const JSRequestInterface = (code: any) => {cameraIndexCode = code.replace(/(^s*)/g, "").replace(/(s*$)/g,""); oWebControl.JS_RequestInterface({ funcName: "startPreview", argument: JSON.stringify({ cameraIndexCode: cameraIndexCode, streamMode: streamMode, transMode: transMode, gpuMode: gpuMode, wndId: wndId }) }); }
2.9 隐藏和显示窗口
const JSHideWnd = () => {oWebControl.JS_HideWnd(); oWebControl.JS_DestroyWnd().then(function () {}, function () {}); } const JSShowWnd = () => {initPlugin(); oWebControl.JS_ShowWnd();}
2.10 监听窗口关闭和调整大小
window.addEventListener('unload', JSHideWnd); const getElementPosition = () => { width = window.innerWidth * 0.3; height = window.innerHeight * 0.56; oWebControl.JS_Resize(width, height); }; window.addEventListener('resize', getElementPosition);
-
window.addEventListener('unload', JSHideWnd)
: 监听窗口关闭事件,隐藏并销毁视频播放窗口。 -
getElementPosition
: 获取窗口大小并调整视频播放窗口的尺寸。 -
window.addEventListener('resize', getElementPosition)
: 监听窗口调整大小事件,动态调整视频播放窗口的尺寸。
2.11 处理节点点击事件
const pitchOns = (e: any) => {if (!e || !e.self) {if (e.equipmentCoding) {handleAddChild(e); } return; } if (e.children) {emit("handleSpjkPOIClick", e.self.indexCode, ''); return; } else {handleAddChild(e); } } const handleAddChild = (e: any) => {if (!e || !e.self) {if (e.equipmentCoding) {videoUrl(e.equipmentCoding); } return; } if (e.self.indexCode) { let params = {UnitIndexCode: e.self.indexCode,}; videoallList(params).then((res: any) => {if (res.data.rows.length == 0) {emit("handleSpjkPOIClick", e.self.indexCode, ''); } else {e.children = e.children || []; res.data.rows = res.data.rows.map((child: any) => ({ ...child, name: child.equipmentName, })); res.data.rows.forEach((child: any) => {e.children.push(child); }); (e as any).expanded = true; } }); } } const videoUrl = (equipmentCoding: string) => { let params = {equipmentCoding: equipmentCoding,}; JSRequestInterface(equipmentCoding) }
-
pitchOns
: 处理树形节点点击事件,根据节点类型调用相应的方法。 -
handleAddChild
: 处理节点的子节点加载,请求子节点数据并展开节点。 -
videoUrl
: 请求指定监控点的视频 URL 并播放视频。
2.12 暴露方法
defineExpose({ initPlugin, JSHideWnd, JSShowWnd, JSRequestInterface })
3. 样式部分
子组件
ScreenMonitoring
主要实现了监控点的树形结构展示和视频播放控制。通过el-tree
组件展示监控点的树形结构,并在节点被点击时调用视频播放插件的初始化和播放方法。子组件提供了JSRequestInterface
方法请求视频流,initialize
方法初始化视频播放,以及JSHideWnd
方法停止视频播放,确保视频监控功能的完整性和可控性。父组件调用
1. 模板部分
-
: 这是一个自定义的对话框组件,用于显示视频监控内容。通过v-model
绑定dialogVideo
变量来控制对话框的显示和隐藏。 -
@close="onCloseDialog"
: 当对话框关闭时,调用onCloseDialog
方法。 -
@open="onOpenDialog"
: 当对话框打开时,调用onOpenDialog
方法。 -
: 包含
ScreenMonitoring
子组件的容器,设置高度为60vh
,并使用v-if
指令确保只有在dialogVideo
为true
时才渲染。
: 子组件,用于显示视频监控内容。通过ref
绑定screenmonitoring
变量,以便在父组件中调用子组件的方法。传递dataTree
和defaultProps
属性,并监听handleSpjkPOIClick
事件。2. 脚本部分
-
dialogVideo
: 一个响应式变量,用于控制对话框的显示和隐藏。 -
dataTree
: 树形结构的数据,用于传递给ScreenMonitoring
子组件。 -
defaultProps
: 树形组件的默认属性,用于传递给ScreenMonitoring
子组件。 -
screenmonitoring
: 一个响应式变量,用于存储ScreenMonitoring
子组件的实例,以便在父组件中调用其方法。 -
handleSpjkPOIClick
: 处理监控点点击事件的方法。当用户点击某个监控点时,会调用子组件的JSRequestInterface
方法,并传递poiId
参数。注释掉的部分是获取视频 URL 的逻辑,可以根据实际需求启用。 -
onCloseDialog
: 当对话框关闭时调用的方法。调用子组件的JSHideWnd
方法,停止视频播放。 -
onOpenDialog
: 当对话框打开时调用的方法。调用子组件的initPlugin
方法,初始化视频播放。
3. 样式部分
通过上述代码,我们在父组件中实现了视频监控对话框的显示和隐藏,并在对话框打开和关闭时调用子组件的相应方法,以控制视频的播放和停止。
本文详细介绍了如何使用 Vue 3 框架集成海康 Web 插件实现视频监控功能。通过定义属性、事件、变量,以及编写初始化、播放视频、处理节点点击事件等方法,我们成功实现了视频监控系统的前端部分。同时,通过样式部分的定制,确保了良好的用户体验。希望本文对读者在开发类似项目时有所帮助。
原文地址: Vue 3 集成海康 Web 插件实现视频监控