如果你最近遇到了需要接入海康平台的监控设备这种业务场景,但是又头疼不知道该如何接入到自己的系统,不妨看看本文,也许对你有帮助。
首先访问海康云眸提供的开发者文档:视频对接指南
目前海康云眸提供了监控画面的六种接入方案,而且每种接入方案都做了说明,并阐明了此方案的优缺点。
如果你是做 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 // 意外断开回调
});
这里的 iServicePortStart
和 iServicePortEnd
的值是硬编码的,猜测是之前安装的 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)),
});
这里具体不再阐述,官方文档有更为详细的说明。
结尾
- 海康云眸提供了 3 种 web 端的视频接入方案,其中最推荐的是使用 UiKit 方案接入,跨端,简便,但需要将监控设备迁到萤石平台。
- Web 视频控件接入复杂且繁琐,仅用于 Windows 系统,如果客户不需要考虑 MacOS 可以尝试此接入方案。