问题背景:
无论是实时视频监控还是直播点播等应用场景,最起码的一个操作就是播放视频。其中最基本的思路就是利用OS的API在PC开发桌面应用、在移动端开发Native App,目前这种技术已经成熟,大厂小厂都是这么做的,但是缺点也很明显:开发比较费时费力,需要IOS开发一遍再去Android开发一遍。特别对于一些非刚性需求比如用户家里有一两个监控摄像头,一个礼拜也不会打开看几次,你却要他下载和安装一个APP进行操作,用户安装意愿其实非常低。
随着前端摄像头输出音视频格式逐渐标准化和Web前端技术的迅速发展,我们打算探索在Web浏览器、微信上开发一些轻量级视频监控应用,虽然在Web上开发音视频应用也有很多方案,但是这些技术也都有优缺点和不同的适用场景,本文就是想总结下目前有哪些成熟的解决方案?这些方案的底层原理是什么?其次优缺点是什么?文章最后放了一些参考链接和Git地址,供大家研究和学习,由于本人并不是前端开发人员,勘误地方还望大家多多指正。
实现思路:
方案1:插件化方案
简介:
自从浏览器发明以来,想在Web浏览器上播放视频,基本都是插件化的解决方案,特别是Adobe的Flash技术将插件化技术普及到各种浏览器。插件化的技术基本分三类:基于IE的Active方案、基于Chome的NPAPI接口和基于Flash插件。但是这些插件化方案逐渐都要淘汰了,主要原因如下:
a. 微软IE式微,市场份额不断下降,微软已经在2015年宣布放弃IE浏览器,现在最新的微软浏览器Microsoft Edge将从EdgeHTML内核迁移为Chromium内核。
b. Chrome上的NPAPI也已经宣布放弃,目前要做需要基于PPAPI /NaCl接口,而且只能针对这款浏览器实现。
c. Flash这种技术也在2020年寿终正寝,所有浏览器就默认禁止在上面跑Flash插件了;
所以综上来看,想在Web上利用插件化播放视频这条路在已经走不通了,这种技术由于各种问题的确该抛弃了,作为程序员我们能做的就是给这种技术的淘汰添一把土,果断抛弃和转身吧。
演示效果:
方案2:跨平台的HLSDASH方案
简介:
HLS是Apple首先提出的流媒体分发协议,目前在苹果家族的整个产品都得到了比较好的支持,后来谷歌在Chrome浏览器和移动端浏览器也进行了原生支持,所以目前无论你是在PC还是移动端的浏览器基本都原生支持HLS协议进行播放视频,算是一个在移动端比较好的跨平台方案,同时微信内嵌的浏览器也都是原生支持的。
缺点:
延时比较大,由于HLS协议本身的切片原理,基本延迟都在10秒+,这对于一些低延时场景非常不友好,虽然HLS也在努力优化,但是想达到秒级延迟还是不现实的。
微信小程序演示效果:
方案3:基于HTML5 Video和Audio的MSE方案
MSE即Media Source Extensions是一个W3C草案,其中桌面对MSE的支持比较好,移动端支持缓慢。MSE扩展了HTML5的Video和Audio标签能力,允许你通过JS来从服务端拉流提供到HTML5的Video和Audio标签进行播放。
MSE在各个浏览器的支持情况如下,目前看在PC端的浏览器支持比较友好,但在移动端浏览器支持这个接口目前还处于刚开始。
MSE目前支持的视频封装格式是MP4,支持的视频编码是H.264和MPEG4,支持的音频编码是AAC和MP3,目前编码层的东西摄像机都支持比较友好,问题不大。封装格式的处理目前要么就是从服务端拉裸流过来,在Web前端合成MP4片段进行播放,要么在服务端提前转封装好直接喂给MSE接口,同时由于RTMP协议在CDN场景的大量使用,所以Web前端应该还支持解析FLV然后转成MP4片段,于是就产生了以下技术细类:
3.1方案:HTTP+FLV
简介:
服务端经摄像头拉流转成FLV,然后客户端过来拉流即可,拉过来的流解封装下FLV然后转成MP4片段,再喂给MSE即可。这个事情现在有个开源项目就是bilibili的flv.js已经帮你实现了,你直接利用这个开源项目简单改改,就基本支持起来了,我们已经在用。
缺点:
目前移动端的微信或者Chrome76我已经测试过,开始支持了,但是IOS的Safari浏览器没有支持,所以这个方案暂时在移动端完全支持起来有困难。
演示:
1.PC Web展示效果:
2. 手机微信7.0.4和Android Chrome76演示效果:
3.2方案:WebSocket+FLV
简介:
方案和3.1目前差不多,就是将拉流协议换成Web的原生WebSocket协议而已,拉过来的FLV码流还是可以靠flv.js来进行转封装为Mp4片段,喂给MSE即可,相应的MP4片段也可以在服务端生成,然后直接用WebSocket拉过来即可,也就是3.3方案。
3.3方案:WebSocket+MP4
缺点:
缺点就是要在服务端提前生成好MP4片段,转封装这块工作服务端需要处理好。
3.4方案:WebSocket+RTSP+H.264数据
简介:
因为现在视频监控类设备目前支持最好的拉流协议基本就是RTSP协议,基本都进行了标准支持,因为视频监控领域有一个国际标准就是ONVIF标准,这个标准使用的拉流协议就是RTSP,所以视频监控不支持RTSP,就无法支持ONVIF,在国际就没有市场。
所以要是Web能直接通过RTSP拉流,那就非常友好,想做到这点比较难,因为Web的W3C标准就不支持RTSP协议,曲线救国的方案就是将RTSP协议放到Websocket协议里面进行透传,然后在服务端做一个Websocket到RTSP协议的代理转换协议,这样就可以在Web支持RTSP协议了,对于视频监控领域用户比较友好,一看就是熟悉的味道,相同的道理也可以在Web前端支持RTMP协议,基本的原理如下:
缺点:
需要服务端做相应的协议转换代理,拉过来的码流Web还是要进行相应的转成MP4片段,这些都是不小的开发工作量;
这个也有相应的开源项目,其中Web这边有个html5_rtsp_player开源项目,实现了RTSP客户端功能,你可以利用此框架直接播放RTSP直播流。此播放器把RTP协议下的H264/AAC再转换为ISO BMFF供video元素使用。Streamedian支持Chrome 23+, FireFox 42+, Edge 13+,以及Android 5.0+。不支持iOS和IE。
演示效果如下:
方案4:WebRTC方案
简介:
WebRTC是一整套API,其中一部分供Web开发者使用,另外一部分属于要求浏览器厂商实现的接口规范。WebRTC解决诸如客户端流媒体发送、点对点通信、视频编码等问题。桌面浏览器对WebRTC的支持较好,WebRTC也很容易和Native应用集成。
WebRTC实现了浏览器P2P的实时通信,其中可以通过调用相应的Web API采集视频进行推流,如果放到视频监控,我们可以把这一段在嵌入式摄像头上实现,将摄像机的编码视频数据采集出来,然后直接发送出去即用摄像头模拟P2P的推流端,另外一端在Web浏览器上用相应接口解码和渲染。我们在自家摄像头预研过这套方案,目前看是可以的。延时非常小,播放非常稳定,同时WebRTC目前在跨平台方面支持比较好。
演示效果:
方案5:
WebSocket/HTTP + WebGL/Canvas2D + FFmpeg+WebAssembly
简介:
WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,并为其他语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。近几年已经被各主流浏览器所广泛支持,支持情况:
它的大概原理:
利用这种技术可以将C/C++库进行前端移植,比如WebAssembly 技术可以帮我们把 FFmpeg 运行在浏览器里,其实就是通过 Emscripten 工具把我们按需定制、裁剪后的 FFmpeg 编译成 Wasm 文件,加载进网页,与 JavaScript 代码进行交互。
这样Wasm 用于从 JavaScript 接收WebSocket或者HTTP-FLV 直播流数据,并对这些数据利用FFmpeg进行解码,然后通过回调的方式把解码后的 YUV 视频数据和 PCM 音频数据传送回 JavaScript,并最终通过 WebGL 在 Canvas 上绘制视频画面,同时通过 Web Audio API 播放音频。
缺点:
前端消耗性能还是比较大,Web前端播放H265的1080P视频还是比较吃力的,同时想在前端播放多路视频基本是不现实的,所以这个应用场景还是局限在特殊的应用场景,不能通用。
我们当时的实践是利用这种技术在Web界面播放鱼眼摄像头视频,这种摄像头视频是几路合成的,如果借助原始Web接口是无法播放的,所以播放器解码必须是我们自己C++写的,然后借助WebAssembly技术允许js接口调用解码播放。
效果演示:
总结:
目前在web浏览器上想播放音视频主要的技术大类就是上面四种:
1. 插件化的技术虽然可以实现各个浏览器的播放音视频,但是即将淘汰;
2. HLS/DASH浏览器虽然原生支持,跨平台比较好,但是延时太大,对于低延时领域不适用;
3. 基于MSE的技术,虽然可以大大降低延时,适用直播和点播,但是苹果系列产品目前还未完全支持,只能部分使用;
4. 基于WebRTC技术,非常适用于实时视频,但是开发量比较大,对于视频监控等低延时交互领域有点杀鸡焉用牛刀的感觉,而且技术处于快速发展阶段,很多还不成熟,对于小公司有一定的门槛;
5. 基于WebAssembly将C/C++音视频解码库前端移植化,这个在一些特殊应用场景可以使用比如浏览器要播放H265音视频,但是弊端是前端跑起来比较重,渲染不了几路视频,性能优化还有待提升,但是是可以突破浏览器和操作系统接口的隔阂。
所以目前来看想在Web上做音视频操作,浏览器的原生支持还远远不够,相比较开发APP还是缺乏一定的灵活性,不仅有一定的限制而且需要兼容处理的事情非常多,想一招解决你的需求还是有困难,所以还是需要上述几种技术综合搭配使用来解决Web播放音视频需求。不过后面相信浏览器会在这方面突破,毕竟5G要来了,浏览器厂商会加紧布局。
本篇文章参考网址和项目:
https://github.com/ty6815
https://github.com/gwuhaolin/blog
https://github.com/Streamedian/html5_rtsp_player
https://github.com/bilibili/flv.js
https://mp.weixin.qq.com/s/EC8Yd74HEoIO2QxJe8-iNQ
https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/96405736
https://www.jianshu.com/p/1bfe4470349b
-End-