Vue 对接海康威视,实现摄像头画面展示

需求

项目中集成海康威视,实现摄像头画面展示

分析

1. 下载

传送门:官方插件包和文档下载
在这里插入图片描述

2. 安装

(1)下载完成后打开
在这里插入图片描述
在这里插入图片描述
(2)在项目中public文件下创建一个文件夹放视频插件js
在这里插入图片描述
在这里插入图片描述

3. new 一个WebControl 插件相关实例

  • 案例一
<template>
    <video v-resize="DomResize" :id="newId ? newId : code" autoplay></video>
</template>
 
<script>
export default {
    props: {
        streamMode: {
            type: Number,
            default() {
                return 0
            }
        },
        code: {
            type: String,
            default() {
                return ''
            }
        },
        newId: {
            type: String,
            default() {
                return ''
            }
        },
        codeList: {
            type: Array,
            default() {
                return []
            }
        },
        layout: {
            type: String,
            default() {
                return '1x1'
            }
        },
        width: {
            type: Number,
            default() {
                return 212
            }
        },
        height: {
            type: Number,
            default() {
                return 120
            }
        }
    },
    data() {
        return {
            initCount: 0,
            pubKey: '',
            oWebControl2: '',
        }
    },
    created() {
        this.$nextTick(() => {
            this.initPlugin();
        });
    },
    methods: {
        DomResize(data) {
            let { width, height } = data;
            // console.log('width:', width, 'height:', height, '   dom尺寸方式改变');
            this.init();
        },
        initPlugin() {
            let _that = this;
            let currentId = _that.newId ? _that.newId : _that.code
            const oWebControl = new window.WebControl({
                szPluginContainer: currentId, // 指定容器id
                iServicePortStart: 15900, // 指定起止端口号,建议使用该值
                iServicePortEnd: 15909,
                szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
                cbConnectSuccess() {
                    console.log('创建WebControl实例成功');
                    oWebControl.JS_StartService('window', {
                        // WebControl实例创建成功后需要启动服务
                        dllPath: './VideoPluginConnect.dll', // 值"./VideoPluginConnect.dll"写死
                    })
                    .then(
                        () => {
                            // // 启动插件服务成功
                            oWebControl.JS_SetWindowControlCallback({
                                // 设置消息回调
                                cbIntegrationCallBack: _that.cbIntegrationCallBack,
                            });
                            oWebControl.JS_CreateWnd(currentId).then(() => {
                                //JS_CreateWnd创建视频播放窗口,宽高可设定
                                _that.init(); // 创建播放实例成功后初始化
                            });
                        },
                        () => {
                            // 启动插件服务失败
                        }
                    )
                    .catch((err) => {
                        console.log(err);
                    });
                },
                cbConnectError() {
                    // 创建WebControl实例失败
                    console.log('xxx');
                    oWebControl = null;
                    $('#' + currentId).html('插件未启动,正在尝试启动,请稍候...');
                    window.WebControl.JS_WakeUp('VideoWebPlugin://'); // 程序未启动时执行error函数,采用wakeup来启动程序
                    this.initCount++;
                    if (this.initCount < 3) {
                        setTimeout(function() {
                            this.initPlugin();
                        }, 3000);
                    } else {
                        $('#' + currentId).html('插件启动失败,请检查插件是否安装!');
                    }
                },
                cbConnectClose(bNormalClose) {
                    // 异常断开:bNormalClose = false
                    // JS_Disconnect正常断开:bNormalClose = true
                    console.log('cbConnectClose');
                    oWebControl = null;
                },
            });
            this.oWebControl2 = oWebControl;
        },
        //初始化
        init() {
            let _that = this;
            this.getPubKey(function() {
                // 请自行修改以下变量值
                var appkey = "XXXXX"; //综合安防管理平台提供的appkey,必填
                var secret = _that.setEncrypt("XXXXX"); //综合安防管理平台提供的secret,必填
                var ip = "XXXXXXX"; //综合安防管理平台IP地址,必填
                var playMode = 0; //初始播放模式:0-预览,1-回放
                var port = 443; //综合安防管理平台端口,若启用HTTPS协议,默认443
                var snapDir = ""; //抓图存储路径
                var videoDir = ""; //紧急录像或录像剪辑存储路径
                var layout = _that.layout; //playMode指定模式的布局
                var enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1
                var encryptedFields = "secret"; //加密字段,默认加密领域为secret
                var showToolbar = 0; //是否显示工具栏,0-不显示,非0-显示
                var showSmart = 0; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
                var buttonIDs = ""; //自定义工具条按钮
                // 请自行修改以上变量值
                _that.oWebControl2.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) => {
                    _that.oWebControl2.JS_Resize(_that.width, _that.height); // 初始化后resize一次,能和盒子大小一致。
                    if(_that.codeList.length > 0) {
                        for(let code of _that.codeList) {
                            _that.getVideoFun(code.cameraIndexCode)
                        }
                    }else {
                        _that.getVideoFun(_that.code)
                    }
                });
            });
        },
        // 设置窗口控制回调
        setCallbacks() {
                this.oWebControl.JS_SetWindowControlCallback({
                    cbIntegrationCallBack: this.cbIntegrationCallBack,
                });
        },
        //获取公钥
        getPubKey(callback) {
                this.oWebControl2.JS_RequestInterface({
                    funcName: "getRSAPubKey",
                    argument: JSON.stringify({
                        keyLength: 1024,
                    }),
                })
                .then((oData) => {
                    if (oData.responseMsg.data) {
                        this.pubKey = oData.responseMsg.data;
                        callback();
                    }
                });
        },
        //RSA加密
        setEncrypt(value) {
                var encrypt = new window.JSEncrypt();
                encrypt.setPublicKey(this.pubKey);
                return encrypt.encrypt(value);
        },
        //视频预览功能
        getVideoFun(Code) {
            var cameraIndexCode = Code; //获取输入的监控点编号值,必填
            var streamMode = this.streamMode; //主子码流标识:0-主码流,1-子码流
            var transMode = 1; //传输协议:0-UDP,1-TCP
            var gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
            var wndId = -1; //播放窗口序号(在2x2以上布局下可指定播放窗口)
            cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
            cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
            this.oWebControl2 .JS_RequestInterface({
                funcName: "startPreview",
                argument: JSON.stringify({
                    cameraIndexCode: cameraIndexCode, //监控点编号
                    streamMode: streamMode, //主子码流标识
                    transMode: transMode, //传输协议
                    gpuMode: gpuMode, //是否开启GPU硬解
                    wndId: wndId, //可指定播放窗口
                }),
            })
            .then((res) => {
                // console.log(res, "res");
            });
        },
        // 销毁播放窗口
        destroyVideoDiv() {
            this.oWebControl2.JS_DestroyWnd()
                .then((data) => {
                    console.log("销毁窗口成功");
            })
            .catch((err) => {
                console.log("销毁窗口失败");
            });
        },
        hideVideoDiv() {
            this.oWebControl2.JS_HideWnd()
        },
        showVideoDiv() {
            this.oWebControl2.JS_ShowWnd()
        }
    }
}
</script>
  • 案例二:
<template>
  <div
    v-show="isDisplay1"
    class="container-1"
  >
    <div :id="id" class="playWnd" v-text="info" />
  </div>
</template>

<script>
export default {
  name: '',
  components: {},
  props: {
    id: {
      type: String,
      default: 'playWnd'
    }
    // videoIdList: {
    //   type: Array,
    //   default: () => ([])
    // }
  },
  data() {
    return {
      oWebControl1: null,
      pubKey: '',
      info: '',
      initCount: 0,
      parentTitle: '',
      iframeClientPos: null,
      iframeParentShowSize: null,
      width: 0,
      height: 0,
      isDisplay1: true // 页面展示
    }
  },

  created() {

  },
  mounted() {
    this.isDisplay1 = true
    const demo = document.querySelector(`#${this.id}`)
    const dom = demo.getBoundingClientRect()
    this.width = dom.width
    this.height = dom.height
    this.initPlugin()
    const initParam = {
      'argument': {
        'appkey': '25329871',
        'ip': '192.168.20.253',
        'port': 443,
        'secret': 'ice4tbPdaVk1k9vX3mMK',
        'enableHTTPS': 1,
        'layout': '1x1',
        'playMode': 0,
        showSmart: 0, // 是否只能显示信息
        'wndId': -1,
        showToolbar: 0 // 是否显示工具栏
      },
      'funcName': 'init'
    }

    // jian
    const list = ['1f11869f492340b2a4911ec140cca712']
    setTimeout(() => {
    // console.log($(".container").height())
      this.requestInterface(initParam)
      // this.oWebControl1.JS_Resize($(".container").width(), $(".container").height());
      this.oWebControl1.JS_Resize(this.width, this.height)
      //
      for (let i = 0; i < list.length; i++) {
        const playParam = {
          'argument': {
            'cameraIndexCode': list[i],
            'ezvizDirect': 0,
            'gpuMode': 0,
            'streamMode': 0,
            'transMode': 1,
            'wndId': -1
          },
          'funcName': 'startPreview'
        }
        setTimeout(() => {
          this.requestInterface(playParam)
        }, 100)
      }
    }, 500)
    window.onload = () => {
      // requestInterface(initParam)
      // requestInterface( playParam)
    }
    const _this = this
    let resizeWaiter = false
    window.addEventListener('resize', function() {
      const demo = document.querySelector(`#${_this.id}`)
      const dom = demo.getBoundingClientRect()
      _this.width = dom.width
      _this.height = dom.height
      console.log(_this.width, _this.height)
      if (!resizeWaiter) {
        resizeWaiter = true
        setTimeout(function() {
          if (resizeWaiter) _this.oWebControl1.JS_Resize(_this.width, _this.height)
          resizeWaiter = false
        }, 100)
      }
    })

    // let   resizeWaiter
    //   if(!resizeWaiter){
    //       resizeWaiter = true;
    //       setTimeout(()=>{
    //           if(  resizeWaiter)        this.oWebControl1.JS_Resize(500,300);
    //           resizeWaiter = false;
    //       }, 100);
    //   }
  },
  destroyed() {
    this.destroyWnd()
    // this.oWebControl1 = null
  },
  beforeDestroy() {
    if (this.oWebControl1) {
      this.oWebControl1.JS_HideWnd()// 隐藏窗口
      // 断开链接
      this.oWebControl1.JS_Disconnect()
        .then(function() {
          console.log('断开与插件服务链接 sucess')
        },
        function() {
          console.log('断开与插件服务链接 fail')
        })
      // 销毁
      this.oWebControl1.JS_DestroyWnd()
        .then(function() {
          console.log('销毁插件 sucess')
        },
        function() {
          console.log('销毁插件 fail')
        })
      // this.oWebControl1 = null
    }
    this.isDisplay1 = false
  },

  methods: {
    destroyWnd(cb) {
      if (this.oWebControl1) {
        this.oWebControl1.JS_HideWnd()
        this.oWebControl1
          .JS_DestroyWnd({
            funcName: 'destroyeWnd'
          })
          .then(function(oData) {
          })
      } else {
        console.log('没有实例')
      }
      cb && cb()
    },
    initPlugin() {
      const _this = this
      this.oWebControl1 = new WebControl({
        szPluginContainer: _this.id,
        iServicePortStart: 15900,
        iServicePortEnd: 15900,
        szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
        cbConnectSuccess: function() {
          _this.initCount = 0
          _this.setCallbacks()
          _this.oWebControl1.JS_StartService('window', {
            dllPath: './VideoPluginConnect.dll'
          }).then(function() {
            // 步骤2:JS_CreateWnd时指定cbSetDocTitle回调,并在回调中向父页面发送更新标题消息,标题为回调出来的uuid
            _this.oWebControl1.JS_CreateWnd(_this.id, _this.width, _this.height, {
					    bEmbed: true,
              cbSetDocTitle: function(uuid) {
						  _this.oWebControl1._pendBg = false
						  window.parent.postMessage({
							  action: 'updateTitle',
							  msg: '子页面通知父页面修改title',
							  info: uuid
                }, '\*') // '\*'表示跨域参数,请结合自身业务合理设置
              }
            }).then(function() {
              // 步骤3:JS_CreateWnd成功后通知父页面将其标题修改回去
              console.log('JS_CreateWnd success')
              window.parent.postMessage({
							  action: 'updateTitle',
							  msg: '子页面通知父页面更新title',
							  info: _this.parentTitle
              }, '\*')

              // 步骤4:发消息更新插件窗口位置:这里不直接更新的原因是,父页面默认可能就存在滚动条,此时有滚动量
              window.parent.postMessage({
							  action: 'updatePos',
							  msg: '更新Pos'
              }, '\*')
            })
          }, function() {
            console.log('JS_CreateWnd fail')
          })
        },
        cbConnectError: function() {
          console.log('cbConnectError')
          _this.oWebControl1 = null
          _this.info = `插件未启动,正在尝试第${_this.initCount + 1}次启动,请稍候...`
          // $("#playWnd").html(`插件未启动,正在尝试第${this.initCount+1}次启动,请稍候...`);
          // WebControl.JS_WakeUp('VideoWebPlugin://')
          _this.initCount++
          if (_this.initCount < 3) {
            setTimeout(function() {
              _this.initPlugin()
            }, 3000)
          } else {
            // $("#playWnd").html("插件启动失败,请检查插件是否安装!");
            // window.parent.postMessage('err','*');
            _this.info = '未安装插件,请点击左侧下载插件!'
            _this.$emit('videoWebPluginMessage')
          }
        },
        cbConnectClose: function(bNormalClose) {
          // 异常断开:bNormalClose = false
          // JS_Disconnect正常断开:bNormalClose = true
          if (bNormalClose == true) {
            console.log('cbConnectClose normal')
          } else {
            console.log('cbConnectClose exception')
          }

          _this.oWebControl1 = null
          _this.info = `插件未启动,正在尝试第${_this.initCount + 1}次启动,请稍候...`
          // $("#playWnd").html(`插件未启动,正在尝试第${this.initCount+1}次启动,请稍候...`);
          // WebControl.JS_WakeUp('VideoWebPlugin://')
          _this.initCount++
          if (_this.initCount < 3) {
            setTimeout(function() {
              // 解决白块问题暂时注释掉
              // _this.initPlugin()
            }, 3000)
          } else {
          // $("#playWnd").html("插件启动失败,请检查插件是否安装!");
            // $("#playWnd").html("插件启动失败,请检查插件是否安装!");
          // window.parent.postMessage('err','*');
            _this.info = '未安装插件,请点击左侧下载插件!'

            _this.$emit('videoWebPluginMessage')
          }
        }
      })
    },
    getPubKey(callback) {
      this.oWebControl1.JS_RequestInterface({
        funcName: 'getRSAPubKey',
        argument: JSON.stringify({
          keyLength: 1024
        })
      }).then(function(oData) {
        console.log(oData)
        if (oData.responseMsg.data) {
          this.pubKey = oData.responseMsg.data
          callback()
        }
      })
    },
    setCallbacks() {
      this.oWebControl1.JS_SetWindowControlCallback({
        cbIntegrationCallBack: this.cbIntegrationCallBack
      })
    },
    cbIntegrationCallBack(oData) {
      this.showCBInfo(JSON.stringify(oData.responseMsg))
    },
    requestInterface(value) {
      this.oWebControl1.JS_RequestInterface(typeof value === 'string' ? JSON.parse(value) : value).then((oData) => {
        this.showCBInfo(JSON.stringify(oData ? oData.responseMsg : ''))
      })
    },
    showCBInfo(szInfo, type) {
      if (type === 'error') {
        szInfo = "<div style='color: red;'>" + this.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss') + ' ' + szInfo + '</div>'
      } else {
        szInfo = '<div>' + this.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss') + ' ' + szInfo + '</div>'
      }
      // $("#cbInfo").html(szInfo + $("#cbInfo").html());
    },
    dateFormat(oDate, fmt) {
      var o = {
        'M+': oDate.getMonth() + 1, // 月份
        'd+': oDate.getDate(), // 日
        'h+': oDate.getHours(), // 小时
        'm+': oDate.getMinutes(), // 分
        's+': oDate.getSeconds(), // 秒
        'q+': Math.floor((oDate.getMonth() + 3) / 3), // 季度
        'S': oDate.getMilliseconds()// 毫秒
      }
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + '').substr(4 - RegExp.$1.length))
      }
      for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
          fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
        }
      }
      return fmt
    }
  }

}
</script>

<style lang="scss" >
.container-1 {
  position: relative;
  // margin-left: -20px;
  width: 100%;
  height: 100%;
  background: transparent;
  .playWnd {
    position: absolute;
    bottom: 5px;
    height: 95%;
    width: 95%;
    background: transparent;
  }
}
</style>

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 09:48:03       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 09:48:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 09:48:03       45 阅读
  4. Python语言-面向对象

    2024-07-21 09:48:03       55 阅读

热门阅读

  1. 新媒体运营如何找准账号定位?

    2024-07-21 09:48:03       16 阅读
  2. C++--fill

    2024-07-21 09:48:03       15 阅读
  3. Docker部署kafka,Docker所在宿主机以外主机访问

    2024-07-21 09:48:03       17 阅读
  4. Rust编程-类面向对象编程

    2024-07-21 09:48:03       14 阅读
  5. SQL Server高级玩法:打造数据库的自定义存储过程

    2024-07-21 09:48:03       16 阅读
  6. 运筹学:决策优化的艺术

    2024-07-21 09:48:03       15 阅读
  7. OpenCV车牌识别技术详解

    2024-07-21 09:48:03       14 阅读
  8. MySQL——索引

    2024-07-21 09:48:03       15 阅读
  9. Log4j2原理及应用详解(十三)

    2024-07-21 09:48:03       18 阅读