场景
若依前后端分离版手把手教你本地搭建环境并运行项目:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662
SpringBoot+Vue+Openlayers实现地图上新增和编辑坐标并保存提交:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121150132
在上面实现的基础上,对接海康威视摄像头实现摄像头预览效果。
该型号只支持IE模式取流。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、去官网-硬件产品-WEB开发包下载官方示例代码。
由于这里的设备不支持websocket取流,所以下载下面的3.0的开发包。
2、按照上面博客中建表与生成前后端代码,进而实现对摄像头参数的管理。
实现预览的主要参数包括Ip、端口号、登录名、登录密码。其他的都是额外加的参数。
3、勾选摄像头进行预览,限制最多选择四个,否则浏览器会卡顿。
<el-table v-loading="loading" :data="videoList" @selection-change="handleSelectionChange" >
多选事件处理
// 多选框选中数据 handleSelectionChange(selection) { this.openVideoData = []; this.openVideoData = selection; this.ids = selection.map((item) => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; },
需要提前声明变量
data() { return { // 遮罩层 loading: false, // 选中数组 ids: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true,
4、点击预览按钮实现跳转到预览的新标签页
<el-button type="success" plain icon="el-icon-setting" size="mini" :disabled="multiple" @click="videoChange" >预览</el-button >
预览按钮的点击事件
// 查看摄像 videoChange() { let routeUrl = this.$router.resolve({ path: "/carVideo", query: { videoData: JSON.stringify(this.openVideoData), }, }); if (this.openVideoData.length > 4) { this.$notify({ title: "失败", message: "最多支持预览选择4个摄像头", type: "error", }); } else { window.open(routeUrl.href, "_blank"); } },
首先校验最多选择四个,然后跳转到新的预览页面/carVideo。
首先配置路由,打开src/router下的index.js,添加路由
{ path: '/carVideo', component: Layout, component: (resolve) => require(['@/views/system/cameramap/component/video'], resolve), meta: {title: '摄像头'}, hidden: true, },
然后跳转路由时携带了要进行预览的摄像头参数this.openVideoData
5、预览页面video.vue引入官网的webVideoCtrl.js文件
首先该页面中需要引入官网的webVideoCtrl.js文件,在根目录下新建static目录,将js文件放在该目录下
引入
import { WebVideoCtrl } from "/static/webVideoCtrl.js";
6、video.vue判断当前是否为IE/兼容模式
data中获取请求代理
ua: navigator.userAgent.toLocaleLowerCase(),
created方法中进行判断并提示
created() { if (this.ua.match(/msie/) != null || this.ua.match(/trident/) != null) { this.browserType = "IE"; this.videoData = JSON.parse(this.$route.query.videoData); if (this.videoData.length <= 1) { this.iWndowType = 1; } else if (this.videoData.length > 1 && this.videoData.length <= 4) { this.iWndowType = 2; } } else { this.$notify({ title: "失败", message: "请在ie模式下查看摄像头", type: "error", }); } },
7、初始化预览页面
在mounted中执行初始化界面的操作
mounted() { this.videoChange(); },
在方法中
videoChange() { setTimeout(() => { this.videoInitPlugin(); // 初始化video界面 }, 300); },
调用videoInitPlugin中校验是否已经安装插件,插件位置为开发包中exe文件
校验是否已经安装插件的方法
videoInitPlugin() { this.$nextTick(() => { var iRet = WebVideoCtrl.I_CheckPluginInstall(); if (iRet === -1) { // alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装"); this.myFunction(); return; } this.initPlugin(); }); }, myFunction() { var r = confirm("您还未安装过插件,请下载后查看摄像!"); if (r == true) { window.location.href = "/WebComponentsKit.exe"; } else { } },
如果没有安装插件会进行提示并且确定后进行下载,所以将WebComponentsKit.exe
放在代码中public目录下
如果已经安装插件则执行官方js中初始化插件的方法
initPlugin() { WebVideoCtrl.I_InitPlugin("100%", "100%", { bWndFull: true, //是否支持单窗口双击全屏,默I_CheckPluginInstall iWndowType: this.iWndowType, //默认展示几个摄像头1x1 2x2 cbInitPluginComplete: function () { WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin"); // 检查插件是否最新 if (WebVideoCtrl.I_CheckPluginVersion() === -1) { return; } }, }); for (var i = 0; i < this.videoData.length; i++) { this.hkvInfo = this.videoData[i]; this.index = i; this.onLogin(); } },
然后是遍历选择的所有摄像头进行登录操作。
8、摄像头登录
// 登录 async onLogin() { var that = this; that.loginLoading = true; // 登录设备 WebVideoCtrl.I_Login( that.hkvInfo.ip, that.iProtocol, that.hkvInfo.port, that.hkvInfo.username, that.hkvInfo.password, { async: false, success: (xmlDoc) => { //TODO 获取通道信息 that.getChannelInfo(); that.getDevicePort(that.hkvInfo.ip + "_" + that.hkvInfo.port); that.loginLoading = false; this.clickStartRealPlay(); }, error: function () { that.loginLoading = false; that.$message({ showClose: true, message: "登录失败", type: "error", }); }, } ); },
9、登录成功后调用预览
在登录成功后直接调用预览方法
clickStartRealPlay() { console.log("开始预览", this.index); // 开始预览 var that = this; that.startPlayLoading = true; var szDeviceIdentify = that.hkvInfo.ip + "_" + that.hkvInfo.port; that.startRealPlay(szDeviceIdentify, this.index, that.hkvInfo.channels[0]); that.startPlayLoading = false; }, startRealPlay(szDeviceIdentify, iWndIndex, iChannelID) { var that = this; WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iRtspPort: that.iRtspPort, iWndIndex: iWndIndex, iChannelID: iChannelID, bZeroChannel: that.bZeroChannel, success: function () { // that.$notify({ // title: "成功", // message: "开始预览通道" + iChannelID + "成功", // type: "success", // }); }, error(status, xmlDoc2) { console.log(xmlDoc2); //不能删除 // that.$notify({ // title: "失败", // message: "开始预览通道" + iChannelID + "失败", // type: "error", // }); if (status === 403) { console.log("szInfo 设备不支持Websocket取流!"); } else { console.log("开始预览失败 ", status, xmlDoc2); } }, }); },
10、在页面销毁关闭时停止预览并退出登录
destroyed() { this.clickStopRealPlay(); this.onLogout(); },
停止预览
clickStopRealPlay: function () { for (var i = 0; i < = this.index; i++) { setTimeout(this.stopRealPlay(i), 1000); } }, stopRealPlay: function (iWndIndex) { var that = this; WebVideoCtrl.I_Stop({ iWndIndex: iWndIndex, success: function () { // that.$notify({ // title: "成功", // message: "停止预览窗口" + iWndIndex + "成功", // type: "success", // }); }, error: function () { // that.$notify({ // title: "失败", // message: "停止预览窗口" + iWndIndex + "失败", // type: "error", // }); }, }); },
退出登录
// 退出 onLogout() { this.videoData.forEach((element) => { var szDeviceIdentify = element.ip + "_" + element.port; var iRet = WebVideoCtrl.I_Logout(szDeviceIdentify); if (0 == iRet) { // this.$message({ // showClose: true, // message: "退出成功", // type: "success", // }); } else { // this.$message({ // showClose: true, // message: "退出失败", // type: "error", // }); } }); },
11、完整video.vue示例代码
<template> <div class="video_box"> <!-- 摄像头 --> <div id="divPlugin" class="plugin"></div> </div> </template> <script> import { WebVideoCtrl } from "/static/webVideoCtrl.js"; export default { name: "OpUser", components: {}, data() { return { szInfo: "", rowList: {}, hkvInfo: {}, mySelectWnd: 0, //当前选中的窗口 g_bPTZAuto: false, iProtocol: 1, loginLoading: false, startPlayLoading: false, bZeroChannel: false, iRtspPort: 0, index: 0, iWndowType: null, videoData: [], ua: navigator.userAgent.toLocaleLowerCase(), }; }, created() { if (this.ua.match(/msie/) != null || this.ua.match(/trident/) != null) { this.browserType = "IE"; this.videoData = JSON.parse(this.$route.query.videoData); if (this.videoData.length <= 1) { this.iWndowType = 1; } else if (this.videoData.length > 1 && this.videoData.length <= 4) { this.iWndowType = 2; } } else { this.$notify({ title: "失败", message: "请在ie模式下查看摄像头", type: "error", }); } }, mounted() { this.videoChange(); }, destroyed() { this.clickStopRealPlay(); this.onLogout(); }, methods: { getList() {}, videoChange() { setTimeout(() => { this.videoInitPlugin(); // 初始化video界面 }, 300); }, handleSelectionChange() {}, submitForm() {}, cancel() {}, // 登录 async onLogin() { var that = this; that.loginLoading = true; // 登录设备 WebVideoCtrl.I_Login( that.hkvInfo.ip, that.iProtocol, that.hkvInfo.port, that.hkvInfo.username, that.hkvInfo.password, { async: false, success: (xmlDoc) => { //TODO 获取通道信息 that.getChannelInfo(); that.getDevicePort(that.hkvInfo.ip + "_" + that.hkvInfo.port); that.loginLoading = false; this.clickStartRealPlay(); }, error: function () { that.loginLoading = false; that.$message({ showClose: true, message: "登录失败", type: "error", }); }, } ); }, // 退出 onLogout() { this.videoData.forEach((element) => { var szDeviceIdentify = element.ip + "_" + element.port; var iRet = WebVideoCtrl.I_Logout(szDeviceIdentify); if (0 == iRet) { // this.$message({ // showClose: true, // message: "退出成功", // type: "success", // }); } else { // this.$message({ // showClose: true, // message: "退出失败", // type: "error", // }); } }); }, clickStartRealPlay() { console.log("开始预览", this.index); // 开始预览 var that = this; that.startPlayLoading = true; var szDeviceIdentify = that.hkvInfo.ip + "_" + that.hkvInfo.port; that.startRealPlay(szDeviceIdentify, this.index, that.hkvInfo.channels[0]); that.startPlayLoading = false; }, startRealPlay(szDeviceIdentify, iWndIndex, iChannelID) { var that = this; WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iRtspPort: that.iRtspPort, iWndIndex: iWndIndex, iChannelID: iChannelID, bZeroChannel: that.bZeroChannel, success: function () { // that.$notify({ // title: "成功", // message: "开始预览通道" + iChannelID + "成功", // type: "success", // }); }, error(status, xmlDoc2) { console.log(xmlDoc2); //不能删除 // that.$notify({ // title: "失败", // message: "开始预览通道" + iChannelID + "失败", // type: "error", // }); if (status === 403) { console.log("szInfo 设备不支持Websocket取流!"); } else { console.log("开始预览失败 ", status, xmlDoc2); } }, }); }, videoInitPlugin() { this.$nextTick(() => { var iRet = WebVideoCtrl.I_CheckPluginInstall(); if (iRet === -1) { // alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装"); this.myFunction(); return; } this.initPlugin(); }); }, myFunction() { var r = confirm("您还未安装过插件,请下载后查看摄像!"); if (r == true) { window.location.href = "/WebComponentsKit.exe"; } else { } }, initPlugin() { WebVideoCtrl.I_InitPlugin("100%", "100%", { bWndFull: true, //是否支持单窗口双击全屏,默I_CheckPluginInstall iWndowType: this.iWndowType, //默认展示几个摄像头1x1 2x2 cbInitPluginComplete: function () { WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin"); // 检查插件是否最新 if (WebVideoCtrl.I_CheckPluginVersion() === -1) { return; } }, }); for (var i = 0; i < this.videoData.length; i++) { this.hkvInfo = this.videoData[i]; this.index = i; this.onLogin(); } }, getDevicePort(szDeviceIdentify) { var oPort = WebVideoCtrl.I_GetDevicePort(szDeviceIdentify); this.iRtspPort = oPort.iRtspPort; }, clickStopRealPlay: function () { for (var i = 0; i <= this.index; i++) { setTimeout(this.stopRealPlay(i), 1000); } }, stopRealPlay: function (iWndIndex) { var that = this; WebVideoCtrl.I_Stop({ iWndIndex: iWndIndex, success: function () { // that.$notify({ // title: "成功", // message: "停止预览窗口" + iWndIndex + "成功", // type: "success", // }); }, error: function () { // that.$notify({ // title: "失败", // message: "停止预览窗口" + iWndIndex + "失败", // type: "error", // }); }, }); }, // 获取通道,实际上可以根据自己的项目,获取数字通道,模拟通道,零通道中的一个或多个,不用全部获取(提高效率) getChannelInfo: function () { var that = this; var szDeviceIdentify = this.hkvInfo.ip + ":" + this.hkvInfo.port; // 数字通道 that.hkvInfo.channels = []; WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, { async: false, mysuccess: function (xmlStr) { console.log("mysuccess I_GetDigitalChannelInfo: ", xmlStr); var jsonObj = that.$x2js.xml2js(xmlStr); var list = jsonObj.InputProxyChannelStatusList.InputProxyChannelStatus; for (var x = 0; x < list.length; x++) { that.hkvInfo.channels.push(list[x].id); } }, success: function (xmlDoc) {}, error: function (status, xmlDoc) { console.log("获取数字通道失败"); }, }); // 模拟通道 WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, { async: false, mysuccess: function (xmlStr) { var jsonObj = that.$x2js.xml2js(xmlStr); console.log("模拟通道mysuccess", xmlStr); var id = jsonObj.VideoInputChannelList.VideoInputChannel.id; that.hkvInfo.channels.push(id); }, success: function (xmlStr) { console.log("模拟通道success", xmlStr); }, error: function (status, xmlDoc) { console.log("模拟通道error", xmlDoc); }, }); // TODO 零通道 }, }, }; </script> <style scoped> .video_box { 100%; height: 100%; } .plugin { 100%; height: 100%; } .my-tag { margin-left: 3px; } .my-group-btn { margin-top: 5px; } </style>