海康——萤石云 web 端视频接入踩坑记录

比小程序开发更累的使用萤石云的 EZUIKit-JavaScript 3.0 来接入海康摄像头视频。因为这两天实在太折腾(还没搞定),所以这篇文章基本是吐槽。

接入方式

web 端萤石云基本是两种接入方式:1. 使用 iframe(EZUIKit-JavaScript-npm 也是 iframe),2. 使用 EZUIKit-JavaScript。

使用 iframe

这种方式使用简单,但是灵活性欠佳,ui 也不忍直视。灵活性欠佳的主要表现是无法自适应。视频内容无法根据外围容器大小自行调整。

使用 EZUIKit-JavaScript

这种方式灵活性较好,但坑也很多。并且也没用发现可以自适应的 api。然后,下面是碰到的几个重大的坑(bug)。

jSPlugin.JS_Play is not a function

其实 jSPlugin 不仅仅是这个报错,只是这个比较典型。官方的 demo 播放是没有问题的,但是,我 react 项目里组件的形式就概率性地报错。看了一下报错的文件——ezuikit.js 的 414 行前后的代码:

/** 创建jSPlugin 对象 */
this.jSPlugin = {};
var _this = this;
/** 根据播放参数获取真实播放地址 */
this.loadingStart();
playStartTime = new Date().getTime();
// var getRealUrl = this.getRealUrl(playParams);
var initDecoder = this.initDecoder(playParams);
// 初始化播放器
_this.loadingSet(0, { text: '初始化播放器...' });
if(playParams.autoplay){
  _this.play()
}
if (isPromise(initDecoder)) {
  initDecoder.then(function (data) {
    _this.loadingSet(0, { text: '初始化完成' });
    // setTimeout(function () {
    //   _this.play(playParams);
    // }, 100)
    // var getRealUrl = _this.getRealUrl(playParams);
    // getRealUrl.then(function (data) {
    //   _this.play(playParams);
    // })
  })
}

其中,_this.play() 执行的时候,jSPlugin 还没有加载完成,应该在 initDecoder.then() 里面调用。然而,这段代码下面有一段注释掉的代码,那段代码看上去却没什么问题。

一个页面只能播放一个视频

官方的多路播放方法并不是我想要的,我想每个组件实例化一个播放器,单独播放相应摄像头的视频。然而,诡异的情况出现了——一个页面只能实例化一个播放器,除第一个播放器外的其他播放器都是黑屏,而第一个播放器会交替播放多个摄像头的画面。

我看了一下 dom 结构,视频是实时画到 canvas 上面的,这没什么问题。问题是,canvas 的 id 是固定的,基本是按照 xxx_xxx_num 这种形式命名的。一个播放器内部多路应该是没有问题的(毕竟官方有这功能),但是多个播放器创建的 canvas 都是同样的 id,这就很不合理。

我寻思着干脆自己改源码好了。打开 jsPlugin-1.2.0.js 文件。嗯……虽然未压缩,但也是打包后的。💔

算了,还是用 iframe 的方式吧。遇到需要自适应的情况就重新渲染吧。

总结

萤石云是太穷还是什么情况,2020 年了,jQuery 也就算了,sdk 各种报错,根本无法正常使用。