SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版)

场景

若依前后端分离版手把手教你本地搭建环境并运行项目:

若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客

SpringBoot+Vue+Openlayers实现地图上新增和编辑坐标并保存提交:

SpringBoot+Vue+Openlayers实现地图上新增和编辑坐标并保存提交_BADAO_LIUMANG_QIZHI的博客-CSDN博客

在上面实现的基础上,对接海康威视摄像头实现摄像头预览效果。

该型号只支持IE模式取流。

注:

博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

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>

猜你喜欢

转载自blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121180769