Vue3 中集成海康 H5 监控视频播放功能

🌈个人主页:前端青山
 🔥系列专栏:Vue篇
 🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来Vuet篇专栏内容:Vue-集成海康 H5 监控视频播放功能
目录
一、引言
二、环境搭建
三、代码解析
子组件部分
1. 导入模块和组件
2. 定义组件属性和事件
3. 初始化变量
4. 初始化视频插件
5. 控制分屏数量
6. 视频线路弹框按钮
7. 生命周期钩子
8. 初始化视频播放
9. 处理事件
10.调用插件播放
父组件调用
一、引言
随着视频监控技术的发展,许多应用场景需要集成实时视频监控功能。本文将详细介绍如何在 Vue 3 应用中集成海康 H5 监控视频播放功能,实现视频的实时播放、分屏显示以及全屏切换等功能。


二、环境搭建
为了确保代码能够正常运行,我们需要准备以下开发环境:
-  Vue 3:用于构建前端应用。 
-  Element Plus:用于 UI 组件库。 
-  海康 H5 SDK:用于播放视频流。 
三、代码解析
子组件部分
<template><div class="play_windows" v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.8)"><div class="tree-form"><el-treeref="tree":data="dataTree":props="defaultProps":highlight-current="true"@node-click="pitchOns"><template #default="{ node, data }"><span class="custom-tree-node">{{ data.name }}</span></template></el-tree></div><div class="video"><div class="dialog-slot-video-header-right"><el-button class="myButton" :class="{ 'active': videoIndex == 4 }" @click="videoTabClick(4)">1×1</el-button><el-button class="myButton" :class="{ 'active': videoIndex == 1 }" @click="videoTabClick(1)">3×3</el-button><el-button class="myButton" :class="{ 'active': videoIndex == 2 }" @click="videoTabClick(2)">4×4</el-button><el-button class="myButton" :class="{ 'active': videoIndex == 3 }" @click="videoTabClick(3)">整体全屏</el-button></div><div id='corpvideo'></div></div></div>
</template>-  功能说明 -  play_windows容器:包含两个主要部分,左侧为树形结构,右侧为视频播放区域。
-  el-tree组件:展示监控设备树形结构,点击节点触发pitchOns方法。
-  视频播放区域:通过按钮控制不同的分屏模式(1×1、3×3、4×4)及全屏模式。 
-  id='corpvideo':指定视频播放容器的 ID,供 H5 SDK 使用。
 
-  
1. 导入模块和组件
import { ref, onMounted, nextTick, defineProps, defineExpose, defineEmits, watch, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import { videoallList } from '@/api/screenVideo/index';
import { getGetByCode } from '@/api/videoSurveillance/index';-  功能说明:导入了 Vue 的一些核心函数,如 ref、onMounted、nextTick等,以及 Element Plus 的消息提示组件ElMessage和相关 API。
2. 定义组件属性和事件
const emit = defineEmits(["handleSpjkPOIClick"]);
const props = defineProps({playURL: String, // 视频 URLsplitNum: Number, // 分屏播放,默认最大分屏 4*4dataTree: Object, // 树形数据defaultProps: Object
});-  功能说明:定义了组件的属性 props和自定义事件emit,用于接收父组件传递的数据和触发事件。
3. 初始化变量
let dataTree = ref<any>(props.dataTree);
let defaultProps = ref<any>(props.defaultProps);
let loading = ref<Boolean>(false);
let myPlugin = ref<any>(null);
let index = ref<any>(1); // 多屏播放显示第几个
let mode = ref<any>(1); // 0 为低级播放,1 为高级播放
const urlList = ref<any>([]);
let playURLs = ref<any>("");
const jsPlugin = (window as any).JSPlugin;-  功能说明:定义了一些响应式变量,用于存储数据和状态,如 loading用于控制加载状态,myPlugin用于存储视频插件实例。
4. 初始化视频插件
const myPlugins = () => {myPlugin.value = new jsPlugin({szId: 'corpvideo', // 需要英文字母开头,唯一性,必填szBasePath: '/h5player', // 必填,与 h5player.min.js 的引用目录一致bSupporDoubleClickFull: true, // 是否支持双击全屏,默认 trueiMaxSplit: 4, // 分屏播放,默认最大分屏 4*4iCurrentSplit: splitNum.value,oStyle: {borderSelect: '#FFCC00',},openDebug: true,});
};-  功能说明:定义了一个方法 myPlugins,用于初始化视频插件实例,并配置相关参数。
5. 控制分屏数量
const tabPosition = ref<any>(1);
const playBackNum = (num: any) => {if (num == "3") {myPlugin.value.JS_FullScreenDisplay(true).then(() => { console.log(`wholeFullScreen success`) },(e: any) => { console.error(e) });return;}if (num == splitNum.value) {return;}splitNum.value = num;
};-  功能说明:定义了一个方法 playBackNum,用于控制分屏数量,并支持全屏显示。
6. 视频线路弹框按钮
const splitNum = ref<any>(1);
const videoIndex = ref<number>(4); // 视频信息弹框默认值 index
const videoTabClick = (type: number) => {videoIndex.value = Number(type);if (type == 1) {splitNum.value = 3;const totalWindows = splitNum.value * splitNum.value;for (let i = 0; i < totalWindows; i++) {const url = urlList.value[i] || urlList.value[0];myPlugin.value.JS_Play(url, { playURL: url, mode: mode.value }, i).then(() => console.log(`Playing in window ${i}`),(e: any) => console.error('Error playing video', e));}} else if (type == 2) {splitNum.value = 4;const totalWindows = splitNum.value * splitNum.value;for (let i = 0; i < totalWindows; i++) {const url = urlList.value[i] || urlList.value[0];myPlugin.value.JS_Play(url, { playURL: url, mode: mode.value }, i).then(() => console.log(`Playing in window ${i}`),(e: any) => console.error('Error playing video', e));}} else if (type == 3) {myPlugin.value.JS_FullScreenDisplay(true).then(() => { console.log(`wholeFullScreen success`) },(e: any) => { console.error(e) });return;} else if (type == 4) {splitNum.value = 1;}myPlugin.value.JS_ArrangeWindow(splitNum.value).then(() => { console.log(`arrangeWindow to ${splitNum.value}x${splitNum.value} success`) },(e: any) => { console.error(e) });console.log(splitNum.value, '监控视频的值');
};-  功能说明:定义了一个方法 videoTabClick,用于控制视频线路弹框按钮,并根据不同的类型调整分屏数量和播放视频。
7. 生命周期钩子
onMounted(() => {nextTick(() => {myPlugins();// 事件回调绑定myPlugin.value.JS_SetWindowControlCallback({windowEventSelect: function (iWndIndex: any) { // 插件选中窗口回调console.log('windowSelect callback: ', iWndIndex);},pluginErrorHandler: function (iWndIndex: any, iErrorCode: any, oError: any) { // 插件错误回调console.log('pluginError callback: ', iWndIndex, iErrorCode, oError);},windowEventOver: function (iWndIndex: any) { // 鼠标移过回调// console.log(iWndIndex);},windowEventOut: function (iWndIndex: any) { // 鼠标移出回调// console.log(iWndIndex);},windowEventUp: function (iWndIndex: any) { // 鼠标mouseup事件回调// console.log(iWndIndex);},windowFullCreenChange: function (bFull: any) { // 全屏切换回调console.log('fullScreen callback: ', bFull);},firstFrameDisplay: function (iWndIndex: any, iWidth: any, iHeight: any) { // 首帧显示回调console.log('firstFrame loaded callback: ', iWndIndex, iWidth, iHeight);},performanceLack: function () { // 性能不足回调console.log('performanceLack callback: ');}});});
});
onBeforeUnmount(() => {console.log('切换了');
});-  功能说明:在组件挂载时初始化视频插件,并绑定事件回调。在组件卸载前执行清理操作。 
8. 初始化视频播放
const initialize = (playURL: any, urls?: any[]) => {urlList.value = urls;playURLs.value = playURL;loading.value = true;index.value = myPlugin.value.currentWindowIndex;myPlugin.value.JS_Play(playURL, { playURL, mode: mode.value }, index.value).then(() => { loading.value = false }, // 成功操作(e: any) => { loading.value = false;ElMessage.error('监控视频异常'); // 失败操作});
};-  功能说明:定义了一个方法 initialize,用于初始化视频播放,并处理加载状态和错误提示。
9. 处理事件
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 中所有数据对象的字段 equipmentName 变成 nameres.data.rows = res.data.rows.map((child: any) => ({...child,name: child.equipmentName, // 将 equipmentName 字段复制到 name 字段// 删除原 equipmentName 字段}));res.data.rows.forEach((child: any) => {e.children.push(child);});// 展开当前节点(e as any).expanded = true;}})}
}10.调用插件播放
const videoUrl =(e:any)=>{let params = {equipmentCoding: e,};getGetByCode(params).then(res => {setTimeout(() => {initialize(res.data.url);}, 1);});
}// 使用 watch 监听 splitNum 的变化watch(splitNum, (newValue, oldValue) => {if (newValue !== oldValue) {myPlugins();myPlugin.value.JS_ArrangeWindow(splitNum.value).then(() => { console.log(`arrangeWindow to ${splitNum.value}x${splitNum.value} success`) },(e: any) => { console.error(e) })}
});
//最后暴露方法defineExpose({initialize,myPlugins})父组件调用
<template><div><ScreenMonitoring ref="screenmonitoring" :dataTree="dataTree" :defaultProps="defaultProps" @handleSpjkPOIClick="handleSpjkPOIClick" /></div>
</template><script setup>
import { ref, onMounted, nextTick } from 'vue';const dataTree = ref<any>([]);
const dataTree1 = ref<any>([]);
let screenmonitoring = ref();
const defaultProps = {children: 'children',label: 'name',
};onMounted(() => {nextTick(() => {let params = {};getTreeJson(params).then((res: any) => {let list = res.rows[0].children[9].children;list.forEach((item: any) => {extractNameAndRebuildTree(item);  // 对每个根节点执行递归提取});dataTree.value = list;  // 将处理后的列表赋值给 dataTree});});
});const extractNameAndRebuildTree = (node: any) => {// 如果节点有 self,提取 name 并放在最外层if (node.self && node.self.name) {node.name = node.self.name;}// 如果节点有 children,递归处理每个子节点if (node.children && node.children.length > 0) {node.children.forEach((child: any) => {extractNameAndRebuildTree(child);});}
};
const handleSpjkPOIClick = (poiId: string, coord: string) => {let params = {UnitIndexCode: poiId,};getGetByCodes(params).then((res: any) => {setTimeout(() => {screenmonitoring.value.initialize(res.data.urls[0], res.data.urls);}, 1);});
};
</script>-  初始化数据树: -  dataTree和dataTree1是两个响应式数组,用于存储处理后的数据。
-  screenmonitoring是一个引用,用于指向ScreenMonitoring子组件的实例。
-  defaultProps是传递给子组件的默认属性配置。
 
-  
-  组件挂载时: -  nextTick():等待 DOM 更新完成后再执行后续操作。
-  getTreeJson(params):从服务器获取数据,并处理返回的数据。
-  extractNameAndRebuildTree(item):递归处理每个节点,提取name并放在最外层。
 
-  
-  处理点击事件: -  handleSpjkPOIClick(poiId, coord):当点击某个 时,获取对应的视频 URL 并初始化视频播放。
-  getGetByCodes(params):从服务器获取视频 URL 数据。
-  setTimeout(() => { ... }, 1):延迟 1 毫秒后初始化视频播放。
 
-  
通过这种方式,父组件能够有效地初始化数据树,并在点击 树状 时触发视频播放。
本文旨在详细介绍如何在 Vue 3 应用中集成海康 H5 监控视频播放功能,实现视频的实时播放、分屏显示以及全屏切换等功能。
相关文章:
 
Vue3 中集成海康 H5 监控视频播放功能
🌈个人主页:前端青山 🔥系列专栏:Vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Vuet篇专栏内容:Vue-集成海康 H5 监控视频播放功能 目录 一、引言 二、环境搭建 三、代码解析 子组件部分 1.…...
Linux: eBPF: libbpf-bootstrap-master 编译
文章目录 简介编译运行展示输出展示:简介 这个是使用libbpf的一个例子; 编译 如果是一个可以联网的机器,这个libbpf-bootstrap的编译就方便了,完全是自动化的下载依赖文件;如果没有,就只能自己准备这些个软件。 需要:libbpf-static; [root@RH8-LCP c]# makeLIB …...
 
1.1.4 计算机网络的分类
按分布范围分类: 广域网(wan) 城域网(man) 局域网(lan) 个域网(pan) 注意:如今局域网几乎采用“以太网技术实现”,因此“以太网”几乎成了“局域…...
 
周家庄智慧旅游小程序
项目概述 周家庄智慧旅游小程序将通过数字化手段提升游客的旅游体验,依托周家庄的自然与文化资源,打造智慧旅游新模式。该小程序将结合虚拟现实(VR)、增强现实(AR)和人工智能等技术,提供丰富的…...
 
【在Linux世界中追寻伟大的One Piece】命名管道
目录 1 -> 命名管道 1.1 -> 创建一个命名管道 1.2 -> 匿名管道与命名管道的区别 1.3 -> 命名管道的打开规则 1.4 -> 例子 1 -> 命名管道 管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据&…...
 
如意控物联网项目-ML307R模组软件及硬件调试环境搭建
软件及硬件调试环境搭建 1、 软件环境搭建及编译 a) 打开官方SDK,内涵APP-DEMO,通过vscode打开程序, 软件程序编写及编译参考下边说明文档链接 OneMO线上服务平台 编译需预安装python3.7以上版本,安装完python后,打开…...
 
大模型分布式训练并行技术(九)-总结
近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&a…...
uniapp view设置当前view之外的点击事件
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
 
【Mybatis篇】动态SQL的详细带练
🧸安清h:个人主页 🎥个人专栏:【计算机网络】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 文章目录 🎯一.动态SQL简单介绍 🚦动态S…...
【MyBatis-Plus】 学习记录 常用功能及代码生成器使用
文章目录 1. 环境准备2. 创建基础实体类3. 编写 Mapper 接口4. Service 层5. 控制器层6. 分页功能7. 条件构造器8. 配置乐观锁9. 常见问题10. 代码生成器1. 创建数据库表2. 引入依赖3. 配置数据库连接4. 编写代码生成器5. 运行代码生成器6. 查看生成的代码 MyBatis-Plus 是一个…...
HalconDotNet实现OCR详解
文章目录 一、基于字符分割的 OCR二、基于模板匹配的 OCR三、基于深度学习的 OCR四、基于特征提取的 OCR五、基于区域建议的 OCR 一、基于字符分割的 OCR 字符分割是 OCR 中的一个重要步骤。首先,对包含文本的图像进行预处理,如去噪、二值化等操作&#…...
手搓一个Agent#Datawhale 组队学习Task3
书接上回,首先回顾一下Task2的一些补充: Task2主要任务是从零预训练一个tiny-llama模型,熟悉一下Llama的模型架构和流程。然后测试一下模型的效果。总的来说,因为某些未知的原因,loss一直没有降下去,导致最…...
 
基于SpringBoot+Vue+MySQL的在线酷听音乐系统
系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展,网络已成为人们日常生活中不可或缺的一部分。在线音乐服务因其便捷性和丰富性,逐渐成为用户获取音乐内容的主要渠道。然而,传统的音乐播放平台往往存在歌曲资源有限…...
 
大数据实时数仓Hologres(一):Hologres 简单介绍
文章目录 Hologres 简单介绍 一、什么是实时数仓 Hologres 二、产品优势 1、专注实时场景 2、亚秒级交互式分析 3、统一数据服务出口 4、开放生态 5、MaxCompute查询加速 6、计算存储分离架构 三、应用场景 搭建实时数仓 四、产品架构 1、Shared Disk/Storage &am…...
 
【鸿蒙HarmonyOS NEXT】数据存储之分布式键值数据库
【鸿蒙HarmonyOS NEXT】数据存储之分布式键值数据库 一、环境说明二、分布式键值数据库介绍三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本: API版本:以12为主 二、分布式键值数据库介绍 KVStore简介: 分布式键值数据库…...
 
基于springboot+小程序的儿童预防接种预约管理系统(疫苗1)(源码+sql脚本+视频导入教程+文档)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 本儿童预防接种预约微信小程序可以实现管理员和用户。 1、管理员功能有个人中心,用户管理,儿童信息管理,疫苗信息管理,儿童接种管理&#x…...
计算物理精解【8】-计算原理精解【5】
文章目录 logistic模型多元回归分析多元回归分析概览1. 多元回归的概念与重要性2. 多元回归在实际应用中的例子3. 多元回归在预测和解释数据中的优势和局限性4. 多元回归的优缺点及改进建议 多元线性回归分析详解一、原理二、性质三、计算四、例子与例题五、应用场景六、优缺点…...
【Linux】 tcp | 解除服务器对tcp连接的限制 | 物联网项目配置
一、修改tcp连接限制 1、编辑 vi /etc/sysctl.conf 2、内容 net.ipv4.tcp_keepalive_intvl 75 net.ipv4.tcp_keepalive_probes 9 net.ipv4.tcp_keepalive_time 7200 net.ipv4.ip_local_port_range 1024 65535 net.ipv4.ip_conntrack_max 20000 net.ipv4.tcp_max_tw_bucket…...
 
如何隐藏Windows10「安全删除硬件」里的USB无线网卡
本方法参照了原文《如何隐藏Windows10「安全删除硬件」里的USB无线网卡》里面的方法,但是文章中的描述我的实际情况不太一样,于是我针对自己的实际情况进行了调整,经过测试可以成功隐藏Windows10「安全删除硬件」里的USB无线网卡。 先说一下…...
【QT Quick】基础语法:导入外部JS文件及调试
在 QML 中,可以使用 JavaScript 来实现业务逻辑的灵活性和简化开发。接下来我们会学习如何导入 JavaScript 文件,并在 QML 中使用它,同时也会介绍如何调试这些 JavaScript 代码。 导入 JavaScript 文件 在 QML 中导入 JavaScript 文件的方式…...
 
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
 
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
 
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
 
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
 
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
