vue中使用HKPlayer播放器连接摄像头监控

vue中使用HKPlayer播放器连接摄像头监控

效果图 可以控制摄像头移动

可以控制摄像头移动
代码

<template>
  <div style="user-select: none;">
    <a-alert type="error" v-if="showErrorTips" :message="errorMessage" banner />
    <div :id="playerContainerId" :style="{ width: width + 'px', height: height + 'px' }"></div>
  </div>
</template>

<script>
/* eslint-disable */
import * as JsEncryptModule from 'jsencrypt'
import UUID from '../../utils/UUID'

import HKPlayerResize from './common/hkplayer-resize'

import HKPlayerInitArgs from './common/hkplayer-init-args'

export default {
  name: 'HKPlayer',
  mixins: [HKPlayerResize],
  props: {
    width: {
      type: Number,
      default: 984,
    },
    height: {
      type: Number,
      default: 600,
    },
    cameraIndexCodes: {
      type: Array,
      default: () => {
        return []
      },
    },
  },
  data() {
    return {
      playerContainerId: new UUID().id,
      oWebControl: undefined,
      showErrorTips: false,
      errorMessage: '',
      pubKey: undefined,
      initSuccess: false,
      playInterval: undefined,
      initCount: 0,
      currentCameraIndexCodes: this.cameraIndexCodes,
      defaultInitArgs: {
        //API网关提供的appkey
        appkey: '27339437',
        //API网关提供的secret
        secretKey: 'zATVBCzPOAAiHtnWBzAz',
        //API网关IP地址
        ip: '202.100.100.50',
        // ip: '172.168.101.31',
        //播放模式(决定显示预览还是回放界面)
        playMode: 0,
        //端口
        port: 4443,
        //抓图存储路径
        snapDir: 'D:\\SnapDir',
        //紧急录像或录像剪辑存储路径
        videoDir: 'D:\\VideoDir',
        //布局
        layout: '1x1',
        //是否启用HTTPS协议
        enableHTTPS: 1,
        //加密字段
        encryptedFields: 'secret',
        //是否显示工具栏
        showToolbar: 1,
        //是否显示智能信息
        showSmart: 1,
        //自定义工具条按钮
        buttonIDs: '0,256,257,258,259,260,512,513,514,515,516,517,768,769',
      },
    }
  },
  watch: {
    cameraIndexCodes(value) {
      this.currentCameraIndexCodes = value
    },
  },
  methods: {
    initPlugin() {
      const { playerContainerId, width, height } = this
      this.oWebControl = new WebControl({
        szPluginContainer: this.playerContainerId, // 指定容器id
        iServicePortStart: 15900, // 指定起止端口号,建议使用该值
        iServicePortEnd: 15909,
        szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
        cbConnectSuccess: () => {
          // 创建WebControl实例成功
          this.oWebControl
            .JS_StartService('window', {
              // WebControl实例创建成功后需要启动服务
              dllPath: './VideoPluginConnect.dll', // 值"./VideoPluginConnect.dll"写死
            })
            .then(
              () => {
                // 启动插件服务成功
                this.oWebControl.JS_SetWindowControlCallback({
                  // 设置消息回调
                  cbIntegrationCallBack: this.cbIntegrationCallBack,
                })

                this.oWebControl.JS_CreateWnd(playerContainerId, width, height).then(() => {
                  //JS_CreateWnd创建视频播放窗口,宽高可设定
                  this.init() // 创建播放实例成功后初始化
                })
              },
              () => {
                // 启动插件服务失败
                this.showErrorTipsHandle('视频播放插件启动失败,未知错误!')
              }
            )
        },
        cbConnectError: () => {
          // 创建WebControl实例失败
          this.oWebControl = undefined
          this.showErrorTipsHandle('插件未启动,正在尝试启动,请稍候...')
          WebControl.JS_WakeUp('VideoWebPlugin://') // 程序未启动时执行error函数,采用wakeup来启动程序
          this.initCount++
          if (this.initCount < 3) {
            setTimeout(() => {
              this.initPlugin()
            }, 3000)
          } else {
            this.showErrorTipsHandle('插件启动失败,请检查插件是否安装!(安装插件后,请刷新当前页面)')
          }
        },
        cbConnectClose: function (bNormalClose) {
          // 异常断开:bNormalClose = false
          // JS_Disconnect正常断开:bNormalClose = true
          this.oWebControl = undefined
        },
      })
    },

    init() {
      const { width, height } = this
      this.getPubKey(() => {
        const args = Object.assign(HKPlayerInitArgs, this.defaultInitArgs)
        args.secret = this.setEncrypt(this.defaultInitArgs.secretKey)
        //通过传入设备,设置播放窗口布局
        args.layout = this.getHKPlayLayout()
        this.oWebControl
          .JS_RequestInterface({
            funcName: 'init',
            argument: JSON.stringify(args),
          })
          .then((oData) => {
            this.oWebControl.JS_Resize(width, height) // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
            this.initSuccess = true
          })
      })
    },

    /**
     * 播放
     */
    play() {
      this.clearPlayInterval()
      // 验证是否已经启动插件
      if (!this.oWebControl) {
        this.initPlugin()
        // 设置计时器 1s执行一次 验证初始化是否执行成功,
        this.playInterval = setInterval(() => {
          if (this.initSuccess) {
            this.clearPlayInterval()
            this.startPlay()
          }
        }, 1000)
      } else {
        // 需要判断播放流数量是否一致,不一致需要重设布局
        setTimeout(() => {
          this.setLayout()
          this.showWnd()
          this.startPlay()
        }, 300)
      }
    },
    setLayout() {
      this.oWebControl.JS_RequestInterface({
        funcName: 'setLayout',
        argument: JSON.stringify({
          layout: this.getHKPlayLayout(),
        }), // 窗口布局
      })
    },
    startPlay() {
      this.currentCameraIndexCodes.forEach((x, index) => {
        var cameraIndexCode = x.cameraIndexCode //获取输入的监控点编号值,必填
        var streamMode = 0 //主子码流标识:0-主码流,1-子码流
        var transMode = 1 //传输协议:0-UDP,1-TCP
        var gpuMode = 0 //是否启用GPU硬解,0-不启用,1-启用
        var wndId = index + 1 //播放窗口序号(在2x2以上布局下可指定播放窗口)

        cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, '')
        cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, '')

        this.oWebControl.JS_RequestInterface({
          funcName: 'startPreview',
          argument: JSON.stringify({
            cameraIndexCode: cameraIndexCode, //监控点编号
            streamMode: streamMode, //主子码流标识
            transMode: transMode, //传输协议
            gpuMode: gpuMode, //是否开启GPU硬解
            wndId: wndId, //可指定播放窗口
          }),
        })
      })
    },

    /**
     * 显示错误提示
     */
    showErrorTipsHandle(message) {
      this.showErrorTips = true
      this.errorMessage = message
    },

    /**
     * 消息回调
     */
    cbIntegrationCallBack(oData) {
    //  console.log(oData)
      /*showCBInfo(JSON.stringify(oData.responseMsg))*/
    },
    /**
     * 获取公钥
     * @param callback
     */
    getPubKey(callback) {
      this.oWebControl
        .JS_RequestInterface({
          funcName: 'getRSAPubKey',
          argument: JSON.stringify({
            keyLength: 1024,
          }),
        })
        .then((oData) => {
          if (oData.responseMsg.data) {
            this.pubKey = oData.responseMsg.data
            callback()
          }
        })
    },
    /**
     * RSA加密
     * @param value
     */
    setEncrypt(value) {
      var encrypt = new JsEncryptModule.JSEncrypt()
      encrypt.setPublicKey(this.pubKey)
      return encrypt.encrypt(value)
    },

    /**
     * 关闭播放链接
     */
    disconnect() {
      if (this.oWebControl != null) {
        // this.oWebControl.JS_HideWnd() // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
        this.oWebControl.JS_Disconnect().then(
          () => {
            // 断开与插件服务连接成功
            console.log('断开与插件服务连接成功')
          },
          () => {
            // 断开与插件服务连接失败
            console.log('断开与插件服务连接失败')
          }
        )
      }
    },

    /**
     * 清楚播放监听任务
     */
    clearPlayInterval() {
      if (this.playInterval) {
        clearInterval(this.playInterval)
        this.playInterval = undefined
      }
    },

    /**
     * 获取播放器layout
     */
    getHKPlayLayout() {
      const length = this.currentCameraIndexCodes.length
      switch (length) {
        case 0:
          return '1x1'
        case 1:
          return '1x1'
        case 2:
          return '1x2'
        case 3:
          return '1+2'
        case 4:
          return '2x2'
        case 5:
          return '1x4'
        case 6:
          return '1+5'
        case 7:
          return '3+4'
        case 8:
          return '1+7'
        case 9:
          return '3x3'
        case 10:
          return '1+9'
        default:
          return '4x4'
      }
    },

    /**
     * 弹窗关闭
     */
    closeHandle() {
      this.clearPlayInterval()
      if (this.oWebControl) {
        this.hideWnd()
        // 停止所有预览
        this.oWebControl.JS_RequestInterface({
          funcName: 'stopAllPreview',
        })
      }
    },
    /**
     * 显示播放窗口
     */
    showWnd() {
      this.oWebControl.JS_ShowWnd()
    },
    /**
     * 隐藏播放窗口
     */
    hideWnd() {
      this.oWebControl.JS_HideWnd()
    },
  },
  beforeDestroy() {
    this.disconnect()
    this.clearPlayInterval()
  //  console.log('>>>>>>beforeDestroy')
  },
}
</script>

其中引入的文件 UUID.js

// On creation of a UUID object, set it's initial value
function UUID() {
  this.id = this.createUUID();
}

// When asked what this Object is, lie and return it's value
UUID.prototype.valueOf = function () {
  return this.id;
}
UUID.prototype.toString = function () {
  return this.id;
}

//
// INSTANCE SPECIFIC METHODS
//

UUID.prototype.createUUID = function () {
  //
  // Loose interpretation of the specification DCE 1.1: Remote Procedure Call
  // described at
  // http://www.opengroup.org/onlinepubs/009629399/apdxa.htm#tagtcjh_37
  // since JavaScript doesn't allow access to internal systems, the last 48
  // bits
  // of the node section is made up using a series of random numbers (6 octets
  // long).
  //
  const dg = new Date(1582, 10, 15, 0, 0, 0, 0);
  const dc = new Date();
  const t = dc.getTime() - dg.getTime();
  const tl = UUID.getIntegerBits(t, 0, 31);
  const tm = UUID.getIntegerBits(t, 32, 47);
  const thv = UUID.getIntegerBits(t, 48, 59) + '1'; // version 1, security version is 2
  const csar = UUID.getIntegerBits(UUID.rand(4095), 0, 7);
  const csl = UUID.getIntegerBits(UUID.rand(4095), 0, 7);

  // since detection of anything about the machine/browser is far to buggy,
  // include some more random numbers here
  // if NIC or an IP can be obtained reliably, that should be put in
  // here instead.
  const n = UUID.getIntegerBits(UUID.rand(8191), 0, 7)
    + UUID.getIntegerBits(UUID.rand(8191), 8, 15)
    + UUID.getIntegerBits(UUID.rand(8191), 0, 7)
    + UUID.getIntegerBits(UUID.rand(8191), 8, 15)
    + UUID.getIntegerBits(UUID.rand(8191), 0, 15); // this last number is two octets long
  return tl + tm + thv + csar + csl + n;
}

//
// GENERAL METHODS (Not instance specific)
//

// Pull out only certain bits from a very large integer, used to get the time
// code information for the first part of a UUID. Will return zero's if there
// aren't enough bits to shift where it needs to.
UUID.getIntegerBits = function (val, start, end) {
  const base16 = UUID.returnBase(val, 16);
  let quadArray = [];
  let quadString = '';
  let i = 0;
  for (i = 0; i < base16.length; i++) {
    quadArray.push(base16.substring(i, i + 1));
  }
  for (i = Math.floor(start / 4); i <= Math.floor(end / 4); i++) {
    if (!quadArray[i] || quadArray[i] === '')
      quadString += '0';
    else
      quadString += quadArray[i];
  }
  return quadString;
}

// Replaced from the original function to leverage the built in methods in
// JavaScript. Thanks to Robert Kieffer for pointing this one out
UUID.returnBase = function (number, base) {
  return (number).toString(base).toUpperCase();
}

// pick a random number within a range of numbers
// int b rand(int a); where 0 <= b <= a
UUID.rand = function (max) {
  return Math.floor(Math.random() * (max + 1));
}

// end of UUID class file

export default UUID;
rsa加密文件jsencrypt.js 可以npm install jsencrypt 引入

在这里插入图片描述
hkplayer-resize.js

/* eslint-disable */

const hkPlayerResize = {
  mounted () {
    const { playerContainerId, width, height } = this
    // 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
    $(window).resize(() => {
      if (this.oWebControl != null) {
        this.oWebControl.JS_Resize(width, height)
        if ($('#' + playerContainerId).get(0)) {
          this.setWndCover()
        }
      }
    })

    // 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动
    $(window).scroll(() => {
      if (this.oWebControl != null) {
        this.oWebControl.JS_Resize(width, height)
        if ($('#' + playerContainerId).get(0)) {
          this.setWndCover()
        }
      }
    })
  },
  methods: {
    setWndCover () {
      const { oWebControl, playerContainerId, width, height } = this
      var iWidth = $(window).width()
      var iHeight = $(window).height()
      var oDivRect = $('#' + playerContainerId).get(0).getBoundingClientRect()

      var iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0
      var iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0
      var iCoverRight = oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0
      var iCoverBottom = oDivRect.bottom - iHeight > 0 ? Math.round(oDivRect.bottom - iHeight) : 0

      iCoverLeft = iCoverLeft > 1000 ? 1000 : iCoverLeft
      iCoverTop = iCoverTop > 600 ? 600 : iCoverTop
      iCoverRight = iCoverRight > 1000 ? 1000 : iCoverRight
      iCoverBottom = iCoverBottom > 600 ? 600 : iCoverBottom

      oWebControl.JS_RepairPartWindow(0, 0, 1001, 600) // 多1个像素点防止还原后边界缺失一个像素条
      if (iCoverLeft !== 0) {
        oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600)
      }
      if (iCoverTop !== 0) {
        oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop) // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
      }
      if (iCoverRight !== 0) {
        oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600)
      }
      if (iCoverBottom !== 0) {
        oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom)
      }
    }
  }
}

export default hkPlayerResize

hkplayer-init-args.js 文件

const args = () => {
  return {
    //API网关提供的appkey
    appkey: undefined,
    //API网关提供的secret
    secret: undefined,
    //API网关IP地址
    ip: undefined,
    //播放模式(决定显示预览还是回放界面)
    playMode: undefined,
    //端口
    port: undefined,
    //抓图存储路径
    snapDir: undefined,
    //紧急录像或录像剪辑存储路径
    videoDir: undefined,
    //布局
    layout: undefined,
    //是否启用HTTPS协议
    enableHTTPS: undefined,
    //加密字段
    encryptedFields: undefined,
    //是否显示工具栏
    showToolbar: undefined,
    //是否显示智能信息
    showSmart: undefined,
    //自定义工具条按钮
    buttonIDs: undefined,
  }
}

export default args()

vant 组件弹出框把视频弹出

<a-modal
      :title="'视频监控-' + modalTitle"
      @cancel="detailClose"
      :maskClosable="false"
      width="1048px"
      :footer="null"
      :visible="detailDrawer"
    >
      <h-k-player ref="hkPlayerRef" :cameraIndexCodes="testCameraIndexCodes"></h-k-player>
    </a-modal>
    

这样就可以了,没有测试过,有需要的自己在摸索一下吧!!!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值