Vue中預覽HIKVSION海康威視的NVR(網路硬碟錄影機)中多個通道(攝像機)的視訊
場景
SpringBoot+Vue+HIKVSION實現攝像頭多選並多視窗預覽(外掛版):
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121180769
上面實現的在Vue中直接通過單個攝像頭的Ip、埠、使用者名稱、密碼來預覽
攝像頭的視訊,這裡將兩個攝像頭裝在海康威視網路硬碟錄影機,即NVR中。
怎樣在Vue中進行預覽。
去海康威視官網下載web開發包
具體參考上面的部落格。
根據其官方文件的說明,Web控制元件既適應於單個攝像頭的預覽,也適用於NVR等裝置的預覽,預覽介面和流程是一致的。
注:
部落格:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程式猿
獲取程式設計相關電子書、教程推送與免費下載。
實現
1、要實現瀏覽器能訪問NVR中的攝像頭的視訊,要保證NVR連線了網路,並配置了ip,以及需要訪問視訊的電腦的網路和nvr網路互通。
在使用Vue進行對接前,先使用海康官方的CH_WEB3.0控制元件開發包中demo/cn下的demo.html或者demo-easy.html測試預覽視訊的效果
因為此款攝像頭只能用外掛加相容模式預覽視訊,所以使用支援相容模式的某60瀏覽器
安裝了外掛後會提示是否允許阻止的內容,點選允許
2、然後配置nvr的ip、埠號、使用者名稱、密碼等資訊
登入成功之後會有提示並且顯示通道列表,這裡Camera 01和02就是代表的有兩個攝像頭。
3、選擇攝像頭1,點選預覽
點選第二個預覽格再下拉選中攝像頭2點選預覽
4、需要注意的是,在進行預覽時要選擇預覽的碼流型別為子碼流
那樣視訊會比主碼流流暢。然後瀏覽器要切換相容模式
5、在Vue中實現
首先在前一個頁面中獲取nvr的ip,因為這裡的埠、使用者名稱和密碼都是統一配置的,所以不再配置和獲取。
下面是在按鈕的點選事件中,即methods中
//NVR視訊預覽,傳遞通道號 nvrPreview(channelNum){ let self = this; //校驗NvrIP是否配置正確if(self.nvrIp){ let openVideoData = []; let hkvInfo = { ip: self.nvrIp, //海康威視攝像頭/硬碟錄影機的ip地址 port: "80", //海康威視攝像頭/硬碟錄影機的埠 username: "admin", //海康威視攝像頭/硬碟錄影機的使用者名稱 password: "你自己的密碼", //海康威視攝像頭/硬碟錄影機的密碼 channels: [channelNum], //海康威視攝像頭/硬碟錄影機的通道 nvrPrechannel: channelNum, //NVR預覽通道 }; openVideoData.push(hkvInfo); let routeUrl = this.$router.resolve({ path: "/carNvrVideo", query: { videoData: JSON.stringify(openVideoData), }, }); window.open(routeUrl.href, "_blank"); }else{ //提示未配置 this.$message({ message: '當前車輛nvrip未配置', type: 'warning' }); } },
6、配置路由跳轉參考前面部落格。
這裡預覽基本和上面單個預覽的程式碼一致,優化的地方是
在呼叫預覽方法時多傳遞了碼流型別iStreamType這個欄位,指定為子碼流,這樣預覽更流暢。
這裡傳遞了通道id引數,1就代表1號通道,即攝像頭1。
startRealPlay(szDeviceIdentify, iWndIndex, iChannelID) { var that = this; WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iRtspPort: that.iRtspPort, iWndIndex: iWndIndex, iChannelID: iChannelID, bZeroChannel: that.bZeroChannel, iStreamType: 2,//碼流型別,2為子碼流 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); } }, }); },
預覽可以參考官方開發文件傳參
7、之前發現在預覽前先驗證是否切換了相容模式,然後切換之後如果配置的Ip或者使用者名稱等不正確,即
登入失敗時所提示的程式碼仍然是Vue的ElementUI的語法,在相容模式中無法執行,所以會導致在預覽時如果
登入失敗就會網頁無響應。所以將其登入失敗的回撥方法中的提示訊息由Vue的程式碼修改為js的alert程式碼
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; alert("當前攝像頭配置不對或不線上,登入失敗"); window.opener=null; window.open('','_self'); window.close(); }, } ); },
8、還要注意在頁面載入完之後要設定一個延遲初始化外掛的程式碼
如果頁面沒載入完就初始化外掛會報錯。
mounted() { this.videoChange(); }, methods: { videoChange() { setTimeout(() => { this.videoInitPlugin(); // 初始化video介面 }, 300); },
9、預覽頁面完整程式碼
<template> <div class="video_box"> <!-- 攝像頭 --> <div id="divPlugin" class="plugin"></div> </div> </template> <script> import { WebVideoCtrl } from "/static/webVideoCtrl.js"; export default { name: "carNvrVideo", 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() { 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; } }, mounted() { this.videoChange(); }, destroyed() { this.clickStopRealPlay(); this.onLogout(); }, methods: { 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; alert("當前攝像頭配置不對或不線上,登入失敗"); window.opener=null; window.open('','_self'); window.close(); }, } ); }, // 退出 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; debugger that.startRealPlay(szDeviceIdentify, this.index, that.hkvInfo.nvrPrechannel); that.startPlayLoading = false; }, startRealPlay(szDeviceIdentify, iWndIndex, iChannelID) { var that = this; WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iRtspPort: that.iRtspPort, iWndIndex: iWndIndex, iChannelID: iChannelID, bZeroChannel: that.bZeroChannel, iStreamType: 2,//碼流型別,2為子碼流 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; }else{ if (this.ua.match(/msie/) != null || this.ua.match(/trident/) != null) { this.browserType = "IE"; this.initPlugin(); } else { this.$notify({ title: "失敗", message: "請在ie模式下檢視攝像頭", type: "error", }); } } }); }, 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]; debugger 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>