一、背景目标
视频会议系统与微信小程序的live-pusher和live-player标签互通,而底层需求是webrtc与rtmp进行互通。
二、业务流程架构
微信信令sdk
live-pusher ---> ---> --->
媒体接入网关 视频会议SFU RTC客户端
live-player <--- <--- <---
- 媒体接入网关实现rtmp和rtc协议的转换
- rtmp需要独立的信令sdk
其中rtmp和webrtc系统互通,核心依赖的是媒体接入网关方案。
三、媒体接入网关方案
实现功能依次如下:
- rtmp协议接入
- rtmp进行mux和demux,解析出音视频的ES数据
- 音频aac和opus转换---主要性能消耗
- 视频avcc和AnnexB格式转换
- 视频时间戳同步到音频上
- webrtc协议接入
其中微信sdk需要通过url记录rtc的room房间信息,媒体接入网关维护url和webrtc媒体流的映射关系,信令sdk支持双向通信,可以接收rtc新加入用户的sfu消息通知。
3.1 音频编码转换
微信小程序推上来的rtmp解析的音频aac流,无adts头
ffmpeg的aac三方库libfdk_aac无adts头
ffmpeg的aac自带库有adts头
3.2 视频封装转换
rtmp的h264格式是avcc
webrtc的h264格式是AnnexB
3.3 音视频同步
问题如下:
- 时间戳计量单位不同,webrtc采用的采样点计算音频时间戳,rtmp是本地系统UTC时间
- 微信启动前1秒、网络切换和app前后台切换时,rtmp时间戳计算不准确,有跳变,需要调整
调整方法是从rtmp的flv文件里,读取Video Tag和Audio Tag,然后判断时间戳大于阈值,然后统一调整到较大的时间戳上。
3.4 I帧适配
rtmp需要固定I帧间隔,所以媒体接入网关定时1秒,向sfu发生FIR关键帧请求,以解决gop长度不统一,rtc音视频先于rtmp请求等首帧和卡顿的问题。
3.5 性能优化
在nginx-rtmp-module、librtmp或者livego的开源实现基础上,进行两个优化
- 合并多个IO指令为一个IO指令,减少IO次数
- 建立内存池
然后再通过srs的 srs-benchmark进行压力测试,可以得到cpu、内存的实际负载效果。
四、结果验证
rtmp到rtc链路延迟500ms-800ms左右,而且由于rtmp是基于tcp链路,抗弱网能力较差,需要结合live-player的快放功能、自适应码率等功能优化。
另外,rtmp没有over tls协议,需要优化为rtmp over quic,提升系统的安全性。
附录
adts头:0x0FFF分割adts单元,7字节的头,包含声道数、采样率和长度等信息,可以与LATM头进行封装转换
avcc格式:
([extradata包括sps、pps等]) | ([length 4字节] NALU) | ([length 4字节] NALU) | ...
AnnexB格式:
[0x00 00 00 01] NALU(sps)
| [0x00 00 00 01] NALU(pps)
| [0x00 00 00 01] NALU(h264 实际负载) |...