SpringBoot+Vue+HIKVSION實現攝像頭多選並多窗口預覽(插件版)


場景

若依前后端分離版手把手教你本地搭建環境並運行項目:

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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM