导读:2020 年,新冠疫情暴发并席卷寰球,对包含中国在内的寰球经济造成了微小的冲击,同时深刻影响了社会生存。在这一背景下,以消费市场上轰轰烈烈的直播电商为引爆点,直播行业再次掀起热潮。在中国企业数字化转型的浪潮中倒退了十年之久的企业直播服务市场,也趁势进入高速倒退阶段。
文|洪顺迪 网易云信流媒体 Server 端研发工程师
1 典型的直播架构
在典型的直播架构中,右边是推流客户端,协定上才采纳 RTMP 上行;左边是拉流客户端,反对不同的拉流协定拉流,比拟常见的是:RTMP、FLV、HLS
1.1 现有架构的长处
这套框架很好的利用了 CDN 厂商或者说云厂商的能力。只管拉流协定没有对立,rtmp/flv/hls 等拉流协定作为比拟成熟的流媒体协定,通过多年的倒退,失去了各 CDN 厂商广泛支持。在云端能力的反对下,服务端并发能力和拉流端减速能力大大增加了,直播行业蓬勃发展。
2 低提早直播的现状
在直播畛域中卡顿和提早就像是天平的两端。提早做的越短,则卡顿越高;提早越长,卡顿就越少。
个别场景下都是客户端用更大的 buffer 时长,就义延时来满足流畅性。随着行业的倒退,某一些利用场景对延时工夫的要求越来越刻薄,比方体育比赛直播,教育场景下老师与学生间的互动等,这些场景下常见的直播流媒体协定的毛病就体现进去了。
个别 rtmp 协定直播延时在 3-10s,如果通过层层 CDN 的缓存和转发,超过 10 秒也是常有的事,flv 和 hls 协定的延时更高。就拉流端来说,提早的很大一部分源自网络传输:rtmp 在传输媒体前的 tcp 3 次握手和 c0/c1/c2 握手协定,无端引入了好几个 RTT 的提早;因为 rtmp/flv/hls 的传输层都是基于 tcp 协定,在网络不稳固的状况下,受限于 tcp 协定的拥塞管制不能充分利用网络带宽,客户端为了放弃流畅性,只能加大缓存工夫,因而更进一步加大了提早。\
在意识到现有流媒体直播协定的局限性后,各大友商也纷纷推出了本人的低延时直播,较好的起到了反抗弱网和放慢首屏的作用。但目前大都基于公有的信令协定和公有的 UDP 流媒体传输协定,各大云厂商无奈相互兼容,这就限度了低提早直播的大规模倒退。
3 基于规范 WebRTC 的低提早直播的开源实际
网易云信始终在摸索如何做一个凋谢的低延时直播计划, 未来各家云厂商也可能比拟不便的实现,就像现有的 rtmp/hls 协定一样,推动整个直播行业低提早化。要实现这种计划须要做以下两件事件。
- 凋谢的信令协定: 信令协定须要满足绝大多数厂商的媒体协商需要,同时又能尽可能的简洁。
- 凋谢的媒体协定: 媒体传输协定须要满足在各大厂商间可能通用,在这之上的 QoS 能力也须要凋谢,不能是公有的。
根据下面的要求咱们抉择了 RTC 畛域成熟的解决方案——WebRTC。下图是咱们当初的实际架构。
上图中 WE-CAN 是网易云信的寰球减速 RTC 大网,媒体在 Server 间的网络传输依赖 WE-CAN。
边缘媒体服务器从 CDN 拉流到 WE-CAN 大网边缘节点,再从 WE-CAN 大网边缘节点发送给客户端。
3.1 开源的信令协定实现
信令协定 上采纳 HTTP+SDP 的形式, 即客户端 POST 一个 SDP Offer。
{
...
"pull_stream": "nertc://your.domain.com/live/testname"
"sdp": "v=0\r\no=4611731400430051336 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\n......",
"type": "offer"
}
而后媒体服务器通过协商返回 SDP Answer。
{
...
"code": 200
"sdp": "v=0\r\no=4611731400430051336 10000 1 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=ice-lite\r\n......",
"type": "answer"
...
}
3.2 规范的 WebRTC 媒体协定
客户端拿到 SDP Answer 后,就是规范的 WebRTC 媒体交互流程:ICE、DTLS 加密连贯,接管 RTP 流媒体。
上面是一个根本的 Web 端的拉流代码 Demo:
self.pc = new RTCPeerConnection(null);
self.pc.addTransceiver("audio", {direction: "recvonly"});
self.pc.addTransceiver("video", {direction: "recvonly"});
var offer = await self.pc.createOffer();
await self.pc.setLocalDescription(offer);
var session = await new Promise(function(resolve, reject) {
var data = {
pull_stream: streamId,
type: "offer",
sdp: offer.sdp
};
$.ajax({type: "POST", url: apiUrl, data: JSON.stringify(data),
contentType:'application/json', dataType: 'json'
}).done(function(data) {resolve(data);
});
});
await self.pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: session.sdp})
);
3.3 开源的 Native 媒体播放器
为了让 Native 客户端可能更不便的接入 WebRTC,咱们同样开源了一个集成了规范 WebRTC 的低提早直播播放器:We-Can-Player,只有输出流地址,就能实现接管 WebRTC 流播放。
3.4 客户端的架构:
只有厂商实现了相似的协定,用这个播放器稍作批改就能够拉到 WebRTC 的流。从架构上能够看出媒体服务器和拉流客户端之间的交互大都是基于规范的 WebRTC,没有公有的 RTP 扩大和公有的 QoS 协定, CDN 厂商甚至能够没有本人的 RTC 大网,只需在 CDN 边缘节点实现规范的 WebRTC 网关 + 一个简略的 HTTP Server 就能够领有同样的能力。
为了优化直播体验,咱们还在 Server 端做了大量的优化。
4 优化直播体验
4.1 首屏优化
4.1.1 GOP 缓存首屏优化
直播畛域有两大指标:首屏和流畅性。 假如用户推流端的 GOP 的是 5 秒,在某些状况下,拉流端要等靠近 5 秒能力收到第一个 I 帧,首屏能力渲染。这对直播来说是不可承受的。
解决方案是在媒体服务器里做 Gop 缓存,缓存最近 1 - 2 个 Gop 的媒体包在 Server 端,当客户端和媒体器媒体连贯胜利当前,先发送 Gop 缓存外面的媒体包,再发送以后的媒体数据。客户端收到媒体包后,须要依据肯定的策略对齐音视频包,再减速追帧。
在具体的实际过程中,要留神 Gop 缓存大小、客户端的 Jitter buffer 大小的配合、Gop 缓存里音视频的对齐、不同的推流端不同的 Gop 长度的适配等状况。
4.1.2 Pacer 平滑发送
如果推流端设置的 Gop 比拟大,当拉流客户端媒体连贯胜利后,会一股脑的给客户端发送全副的 Gop 里数据,可能造成客户端缓冲溢出以及其余问题。这时候就须要 Server 的 Pacer 平滑发送发挥作用了。
在具体的实际过程中,要留神 Pacer 的追帧速率与客户端追帧速率的配合。
4.2 提早优化
4.2.1 WE-CAN 大网
前文提到了直播行业之所以能蓬勃发展,在技术方面 CDN 厂商的云端能力起到了很大的推动作用。CDN 放慢了边缘节点的回源速度,边缘节点又放慢了拉流终端的接入速度。
从下面的架构图能够看到,为了放慢回源速度,回源媒体服务的抉择会尽可能的靠近 CDN 的区域核心节点;为了优化客户端的接入性能,拉流媒体服务器也要尽可能的靠近拉流客户端,因而媒体 如何迅速地从回源媒体服务传输给拉流媒体服务就至关重要。
而 WE-CAN 就承担了这个职责, 他是云信外部开发的一套高效寰球传输大网,能减速寰球任何两个媒体服务器之间的网络传输。从某种意义上来说,他起到了推动 CDN 减速传输的作用,不过 CDN 的原理是层层 cache,WE-CAN 靠的是门路优化。
4.2.2 全 SFU 架构的媒体服务器
构想两个主播的互动,如果咱们退出 MCU 的话必然会引入缓存,导致首屏和提早都加大,所以 RTC 大网外部都是基于 SFU 架构做的布局。
4.2.3 全链路延时监控
如何全链路的监控拉流测引入的提早? 媒体流在 WE-CAN 大网里通过层层转发,如果任何一段路由引入不必要的提早,就会影响最终的低提早成果。咱们的做法是在 RTP 头里加上一个 extension,记录 RTP 包达到每个机器的毫秒级的 NTP 工夫后,在转发给客户端的最初一个媒体服务器上汇报每跳路由的工夫耗费以及边缘服务器与客户端之间的 RTT 工夫,在最终发给客户端的客户端 RTP 中再剥离这个 extension。只管各机器的 NTP 工夫没有相对对齐,但依赖 WE-CAN 大网的全局 NTP 工夫同步性能,差距可能管制在 1ms,这个精度足够在工程实际中施展监控作用。
5 成果和后续工作
第一阶段在网络 QoS 方面临时只反对 ARQ 和 Opus 的 inband-FEC 能力。因为 WebRTC 原生反对基于 XOR 的 FEC 能力,在抗间断丢包方面很弱,所以临时没有开启 FEC,但较 RTMP 有了微小的改良。实现了在 50% 丢包条件下,管制在 2 秒左右的提早,200~400ms 的首屏。
咱们前面的打算包含:退出更多的 WebRTC 规范 Qos 能力(包含 FEC 在内);推流侧的 WebRTC 革新能力等,具体的开源内容能够继续关注【智企技术 +】公众号,后续咱们会继续更新开源相干内容及开源地址。
作者介绍
洪顺迪,网易云信流媒体 Server 端研发工程师,负责网易云信流媒体 Server 端的开发工作。