1、前言:
WebRTC是一个开放的Web标准,用于支持在浏览器之间的语音、视频和通用数据的双向实时通信。在以Google为首的大厂推动下,WebRTC各项技术逐渐成熟并标准化,成为各种主流浏览器都支持的基于Web的实时音视频通信解决方案。 WebRTC本身是一个应用在客户端的类P2P技术,SRS4.0引入WebRTC处理能力,主要是为了构建服务器的SFU能力(什么是SFU读者可自行搜索)。这里借用一个网图来说明SFU的工作原理:
如上图所示,对于视频会议场景,一般都有多个WebRTC客户端。此时通过部署SFU服务器,每个WebRTC客户端都和SFU服务器之间建立一条针对本地音视频数据的推流连接,同时,WebRTC客户端和SFU服务器之间还可以按需建立多个拉流连接。这样做的好处是即利用了SFU服务器强大的客户端接入能力,又不会在服务端因为音视频混流消耗过多的CPU计算能力。
所以,SRS4.0引入WebRTC能力的主要目的是: 1)支持浏览器无插件的从SRS服务器拉流并直接播放。 2)降低音视频数据的总延时(最低毫秒级延时)。 3)支持双向音视频能力,支持直播连麦场景。
2、目标:
WebRTC包括的知识点非常多,从SDP报文的生成与交换、ICE方式建立连接,DTLS握手/SRTP加解密、RTP/RTCP数据封装与传输,到面对网络抖动、带宽不足时各种提升音视频用户体验的Qos处理,每个知识点涉及的内容都非常多,本章将从WebRTC推拉流连接建立开始,通过分析音视频数据在关键类和关键函数之间的总体流向,先从整体上了解SRS4.0 WebRTC服务器模块的代码逻辑。
3、内容:
3.1 SRS4.0 WebRTC服务启动
SRS WebRTC服务模块的初始化和启动接口在文件srs_app_rtc_server.cpp中,整体处理逻辑包括: 1)生成用于DTLS的自签名证书 2)启动UDP端口(8000)监听,处理STUN/DTLS/RTP报文 3)注册推拉流API接口
srs_error_t RtcServerAdapter::initialize()
{
......
// 此函数内部调用openssl库,生成自签名证书,用于后续的DTLS认证
if ((err = _srs_rtc_dtls_certificate->initialize()) != srs_success) {
return srs_error_wrap(err, "rtc dtls certificate initialize");
}
// 此函数内部订阅5秒定时器的超时消息,通过此消息完成一些周期性工作
if ((err = rtc->initialize()) != srs_success) {
return srs_error_wrap(err, "rtc server initialize");
}
return err;
}
srs_error_t RtcServerAdapter::run()
{
......
// 创建UDP端口监听对象SrsUdpMuxListener,默认监听8000端口
if ((err = rtc->listen_udp()) != srs_success) {
return srs_error_wrap(err, "listen udp");
}
// 向全局SrsHttpServeMux对象注册RTC模块的推拉流API
if ((err = rtc->listen_api()) != srs_success) {
return srs_error_wrap(err, "listen api");
}
// 启动_srs_rtc_manager内部协程,用于清理内部僵尸连接,回收资源
if ((err = _srs_rtc_manager->start()) != srs_success) {
return srs_error_wrap(err, "start manager");
}
return err;
}
前