0x01 Simulcast
Simulcast就是多播,在多人会议中,有时候大家网络状况并不相同,Simulcast能适配不同用户的网络和终端情况。
举个例子,3个人,有的是1Mbps网络,有的是2Mbps,有的是5Mbps。大家该推多少码率的流?
•如果推2Mbps的流,两个人会很Happy画质清晰很流畅,但是那个网络差的人就挂了,整个会议也开不下去。
•如果照顾比较差的网络,大家推1Mbps或更低码率的流,其他网络很好也只能看低码率的流,明明网络很好画质却很差。
Simulcast就是这个问题的解决方案之一,客户端只需要推一路流,但在服务器转发时(不用视频转码),可以出不同的码率的流,客户端根据自己的网络选择合适的流。
- 大家全部推3Mbps码率的一路流。
- 带宽只有1Mbps的客户端,就拉1Mbps的流,虽然画质不清楚,但是很流畅,可以正常开会。
- 带宽很好的客户端,可以拉3Mbps的流,流畅而且画质很好。
0x02 WebRTC Simulcast
WebRTC 的 Simulcast , 在一个视频媒体行(MediaLine)中存在多个视频流(RTP Stream), 这些流来自相同的视频采集源, 其差别主要体现在视频编码,分辨率,码率等方面。
在 WebRTC 内部, Simulcast 会为每一个视频流分配一个编码器, 不同的编码器生成不同大小的码流, 这些码流经服务端转发, 最终达到用户播放器。
不过与普通单流转发不同, 因 Simulcast 推送多个码流的特点, 服务器可以为不同用户调度不同的码流。
比如, 考虑到播放端用户的 带宽 和 设备分辨率 的差异, 可以给部分用户推送高清码流, 另一部分推送低清码流.
代价是 推送端 需要更大的带宽, 更强的算力, 应付多码流的输出.
目前 WebRTC 源码为 Simulcast 提供了两种接口的API
- SDP munging 风格
- RID based 风格
SDP 示例
// SDP munging 风格
a=ssrc-group:SIM 1390104252 1390104253 1390104254
// RID based 风格
a=rid:high send
a=rid:mid send
a=rid:low send
a=simulcast:send high;mid;low
0x03 SDP munging 风格特点
1. 特点
SDP munging 风格的 Simulcast 接口体现在sdp协商时,其视频媒体行会出现 a=ssrc-group:SIM 字样,其格式为
a=ssrc-group:SIM layer0 layer1 layer2...
其中 SSRC 序列 即为 Simulcast 的多个层级, 序列长度通常不超过3.
它们按照分辨率大小从小到大依次排列; 假定 layer0 的分辨率为 w0xh0, 其他类推, 则:
分辨率满足:
layer0(w0xh0) < layer1(w1xh1) < layer2(w2xh2) ...
长宽比率满足:
w0 : w1 : w2 = 1: k: k^2
h0 : h1 : h2 = 1: k: k^2
(通常k = 2, 如果是源码开发,可自行修改)
2. 示例
一份offer的某个视频媒体的部分片段
a=ssrc-group:FID 1390104252 2798384649
a=ssrc:1390104252 cname:rsPDymoMnGBuVXTx
a=ssrc:1390104252 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc:2798384649 cname:rsPDymoMnGBuVXTx
a=ssrc:2798384649 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc-group:FID 1390104253 2798384650
a=ssrc:1390104253 cname:rsPDymoMnGBuVXTx
a=ssrc:1390104253 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc:2798384650 cname:rsPDymoMnGBuVXTx
a=ssrc:2798384650 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc-group:FID 1390104254 2798384651
a=ssrc:1390104254 cname:rsPDymoMnGBuVXTx
a=ssrc:1390104254 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc:2798384651 cname:rsPDymoMnGBuVXTx
a=ssrc:2798384651 msid:ez0lPBqQZbbAN0ImN4ZrrUCbshr2khvkB6ob 99528680-68d8-418b-afc6-205372e9cb6f
a=ssrc-group:SIM 1390104252 1390104253 1390104254
3. 解释
根据这个片段可以推测, 这个sdp里面视频媒体行是一个同播3个码流的 Simulcast
low: 1390104252
mid: 1390104253
high: 1390104254
0x04 参考
- https://www.meetecho.com/blog/simulcast-janus-ssrc/ https://webrtchacks.com/not-a-guide-to-sdp-munging/
- https://github.com/fippo/simulcast-playground https://fippo.github.io/simulcast-playground/ https://webrtchacks.com/a-playground-for-simulcast-without-an-sfu/
- 一份 SDP munging 风格 Simulcast 的 sdp
https://gist.github.com/johzzy/067dd46a1222bf211f79aef5bcf4cd3a