使用MSE 来扩展实现 HTML5 video tag的流式直播。
- 2019-03-15 15:47:00
- admin 转贴
- 22887
使用MSE(Media Source Extension, 具体参考W3C标准)扩展实现 HTML5 video tag的流式直播。
方案描述: 使用websocket 从服务端传输h264编码数据到浏览器, 在浏览器端使用JS 解析h264数据 , 封装成fMP4 fragment, 喂给media source 中的sourceBuffer, 浏览器video tag自动获取sourceBuffer中的数据进行解码渲染。
最后实现的demo体验效果良好,延时能达到100ms以内,使用笔记本软解、硬解, chrome book 软解表现都很完美,唯独chrome book 硬解会缓冲一帧数据,是一个瑕疵, 不过这个缺点可以在服务器端多发一帧数据解决。
下面主要记录预研过程中出现的重要问题和解决方案:
(1)解析h264数据,封装fMP4 fragment。
这一步比较复杂,由于之前没有JS开发经验,没有选择自己写,在github找了一个开源实现。参考: https://github.com/ChihChengYang/wfs.js; 根据wfs.js搭建的直播方案,主要出现三个问题(只有第一个延时是wfs.js库的问题,其余是自己的问题):
(2)第一个是延时问题,延时很大,在3~5s左右
原因有两个: 1. wfs.js库中做了缓存,收到一定的数据之后才执行fMP4 fragment的封装。
2. chrome浏览器的解码器默认不是以直播流的模式解码视频帧,所以会在解码的时候缓存4帧数据。
解决方法: 1. 把wfs.js库中的缓存去掉,每来一帧数据都执行fMP4 fragment的封装
2. 设置mvhd.duration = 0,如果有mehd的话,设置mehd.fragmentDuration = 0, 这样chrome 会进入“low delay mode”, 不会缓存数据。
具体参考: https://stackoverflow.com/questions/36364943/frame-by-frame-decode-using-media-source-extension
https://bugs.chromium.org/p/chromium/issues/detail?id=465324
(3)第二个就是解码问题,解码花屏
原因: 虚拟机spice服务端使用了websokify代理(python 写的)。首先,这个代理服务器是流式的(出现数据帧被分割和合并的现象),浏览器端js没有进行数据帧边界的解析; 第二,代理缓冲区过小,导致数据帧被分割传输。
解决方法:1. 修改websokify代理的接收缓冲区大小。
2. 在wfs.js库中对收到的数据进行解析,一帧一帧的提交数据,封装fMP4 fragment。
(4)第三是屏幕倒转问题
原因: spice服务端发过来的h264数据就是倒的,在终端平台,是由终端处理的。
解决方法: 利用css的画面旋转功能,以x轴为旋转轴, 旋转180度。如:
<style type="text/css" media="screen">
video.rotate180{
width:100%;
height:100%;
transform:rotateX(180deg);
-moz-transform:rotateX(180deg);
-webkit-transform:rotateX(180deg);
-o-transform:rotateX(180deg);
-ms-transform:rotateX(180deg);
}
</style>
(5)关于chrome book硬解码缓存一帧问题解决办法
通过看chrome源码 decoder部分,发现decoder处理几个数据类型会直接flush缓冲区,所以可以在wfs.js每收到一帧数据,
就构造一帧这种类型的空数据 ag, 把缓冲的一帧flush出来,同时把播放时间缩短一半即可(否则会帧堵塞)。示例:
var copy2 = new Uint8Array(4);
copy2[0] = 0, copy2[1] = 0, copy2[2] = 1, copy2[3] = 10; //类型10,11 都可以,但是10可以兼容软解
this.wfs.trigger(Event.H264_DATA_PARSING, {data: copy2});
[后记]AMS8已经支持WebSocket和flv_over_http,可以通过flv.js或者上面的方法来实现HTML5流式低延迟直播。在AMS8.1版本中,我们将把封装fMP4的操作放到AMS端,通过WebSocket直接发送fMP4给HTML5端,喂给Media Source中的SourceBuffer,来实现直播。HTML5端减轻负担,可以运行在更多环境中.
联系人: | 北极星通公司 |
---|---|
电话: | 010-56545416 |
传真: | 010-82896426 |
Email: | support@bjsin.cn |
QQ: | 35338585 |
微信: | Aoku2017 | QQ群:241759321 |
地址: | 北京市中关村生命科学园创意园3-3-103 |