場景
若依前后端分離版手把手教你本地搭建環境並運行項目:
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 { width: 100%; height: 100%; } .plugin { width: 100%; height: 100%; } .my-tag { margin-left: 3px; } .my-group-btn { margin-top: 5px; } </style>
