vue-element-admin 集成海康威视监控插件VideoWebPlugin

项目场景:

项目为智慧园区后台管理系统
需求 全部摄像头实时监控&&单个监控直播&&单个监控回放
集成 海康威视监控 WEB插件
网上有非常多的资源代码实例 大多数还需要根据自己的需求改进
实测 完美兼容

演示:

页面监控

在这里插入图片描述

弹出层监控

在这里插入图片描述


准备

海康开放平台
注册个账号=>下载 =>iSecureCenter=> 视频WEB插件V1.5.1
下载后在bin文件夹 VideoWebPlugin.exe 双击安装 (仅支持Windows)

里面的几个demo非常有用 挨个测试一下 至少知道怎么一回事
最关键 是这个开发指南 所有你想试下的功能 都在里边了
在这里插入图片描述

或许能用到的几个网址:
直播地址测试
Vue接入监控视频技术整理
基于vue项目 vue-video-player实现rtmp hls视频流播放
vue cli中播放rtmp&flv/m3u8/rtsp ; 在html原生页面中播放m3u8
vue截图,上传,下载,预览
vue实现播放rtmp直播视频流
阿里云Web端播放器

方案

封装一个海康威视的播放器组件

这里从父组件传入了几个参数 以及一些引入的库 实际开发因人而异
*index :当前组件所属页面 因为由多个页面用到
*type : 回放 || 直播
*code : 监控点编号 监控设备页面String || 实时监控 Array
*time 回放时间设定 暂时废弃
几点注意 :
监控组件的 宽高自适应外层父组件 ;
项目中另外一个监控组件是装在vxe-modal弹出层的,这个modal可以拖拽,拖拽时需要对视频组件进行重新定位,会有卡顿感;
监控视频的显示优先级最高,不知道怎么调整,因此需要确保每次只能初始化一个插件实例;
组件视频采用九宫格3x3展示,超出部分分页实现,我也写过根据监控id总量动态布局,后来默认了;
创建插件实例 initPlugin 这个方法 朝父组件发射了个事件 通知父组件 我这边正在初始化,防止重复加载监控实例;

/**
 * @author deep1nBlur
 * @email mailbrcee@gmail.com 
 * @create date 2020-11-05 09:10:05 
 * @modify date 2020-11-05 09:10:05
 * @desc [海康监控视频组件]
 *  */
<template>
  <div
    class="root-haikang-video"
    id="video-frame"
    :style="{
      width: sizes.width,
      height: sizes.height
    }"
  >
    <div
      id="playWnd"
      class="playWnd"
      v-html="playText"
      :style="{ width: swfWidth + 'px', height: swfHeight + 'px' }"
    ></div>

    <el-button-group
      v-if="show"
      style="margin-top: 5px; display: flex; justify-content: center"
    >
      <el-button
        size="mini"
        type="primary"
        icon="el-icon-arrow-left"
        @click="nextPage('left')"
        :disabled="page == 0"
        >上一页</el-button
      >
      <el-button
        size="mini"
        type="primary"
        @click="nextPage('right')"
        :disabled="page + 1 == pageNum"
        >下一页<i class="el-icon-arrow-right el-icon--right"
      /></el-button>
    </el-button-group>
  </div>
</template>

<script>
import request from "@/utils/request";
import { isArray } from "xe-utils/methods";

export default {
  /**
   * index :当前组件所属页面 设备管理 为空 ||实时监控 realTime
   * type : 回放 || 直播
   * code : 监控点编号 监控设备页面String || 实时监控 Array
   * time 回放时间 暂时废弃
   */
  props: ["index", "type", "code", "time"],
  data() {
    return {
      sizes: {
        width: "782px",
        height: "490px"
      },
      layoutFmt: {
        1: "1x1",
        2: "1x2",
        3: "1+2",
        4: "2x2",
        5: "1+5",
        6: "3+4",
        7: "3+4",
        8: "1+7",
        9: "3x3"
      },
      page: 0,
      pageNum: 1,
      show: false,
      timeRange: "",
      swfHeight: "",
      swfWidth: "",
      //初始化参数
      initparam: {},
      //监控点编号
      pointCode: "",
      pubKey: "",
      oWebControl: null,
      WebControl: null,
      playText: "插件正在启动,请稍候..."
    };
  },
  methods: {
    nextPage() {
      // 实时监控 当code 长度 当大于页面布局  显示 下一页按钮
      if (arguments[0] == "left") {
        this.page--;
      } else {
        this.page++;
      }
      this.startPlay();
    },
    getInitParams() {
      // 获取海康综合安防参数
      this.initparam = {};
      request({
        url: `xxxxxxxxxxxxxxxxxxxxxxxxxxÏ`,
        method: "get"
      })
        .then(res => {
          if (res && !res.data.hkApiBackend) {
            this.$message({
              message: "请完善华为云Roma平台配置!",
              type: "error"
            });
            this.playText = "";
            return;
          }
          this.initparam = res.data;
          //页面加载时创建播放实例初始化
          this.initPlugin();
        })
        .catch(err => {
          console.log(err);
        });
    },

    // 创建插件实例
    initPlugin() {
      this.$emit("update:pluginIsInit", true);
      this.oWebControl = new WebControl({
        szPluginContainer: "playWnd", // 指定容器id
        iServicePortStart: 15900, // 指定起止端口号,建议使用该值
        iServicePortEnd: 15909,
        szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
        // 创建WebControl实例成功
        cbConnectSuccess: () => {
          this.oWebControl
            .JS_StartService("window", {
              // WebControl实例创建成功后 启动插件服务接口 参数固定
              dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死
            })
            .then(
              () => {
                // 启动插件服务成功
                this.oWebControl.JS_SetWindowControlCallback({
                  // 设置消息回调
                  cbIntegrationCallBack: this.cbIntegrationCallBack
                });

                this.oWebControl
                  .JS_CreateWnd("playWnd", this.swfWidth, this.swfHeight)
                  .then(() => {
                    //JS_CreateWnd创建视频播放窗口,宽高可设定
                    this.init(); // 创建播放实例成功后初始化
                  });
              },
              () => {
                // 启动插件服务失败
              }
            );
        },
        // 创建WebControl实例失败
        cbConnectError: () => {
          this.oWebControl = null;
          this.playText = "插件未启动,正在尝试启动,请稍候...";
          this.WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序
          this.initCount++;
          if (this.initCount < 3) {
            setTimeout(() => {
              this.initPlugin();
            }, 3000);
          } else {
            this.playText =
              '插件启动失败,请检查插件是否安装!<a target="_blank" style="color: #30a8ff;text-decoration: underline;" href=" ' +
              this.initparam.hkVideoPlugin +
              '">windows下载地址(软件大小:67MB)</a>';
          }
        },
        // 异常断开:bNormalClose = false
        cbConnectClose: bNormalClose => {
          // JS_Disconnect正常断开:bNormalClose = true
          console.log(
            "%c海康插件=>插件正常断开",
            "color:#00e676",
            bNormalClose
          );
          this.oWebControl = null;
        }
      });
    },
    // 设置窗口控制回调
    setCallbacks() {
      this.oWebControl.JS_SetWindowControlCallback({
        cbIntegrationCallBack: this.cbIntegrationCallBack
      });
    },
    // 推送消息
    cbIntegrationCallBack(oData) {
      console.info(
        "%c海康web插件信息推送=>",
        "color:#00e676;",
        oData.responseMsg
      );
      /* showCBInfo(JSON.stringify(oData.responseMsg)); */
    },
    //初始化视频播放
    init() {
      this.getPubKey(() => {
        let appkey = this.initparam.hkAppkey; //综合安防管理平台提供的appkey,必填
        let secret = this.setEncrypt(this.initparam.hkSecret); //综合安防管理平台提供的secret,必填
        let ip = this.initparam.hkApiBackend.split("//")[1].split(":")[0]; //综合安防管理平台IP地址,必填
        let port = this.initparam.hkApiBackend.split("//")[1].split(":")[1]; //综合安防管理平台端口,若启用HTTPS协议,默认443
        port = parseInt(port);
        let layout = "1x1";
        let playMode = this.type == "live" ? 0 : 1; //初始播放模式:0-预览,1-回放
        let snapDir = "D:\\SnapDir"; //抓图存储路径
        let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
        let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,是为1,否为0
        let encryptedFields = "secret"; //加密字段,默认加密领域为secret
        let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
        let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
        let buttonIDs = "256,258,259,260,512,515,516,517,768,769"; //自定义工具条按钮
        this.oWebControl
          .JS_RequestInterface({
            funcName: "init",
            argument: JSON.stringify({
              appkey: appkey, //API网关提供的appkey
              secret: secret, //API网关提供的secret
              ip: ip, //API网关IP地址
              playMode: playMode, //播放模式(决定显示预览还是回放界面)
              port: port, //端口
              snapDir: snapDir, //抓图存储路径
              videoDir: videoDir, //紧急录像或录像剪辑存储路径
              layout: layout, //布局
              enableHTTPS: enableHTTPS, //是否启用HTTPS协议
              encryptedFields: encryptedFields, //加密字段
              showToolbar: showToolbar, //是否显示工具栏
              showSmart: showSmart, //是否显示智能信息
              buttonIDs: buttonIDs //自定义工具条按钮
            })
          })
          .then(oData => {
            this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
            this.$emit("update:pluginIsInit", false);
            this.playText = "";

            if (this.index == "realTime") {
              // 实时监控 批量播放 设置布局
              if (this.code.length && isArray(this.code)) {
                let basicLayout = "1x1"; //基础布局
                let totalCode = this.code.length; //实时监控总条数
                let layoutPage = Math.ceil(totalCode / 9); //超过十条每页显示十条   向上取整
                // console.log("=====总页数", layoutPage);
                if (totalCode <= 9) {
                  basicLayout = this.layoutFmt[totalCode];
                } else {
                  // 大于10 时 按照"2x2" 布局
                  // 显示下一页 总页数
                  this.show = true;
                  this.pageNum = layoutPage;
                  basicLayout = "3x3";
                }
                this.oWebControl.JS_RequestInterface({
                  // 设置窗口布局
                  funcName: "setLayout",
                  argument: JSON.stringify({
                    layout: "3x3" // 窗口布局默认9
                  })
                });
              }
            }

            this.startPlay(); //初始化之后开启预览
          });
      });
    },
    // 申请 RSA 公钥,用于对敏感信息(如 appkey、secret)加密。
    getPubKey(callback) {
      this.oWebControl
        .JS_RequestInterface({
          funcName: "getRSAPubKey",
          argument: JSON.stringify({
            keyLength: 1024
          })
        })
        .then(oData => {
          // console.log(oData);
          if (oData.responseMsg.data) {
            this.pubKey = oData.responseMsg.data;
            callback();
          }
        });
    },
    //RSA加密
    setEncrypt(value) {
      let encrypt = new JSEncrypt();
      encrypt.setPublicKey(this.pubKey);
      return encrypt.encrypt(value);
    },
    // 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
    setWndCover() {
      let iWidth = $(window).width();
      let iHeight = $(window).height();
      let oDivRect = $("#playWnd")
        .get(0)
        .getBoundingClientRect();
      let iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0;
      let iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0;
      let iCoverRight =
        oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0;
      let iCoverBottom =
        oDivRect.bottom - iHeight > 0
          ? Math.round(oDivRect.bottom - iHeight)
          : 0;

      iCoverLeft = iCoverLeft > this.swfWidth ? this.swfWidth : iCoverLeft;
      iCoverTop = iCoverTop > this.swfHeight ? this.swfHeight : iCoverTop;
      iCoverRight = iCoverRight > this.swfWidth ? this.swfWidth : iCoverRight;
      iCoverBottom =
        iCoverBottom > this.swfHeight ? this.swfHeight : iCoverBottom;
      this.oWebControl.JS_RepairPartWindow(
        0,
        0,
        this.swfWidth + 1,
        this.swfHeight
      ); // 多1个像素点防止还原后边界缺失一个像素条
      if (iCoverLeft != 0) {
        this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.swfHeight);
      }
      if (iCoverTop != 0) {
        this.oWebControl.JS_CuttingPartWindow(
          0,
          0,
          this.swfWidth + 1,
          iCoverTop
        ); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
      }
      if (iCoverRight != 0) {
        this.oWebControl.JS_CuttingPartWindow(
          this.swfWidth - iCoverRight,
          0,
          iCoverRight,
          this.swfHeight
        );
      }
      if (iCoverBottom != 0) {
        this.oWebControl.JS_CuttingPartWindow(
          0,
          this.swfHeight - iCoverBottom,
          this.swfWidth,
          iCoverBottom
        );
      }
    },
    //播放监控视频 预览 || 回放 || 批量
    startPlay() {
      let streamMode = 1; //主子码流标识:0-主码流,1-子码流
      let transMode = 1; //传输协议:0-UDP,1-TCP
      let gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
      if (this.index == "realTime") {
        // 实时监控 批量播放
        // console.log(
        //   "这是实时页码================================================",
        //   this.page
        // );

        if (this.code.length && isArray(this.code)) {
          let temp = [];
          let arr = [];
          if (this.code.length > 9) {
            // 大于9 分页显示
            arr = this.code.slice(this.page * 9, (this.page + 1) * 9);
          } else {
            arr = this.code;
          }
          arr.forEach((item, index) => {
            let obj = {};
            obj.cameraIndexCode = item.pointInterCode;
            obj.wndId = index + 1;
            obj.transMode = transMode;
            obj.streamMode = streamMode;
            obj.gpuMode = gpuMode;
            temp.push(obj);
          });
          this.oWebControl.JS_RequestInterface({
            funcName: "startMultiPreviewByCameraIndexCode",
            argument: JSON.stringify({
              list: temp
            })
          });
        }
      } else {
        // 监控设备管理 直播 or 回放
        let cameraIndexCode = this.code; //获取输入的监控点编号值,必填
        let wndId = -1; //播放窗口序号(在2x2以上布局下可指定播放窗口)
        cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
        cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");

        if (this.type == "live") {
          // 视频预览
          this.oWebControl.JS_RequestInterface({
            funcName: "startPreview",
            argument: JSON.stringify({
              cameraIndexCode: cameraIndexCode, //监控点编号
              streamMode: streamMode, //主子码流标识
              transMode: transMode, //传输协议
              gpuMode: gpuMode, //是否开启GPU硬解
              wndId: wndId //可指定播放窗口
            })
          });
        } else {
          //视频回放
          this.oWebControl.JS_RequestInterface({
            funcName: "startPlayback",
            argument: JSON.stringify({
              cameraIndexCode: cameraIndexCode, //监控点编号
              startTimeStamp: this.timeRange[0] / 1000, // 录像查询开始时间戳,单位:秒
              endTimeStamp: this.timeRange[1] / 1000, // 录像查询结束时间戳,单位:秒
              recordLocation: 1, // 录像存储类型 0-中心存储 1-设备存储
              transMode: transMode,
              gpuMode: gpuMode,
              wndId: wndId
            })
          });
        }
      }
    },

    //停止全部预览功能
    stopAllPreview() {
      this.oWebControl.JS_RequestInterface({
        funcName: "stopAllPreview"
      });
    },
    //关闭视频窗口
    closeWindow() {
      console.log("%c海康插件=>", "color:#00e676;", "关闭页面,销毁插件实例!");
      if (this.oWebControl != null) {
        this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
        this.oWebControl.JS_Disconnect().then(
          () => {
            // 断开与插件服务连接成功
          },
          () => {
            // 断开与插件服务连接失败
          }
        );
      }
    }
  },
  created() {
    this.timeRange = this.time;
    this.WebControl = WebControl; //调用电脑中的插件
    if (this.index == "realTime") {
      // 重新计算布局
      this.sizes = {
        width: this.$parent.$el.clientWidth - 50 + "px",
        height: this.$parent.$el.clientHeight - 50 + "px"
      };
    }
  },
  mounted() {
    this.closeWindow();
    this.swfHeight = document.getElementById("video-frame").offsetHeight;
    this.swfWidth = document.getElementById("video-frame").offsetWidth;

    // 获取海康威视安防配置参数
    this.getInitParams();
    // 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
    $(window).resize(() => {
      if (this.oWebControl != null) {
        this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
        this.setWndCover();
      }
    });
    // 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动
    $(window).scroll(() => {
      if (this.oWebControl != null) {
        this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
        this.setWndCover();
      }
    });
    // 监听vxe-modal 拖拽完成事件 仅在监控设备管理页面
    if (this.index !== "realTime") {
      $(window).mouseup($evt => {
        if ($evt.target.className.indexOf("vxe-modal--header") != -1) {
          // vxe modal 表头拖拽 动态调整插件位置
          console.log(
            "%c海康插件=>",
            "color:#00e676;",
            "Modal被拖拽,动态调整插件位置"
          );
          if (this.oWebControl != null) {
            this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
            this.setWndCover();
          }
        }
      });
    }
  },
  beforeDestroy() {
    $(window).off(); //关闭插件之前 移除jquery所有绑定事件
    this.closeWindow(); //关闭插件
  },
};
</script>

<style lang="scss" scoped>
.root-haikang-video {
  .playWnd {
    width: 100%;
    height: 100%;
  }
}
</style>

组件调用


//展示所有监控时
	<haikang
            type="live"
            index="realTime"
            :code="codeList"
            :pluginIsInit.sync="pluginIsInit"
          />
//单点监控 直播 或者回放
	<haikang
          :type="type"
          :index="index"
          :code="params.pointInterCode"
          :time="timeRange"
        />


芜湖 起飞~

版权声明:本文为bosslay原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。