Vue+Openlayers+HIKVSION实现点击摄像头进行预览
場景
SpringBoot+Vue+HIKVSION實現攝像頭多選并多窗口預覽(插件版):
SpringBoot+Vue+HIKVSION實現攝像頭多選并多窗口預覽(插件版)_霸道流氓氣質的博客-CSDN博客
上面實現的攝像頭的預覽,是在菜單中配置攝像頭參數,然后點擊預覽按鈕時進行預覽。
攝像頭信息的新增和編輯包括在地圖上添加和修改攝像頭的坐標參考如下
SpringBoot+Vue+Openlayers實現地圖上新增和編輯坐標并保存提交:
SpringBoot+Vue+Openlayers實現地圖上新增和編輯坐標并保存提交_霸道流氓氣質的博客-CSDN博客
在上面的基礎上實現的效果如下
注:
博客:
霸道流氓氣質的博客_CSDN博客-C#,架構之路,SpringBoot領域博主
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
1、后臺邏輯
定時任務中查詢所有攝像頭的坐標和ip、用戶名、密碼、端口等信息。
為了避免頻繁對msyql數據庫操作,可以借助于redis緩存的實現。
SpringBoot中通過自定義緩存注解(AOP切面攔截)實現數據庫數據緩存到Redis:
SpringBoot中通過自定義緩存注解(AOP切面攔截)實現數據庫數據緩存到Redis_霸道流氓氣質的博客-CSDN博客
然后后臺通過websocket推送給前端。
2、前端收到數據之后將攝像頭圖標添加顯示
??????????? if (data.video && data.video.length > 0) {await this.videoLayer.getSource().clear();this.drawVideoPoint(data.video);this.videoListData = data.video;}每次收到新的數據重新新增feature,要將該圖層的source清理一下。
在收到推送的數據的回調方法中判斷數據不為0,則調用繪制點位的方法,并且將攝像頭的數據存儲一份給this.videoListData 。
接收的數據結構如下
?
3、添加點的方法drawVideoPoint實現
??????? drawVideoPoint(data) {// 畫起點,終點data.forEach((item, index) => {var feature = new Feature({geometry: new Point(item.videoAdd),});feature.setId(`video_${item.id}`);let url = "images/video.png";const zoom = this.map.getView().getZoom();let style = new Style({image: new Icon({scale: 0.06 * (zoom - 13),src: url,anchor: [0.48, 0.52],}),});feature.setStyle(style);this.videoLayer.getSource().addFeature(feature);});},在添加每一個feature時一定要設置其id
feature.setId(`video_${item.id}`);4、監聽地圖的點擊事件
??????????? // 監聽地圖點擊事件self.onShow = self.map.on("singleclick", (evt) => {self.mapDialog(evt);});5、點擊事件方法實現
獲取點擊的feature
??????????????????? var feature = self.map.forEachFeatureAtPixel(evt.pixel, (feature) => {return feature;});然后遍歷上面存儲的攝像頭的數據對比id是否一致,獲取對應feature的攝像頭的屬性
??????????????????????? self.videoListData.forEach(async (e) => {if (self.searchEmpId == 'video_'+ e.id) {let openVideoData = [];let hkvInfo = {ip: e.ip, //海康威視攝像頭/硬盤錄像機的ip地址port: e.port, //海康威視攝像頭/硬盤錄像機的端口username: e.username, //海康威視攝像頭/硬盤錄像機的用戶名password: e.password, //海康威視攝像頭/硬盤錄像機的密碼channels: [], //海康威視攝像頭/硬盤錄像機的通道};openVideoData.push(hkvInfo);let routeUrl = this.$router.resolve({path: "/carVideo",query: {videoData: JSON.stringify(openVideoData),},});window.open(routeUrl.href, "_blank");}});然后將預覽攝像頭所需的參數傳遞到新的路由頁面并在新的標簽頁中打開。
6、在router下index.js中添加/carVideo路由
??? {path: '/carVideo',component: Layout,component: (resolve) => require(['@/views/runcontrolmange/carVideo/component/video'], resolve),meta: {title: '攝像頭'},hidden: true,},?
7、來到預覽攝像頭的頁面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: [],};},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: {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_CheckPluginInstalliWndowType: this.iWndowType, //默認展示幾個攝像頭1x1 2x2cbInitPluginComplete: 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>
?
總結
以上是生活随笔為你收集整理的Vue+Openlayers+HIKVSION实现点击摄像头进行预览的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS中调用本地Winform程序并传递参
- 下一篇: Vue中使用uuidv1根据时间戳和MA