前言
SRS4.0
支持将RTMP
流转换成RTC
流,本文将结合源码分析下这个过程。
配置
首先,需要在SRS4.0
的启动配置文件里面开启RTC Server
和RTC
能力,可以参考官方提供的配置文件./trunk/conf/rtmp2rtc.conf
,对应配置项如下:
RTC Server
配置:
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
candidate $CANDIDATE;
}
RTC
配置,RTC
配置是在vhost
项下开启的
vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
rtc_to_rtmp on;
}
}
源码分析
接下来具体分析下rtmp2rtc
的源码
-
在
SrsRtmpConn
类中的acquire_publish
方法中判断是否开启了rtc
功能,如果开启了,则会为该路流创建一个SrsRtcSource
实例,用来管理一路rtc
流
-
创建
rtmp2rtc
的bridger SrsRtcFromRtmpBridger
用于将rtmp
的音视频packet
转封装成rtc
需要的packet
。将前面创建的SrsRtcSource
实例传递到bridger
中,并且初始化bridger
, 随后将该bridger
注册到管理一路rtmp
流的SrsLiveSource
实例中。 -
bridger
初始化,在bridger
的初始化函数分别初始化了SrsRtmpFormat
和SrsAudioTransCoder
实例,SrsRtmpFormat
实例用于解析rtmp
流的音视频tag
,SrsAudioTransCoder
实例用于将音频编码格式转换成webrtc
需要的opus
格式。 -
接下来看下
SrsLiveSource
里面是怎么调用bridger
的,SrsLiveSource
主要在四个地方调用了bridger
。将音视频包透传到bridger
中,将[un]publish
状态传递到bridger
中。on_publish
,在SrsLiveSource
的on_publish
函数中会调用bridger
的on_publish
函数,而bridger
的会做一些逻辑校验以及调用SrsRtcSource
的on_publish
函数,并且清除meta(video/audio sequence header)
缓存
on_unpublish
,unpublish的处理逻辑和publish
的差不多,meta
数据不清除,并且缓存当前(video/audio sequence header
),代码如下,不再赘述
-
on_audio
处理逻辑bridger
通过on_audio
收到音频数据包时,通过SrsRtmpFormat
实例对音频数据进行解tag
和解封装,丢弃掉非AAC
编码的音频数据包,并且给AAC raw
数据增加ADTS
头
- 将增加
ATDS
头的音频数据保存到SrsAudioFormat
中,调用SrsAudioTranscoder
实例将AAC音频数据转码成OPUS音频数据,将转码后的音频数据打包成RTP packet
,透传给SrsRtcSource
。
-
on_video
处理逻辑bridger
首先判断视频数据是不是h264
序列头,如果是则缓存它
-
通过
SrsRtmpFormat
实例解析视频数据tag
和封装
-
过滤视频数据,根据配置过滤B帧,因为
RTC
不支持B
帧
-
对于
IDR
帧,首先按照rtp STAP-A
的打包方式打包SPS/PPS
数据递交到SrsRtcSource
-
如果开启了
merge nalu
,则将所有NALU
合并成一个NALU
,并且打包到一个RTP
或者FUA packet
中
-
未开启
merge nalu
,则一个NALU
对应一个RTP packet
,单个NALU
大于最大的RTP packet
负载(webrtc default: 1200
)则使用FUA packet
,打包完成后则投递到SrsRtcSource
中
总结
SRS4.0
rtmp2rtc
的流程包括:首先创建一个rtmp2rtc
的bridger
,这个bridger
包含一个管理rtc
流的SrsRtcSource
实例, 将这个briger
注册到管理rtmp
流的SrsLiveSource
实例中,SrsLiveSource
收到的所有rtmp tag
都将投递一份到这个bridger
,这个bridger
负责将rtmp tag
数据解析和转码(AAC2OPUS
),并且按照配置打包成rtp packet
投递到SrsRtcSource
中。