在实现功能上花了大概1天半左右的时间,其中踩到的三个坑也一一解决了,源码地址贴在最后了
大概需求
最近公司需要的一个需求,实现Web端的监控视频的播放、录制、拍照功能,而给到我的只有一个这么一个链接:
录制和拍照功能都是针对vedio标签的,如果切换到其他标签页或最小化浏览器不能影响视频的正常录制。
播放功能实现
这个是通过一个jswebrtc库实现的,npm地址:www.npmjs.com/package/jsw… ,文档只有一点,使用方法也非常的简单:
参考文档上的:
使用:
new JSWebrtc.Player(
"webrtc://xxx.xx.xx.xxx/live/live/rj5",
{
video: this.$refs.video,
autoplay: true,
}
);
延迟大概在1秒内,webrtc的实时性果然是比较好的
拍照功能实现
这个有了vedio标签能播放之后,利用canvas来拍照好像也不是什么难事了,利用canvas对vedio进行截图,关键代码:
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
let url = canvas.toDataURL();
download(url, "jpg");
canvas直接用js生成,使用drawImage方法,传入video的DOM,然后设置好样式,最后用canvas.toDataURL把canvas变为一个base64的路径然后下载即可,download方法我是使用了a标签下载的,但下载的方法很多这里不详细说了,能下载就行,甚至window.open都可以。
录制功能实现
寻找API:MediaRecorder
由于之前做过一个记录一次express+socket.io+webrtc实现一对一视频通话对视频流有点概念,所以当时主管找到我问这个功能的时候我就能感觉到这个没问题,果不其然找到了个MediaRecorder类,地址:developer.mozilla.org/zh-CN/docs/… ,这个类就是需要传入视频流即可进行录制,大概方向就是这样了。
上图红框内的这句话也确实认证了我的想法,上次的视频通话我做过了navigator.mediaDevices.getUserMedia() 获取MediaStream,但这个来自于video DOM元素的MediaStream就成了我遇到的第一个问题,因为我找了很久的mdn的vedio都没有找到要怎么获取他的MediaStream,直到我放弃了mdn直接百度才找到了这个
let stream = this.$refs.video.captureStream();
功能大概是2022年2月底做的,这文章是3月6日写的,写文章的时候我又去找了一下,发现完全找不到video.captureStream相关的内容,这里就算是做个记录吧,确实这个功能我研究了一天大部分时间都是花在找这个东西上了。
MediaRecorder的使用
主要是两个方法和三个事件
- MediaRecorder.start()
- MediaRecorder.stop()
- MediaRecorder.onstart
- MediaRecorder.onstop
- MediaRecorder.ondataavailable
这里大家应该都能看懂这前四个的作用,这第五个则是一个关键的保存录制内容的事件,具体的逻辑大家大概都能想到了,但在这里我遇到了第二个问题:这个start和stop居然是有点类似异步的方法,start和stop方法调用了并不会立刻就start和stop,他是不是真的异步我不是很清楚,因为mdn文档上完全没提到有异步的字眼,然后百度看到别人的使用也是并没有onstart和onstop两个事件的,也有可能是因为我的是实时的视频流问题导致的,这也是耽误了我大部分时间的一个问题。
这个问题的解决方法也很简单了,把所有start和stop之后的操作全部放到onstart和onstop两个事件的处理函数中就没问题啦。
第三个问题:视频时长不对,录制下来的视频发现进度条不会动,然后把视频发到经理那一看才发现企业微信上显示视频有6w+的时长,进度条会动才有鬼呢,再去看视频的属性-详细信息那一栏,视频的信息基本都是空的,问题就确定下来了,而最后解决则是使用了一个EBML的库来对视频进行了格式转换解决了,地址:www.npmjs.com/package/ebm…
功能展示
这个是第一天做完晚上录制的,视频时长问题还没解决,等解决完想录制时测试的webrtc链接已经被关掉了。但源码是已经解决了这个问题的了,以及写了些看点的样式,可以下载来替换成自己的webrtc链接进行查看。
拍照功能
录制功能