因为在直播中,H5侧目前主要是B站的 flv.js
这个项目来做FLV的直播,但是H5原生支持MP4,而且SRS等均只输出简单的FLV视频。因此可以考虑尝试使用直接输出MP4的方法来实现,这样就可以跳过很多控制,直接原生支持,结果验证失败了。
测试前思考
想要输出MP4,势必先要了解MP4的格式,然后再remux,CSDN的这篇博客是我的主要参考
作者主要是从事类似 flv.js
这样通过JS进行的转换操作,我只需要用C++实现格式即可。
通过简单了解,大概可以确认直接使用MP4格式是不行的,因为在MP4的开始的 moov
就记录了视频的所有帧,显然在直播中是不行的。好在MP4还有一种格式,号称是适应网络的,流式的,也就是我们所说的FMP4格式。显然在直播服务器上需要实时生成视频文件,只能选择FMP4格式。
编写测试程序
编写测试程序没什么好说的,参照上面的博客进行实现即可。但是有两点需要注意:
- 每个box的大小是包含开始的size在内的
turn
记录的包大小也是包含size在内的
程序流程就是在开始先获取到 AVCDecoderConfigurationRecord
解析出SPS,并且从SPS中解析出宽高后就开始合成 ftyp
和 moov
, 后面就一直合成 moof
和 mdat
对即可。
因为我面对的是视频监控,直接忽略音频相关,相对会少一些工作量。
程序测试
花两三天就搞定测试程序,测试程序通过HTTP进行输出,在调试阶段通过 curl
工具保存文件,然后使用桌面播放器进行播放,确认合成的格式是正常的。如果有问题,配合 MP4 Reader
这个工具进行解析分析。
测试正常之后,开始通过H5的 <video>
标签进行播放,F12 进行查看。可以发现以下现象和问题:
- 视频无法播放,一直在等待
- 视频有两次下载,第一次仅下载非常小的量
- 视频第二次一直下载,不结束
- 停止服务器端,视频开始正常播放
通过以上现象,基本可以分析得出浏览器是通过下载整个视频进行播放的,这和流式不流式没什么关系。然后再在HTTP服务器上放一个通过工具转码的FMP4文件,可以发现浏览器分块下载播放,也不是流式的。
总结分析
MP4不能直播,至少现阶段浏览器是不支持的!
至于现在流行的H5的MSE方法,我没有写过代码,但是听说其有一些限制。
- 浏览器支持不一致(问题不太大)
- 必须使用FMP4格式封装输入
- 每次必须一个GOP输入(未确认)
- 音视频格式有限制(问题不大)
如果想要使用H5直播,现阶段最简单的方案就是 flv.js
,而且FLV文件本身格式比MP4简单太多,浏览器也不支持MP4直播,还不如使用简单的FLV格式。
另外还有就是WebRTC直播,不过技术含量有些高以及其他一些原因,没有大量普及。不过虎牙已经在使用了,而且貌似是P2P。