海康云眸 web 视频控件接入教程指北

如果你最近遇到了需要接入海康平台的监控设备这种业务场景,但是又头疼不知道该如何接入到自己的系统,不妨看看本文,也许对你有帮助。

首先访问海康云眸提供的开发者文档:视频对接指南

目前海康云眸提供了监控画面的六种接入方案,而且每种接入方案都做了说明,并阐明了此方案的优缺点。

如果你是做 Web 端的监控设备接入,并且要支持回放和实时预览,可选的方案就三种:

  • Web 视频控件
  • 标准流
  • UIKit

标准流这里我们就直接 ❌ 了,不通过的原因是此方案不需要换平台的 accessToken 就能播放客户的视频,而且 HLS 编码的视频设备不能看回放,不符合我们的业务场景。

剩下的就是 Web 视频控件方案和 UIKit。

这里笔者强烈建议使用 UiKit 接入方案,不仅支持 Npm 方式下载,还能跨平台播放,并且文档清晰明了。

这种方案需要将客户的监控设备接到萤石平台,因为走的是萤石的协议,调的是萤石的 API,但是这种方案需要付费,因为萤石的开放平台是根据接入设备的数据按月收费。

但是本文主要讨论的是 Web 视频控件接入方案,所以 Uikit 接入方案不再阐述。

Web 视频控件方案仅支持在 Windows 系统内的浏览器播放

安装

找到官方提供的 jsWebControl.min.js 这个脚本的下载链接,点击下载并安装下载目录内的 exe 可执行文件,拷贝其中的 jsWebControl.min.js 放到你的项目工程目录。

假设你的项目是用的 Vue.js,请把该脚本 copy 到你的项目的 public 目录下(如果公司有搭建 CDN 服务,放到 CDN 服务器上更好),并在 index.html 引入该脚本。

html 复制代码
<script src="web-control_1.2.5.min.js"></script>

当然官方也提供了 es module 版本的 jsWebControl.js, 访问海康开放平台,点击下方红色方框内的立即下载按钮(你需要登录网站后才能点击下载按钮,可以手机号验证码一键登录)。

下载并解压后,在 demo 目录就能找到 jsWebControl.esm.min.js

接着在业务文件内直接导入即可使用:

js 复制代码
import { WebControl } from "@/utils/web-control.esm.min";

相比起使用非模块化的 js 的控件脚本,esm 版本的控件脚本能够让我们在开发时得到智能提示,开发体验更友好。

如果你的项目是用的 Typescript 进行开发,你只需要使用 InstanceType 即可享受 WebControl 的实例类型智能提示。

接入

对着文档的接入教程,首先需要创建 WebControl 实例,

js 复制代码
oWebControl = new WebControl({
    szPluginContainer: 'playWnd', // 与控件关联的dom节点id
    iServicePortStart: 14510, // 对应 LocalServiceConfig.xml 中的ServicePortStart值
    iServicePortEnd: 14519, // 对应 LocalServiceConfig.xml 中的ServicePortEnd值
    cbConnectSuccess, // 成功回调
    cbConnectError, // 失败回调
    cbConnectClose // 意外断开回调
  });

这里的 iServicePortStartiServicePortEnd 的值是硬编码的,猜测是之前安装的 WebControl 控件的运行端口。虽然在视频播放时,控制台会打印无法访到该端口,但是不影响视频播放。

创建实例后,需要进行 init 操作,init 操作必须在 cbConnectSuccess 的回调函数内完成,否则会 init 失败。

初始化播放器示例

js 复制代码
this.oWebControl = new WebControl({
    szPluginContainer: id,
    iServicePortStart: 14510, 
    iServicePortEnd: 14519,
    // 控件连接成功的回调
    cbConnectSuccess: async () => {
        this.oWebControl?.JS_SetWindowControlCallback({
            cbIntegrationCallBack: (oData: any) => {
             if (oData.responseMsg.eventName === "FireOcxVersion") {
                    //  判断 eventName 为 FireOcxVersion 时,可以确保初始化操作成功 
                    const args = {
                    // ....
                    }
                     this.oWebControl!.JS_RequestInterface({
                        funcName: "Init",
                        arguments: encodeURI(JSON.stringify(args)),
                     })
             }
            },
        });
        await this.oWebControl?.JS_StartService("window", { dllPath: "./chain/cloudTransform.dll" });
        await this.oWebControl?.JS_CreateWnd(id, width, height);
    },
});

由于 Web 控件方案的初始化参数有太多的 options,我第一次看文档被这些 options 搞得头皮发麻。

其实文档列出的这些参数大部分都是非必填参数,而且很多参数并没有在文档内作说明。

下面这段示例是我认为初始化播放器所必须要传递的一些参数。

js 复制代码
const args = {
    // 平台的 accessToken,调用接口得到
    token: options.accessToken,
    response: {
      code: 0,
      message: null,
      data: {
          // 账号的 appkey
          appKey: options.appKey,
          // 播放画面的 token
          ezvizToken: options.token,
          // -1 会弹出声音确认框,为 0 时默认声音关闭,为 1 是默认声音开启
          OpenWndsVolume: 1,
          // 默认取流清晰度,0:流畅,1:均衡,2:高清,3:超清
          videoLevel: 0,
          // 如果要隐藏控件自带的工具栏,传 0
          showMainTool: 0,
          showSubTool: 0,
      }
  }
}

// oWebCotnrol.JS_RequestInterface 函数返回的都是一个 Promise.
await this.oWebControl!.JS_RequestInterface({
     funcName: "Init",
     arguments: encodeURI(JSON.stringify(args)),
})

init 成功后后并不代表就能播放画面了,只是界面上已经成功创建了播放控件,接下来还需要调用 StartPreview 方法才能开始拉流播放。

预览画面示例

同样的,预览画面也需要配置预览入参

js 复制代码
const previewArgs = {
    response: {
        code: 0,
        message: null,
        data: {
            // 摄像头的设备序列号
            deviceSerial: options.deviceSerial,
            // 摄像头的名称
            channelName: options.channelName,
            // 摄像头的通道号
            channelNo: options.channelNo,
            // 同摄像头的通道号
            channelCode: options.channelNo,
            // 设备是否开了加密
            codeIsEncrypt: 0,
            /**
             * @description 协议类型,0:海康协议,1:国标协议
             */
            deviceClass: "0",
        },
    },
};

await this.oWebControl!.JS_RequestInterface({
    funcName: "StartPreview",
    arguments: encodeURI(JSON.stringify(previewArgs)),
});

调用成功后,你的视频窗口正常情况下已经出现了加载画面。

如果播放失败,最好找硬件工程师确定通道号和设备是否加入到海康平台,并设备已上电。

网络正常的情况下界面上就能看到监控设备的实时画面。

我在第一次成功接入海康控件的时候遇到过一个偶发 bug,当我切换到其他 tab 页面或者关闭浏览器后,海康视频窗口会一直位于屏幕的正前方,不会被关闭也不会被销毁销毁,像似粘在了屏幕上一样。

原因是在浏览器内看到的视频画面并非是页面 DOM 树的一个元素节点呈现的。而是安装的海康指定的可执行文件程序与浏览器通信后由类似于 QT 这样的 GUI 程序,在确定好 DOM 容器在屏幕的位置后,指定位置绘制出来的界面。

这种 bug 的解决办法只能通过监听当前页面的 visibilitychange 事件来控制视频控件的显隐。

js 复制代码
useEventListener(document, "visibilitychange", () => {
    if (document.hidden) {
        this.oWebControl.JS_HideWnd();
    } else {
        this.oWebControl.JS_ShowWnd();
    }
});

如果要切换路由,必须得销毁当前创建的视频播放控件,否则控件会一直停留当前 tab。

销毁控件示例

js 复制代码
   onBeforeUnmount(() => {
       this.oWebControl.JS_DestroyWnd();
       this.oWebControl.JS_StopService("window");
       this.oWebControl.JS_Disconnect()
   });

海康的监控回放和预览接口操作大同小异,仅入参新增了开始时间和结束时间,以及调用操作方法名不同。

js 复制代码
// 回放入参
const recArgs = {
    response: {
        code: 0,
        message: null,
        data: {
            deviceSerial: options.deviceSerial,
            channelNo: options.channelNo,
            channelName: options.channelName,
            // 格式为 YYYY-MM-DD HH:mm:ss
            startTime: options.startTime,
            endTime: options.endTime,
            isEncrypt: 0,
        },
    },
};

this.oWebControl!.JS_RequestInterface({
    funcName: "StartPlayback",
    arguments: encodeURI(JSON.stringify(recArgs)),
});

这里具体不再阐述,官方文档有更为详细的说明。

结尾

  1. 海康云眸提供了 3 种 web 端的视频接入方案,其中最推荐的是使用 UiKit 方案接入,跨端,简便,但需要将监控设备迁到萤石平台。
  2. Web 视频控件接入复杂且繁琐,仅用于 Windows 系统,如果客户不需要考虑 MacOS 可以尝试此接入方案。
相关推荐
永乐春秋3 分钟前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿4 分钟前
【前端】CSS
前端·css
ggdpzhk6 分钟前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
学不会•2 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜5 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点5 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow5 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o5 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā6 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue