前文描述了WebRTC视频直播技术,后续应用到系统中,版本已经做出来了并封装了JS的SDK,实时性效果还是非常令人惊喜的,针对部分调整和问题进行记录。
视频源
项目使用的是海康摄像头,我打算取消本地服务器,直接让摄像头通过GB28181协议进行推流。为了让所有用户可以观看,将服务部署在公网,当然这里需要考虑NAT问题,部署在在公网与摄像头直连,基本可以忽略NAT问题,根据协议标准,摄像头主动注册到服务,服务发起SIP INVITE请求,SDP协商之后进行RTP推流。这里GB28181/2016支持RTP over TCP机制,但是我没有选用,主要还是为了考虑实时性,另外摄像头推流的数据是PS流,需要自己解码成H264裸流。
播放服务
获取并得到H264裸流,采用前文的WebRTC技术进行直播,信令采用WebSocket通信,ICE通道我取消了之前采用的pjnath库,自己开发了对应库实现该功能,使得功能更可控。RTP通过FuA打包,然后libsrtp加密发送。通过实测发现以下问题:
- 摄像头主码流H264的SPS中有缩放矩阵参数,而Chrome浏览器不支持,但是360浏览器支持。尝试通过将SPS中的缩放矩阵取消,Chrome浏览器可以正常播放,但是视频出现微弱的花纹。最终尝试配置摄像头的编码复杂度改为中等之后,基本在1080P模式下播放无问题。
- 丢包问题。由于1080P的视频量非常大,因此RTP经常出现一毫秒好多包,程序基本不太可能全部接收到,因此部分包丢失了,导致视频偶尔花屏,Chrome浏览器经常就画面卡死(360可以恢复)。最终通过NALU方式确认,确保NALU完整再打包发送解决,并且轻微的丢包在最终展现的画面上很难觉察(这也是为什么音视频通信采用UDP的原因)。
- 海康摄像头推的RTP的时间戳不正确,最好手动计算,否则录制保存文件有问题。
- 因为我还没做音频处理,因此抓包分析过音视频,WebRTC端是复合流,并不需要发起两个ICE。
关于直播性能
在我本机测试的时候,性能主要和视频的高清以及播放用户有关系,在我本机百分之十几的CPU占用可以播放几十路,当然Chrome播放高清版本时候开十几个标签基本就已经扛不住了,想测试也很难测试。不过针对项目的应用场景,更多的是要支持大量的摄像头,而非特别多的用户。