RTMP转RTC;或者RTC转RTMP,是通过Bridger实现的。
RTMP转RTC
class SrsRtcFromRtmpBridger : public ISrsLiveSourceBridger
RTMP推流
创建RtcFromRtmpBridger
在acquire_publish函数中:
if (rtc_server_enabled && rtc_enabled && !info->edge) {
if ((err = _srs_rtc_sources->fetch_or_create(req, &rtc)) != srs_success) {
return srs_error_wrap(err, "create source");
}
if (!rtc->can_publish()) {
return srs_error_new(ERROR_RTC_SOURCE_BUSY, "rtc stream %s busy", req->get_stream_url().c_str());
}
}
判断配置文件中是否配置并开启了RTC服务,还需要当前服务不是Edge类型节点的服务。如果条件都满足,会根据RTMP推流的req信息(application和streamname)获取或创建SrsRtcSource对象rtc。
if (rtc) {
SrsRtcFromRtmpBridger *bridger = new SrsRtcFromRtmpBridger(rtc);
if ((err = bridger->initialize(req)) != srs_success) {
srs_freep(bridger);
return srs_error_wrap(err, "bridger init");
}
source->set_bridger(bridger);
}
创建SrsRtcFromRtmpBridger的桥接对象bridger,使用RTMP推流的req信息初始化bridger,其中包括初始化音频转码,从AAC转Opus。最后将bridger设置进SrsLiveSource* source中,供后续接收到音视频数据时使用。
RTMP接收推流线程
SrsPublishRecvThread rtrd(rtmp, req, srs_netfd_fileno(stfd), 0, this, source, _srs_context->get_id());
err = do_publishing(source, &rtrd);
创建接收RTMP推流的线程并启动。
线程创建的过程:
graph TD
SrsPublishRecvThread--构造函数初始化trd-->B[SrsRecvThread trd]
B --创建SrsDummyCoroutine-->C[SrsDummyCoroutine trd]
线程启动
RTC转RTMP
class SrsRtmpFromRtcBridger : public ISrsRtcSourceBridger