Simulcast 是实时音视频通信中的一种带宽优化技术,发送端同时编码并发送多个不同分辨率的视频流(如1080p、720p、360p),接收端根据自身网络带宽、设备性能和显示区域大小,动态选择最合适的流进行接收和解码。
在多人视频会议场景中,Simulcast多流传输解决了一个核心矛盾:不同参与者的网络状况和观看需求差异很大。有人用高端电脑连着千兆光纤,有人用老手机连着不稳定的4G;有人需要全屏观看某个发言者,有人只是看缩略图。如果所有人都接收同样的高清流,低端设备和弱网用户会卡顿;如果统一降到低清,高端用户的体验又会变差。
Simulcast多流传输通过让每个接收端按需选择流,在不增加发送端网络负担的前提下,让所有参与者都能获得与自身条件匹配的最佳体验。本文将详细介绍Simulcast多流传输的技术原理、WebRTC中的实现方式,以及在实际应用中的优化策略。
一. 多人会议遇到的问题
10人视频会议,每个人都在发送自己的视频流。如果A用1080p推流,其他9个人都要接收A的1080p流吗?理论上可以,但可能存在这类情况,如B可能在手机上看会议,屏幕小,1080p和720p在手机上看不出太大区别,却要消耗更多流量和解码资源;C的网络带宽不够,接收1080p会卡顿;D在会议软件里把A的画面缩小成了缩略图,只占屏幕的1/9,根本不需要1080p的清晰度。
但如果A为了照顾网络最差的人,统一降到360p推流,那些网络好、屏幕大、需要看清楚细节的人就会觉得画面太糊。
这个矛盾在传统方案里不好解决。A只能推一路流,要么高清(部分人卡顿),要么低清(部分人不满意),没法让所有人都满意。
Simulcast的思路是:A同时推送多路流(1080p、720p、360p)。网络好的接收1080p,网络一般的接收720p,网络差的或者只看缩略图的接收360p。每个人各取所需。
二. Simulcast多流传输的工作原理
发送端编码多路流
发送端的摄像头采集到原始画面后,编码器会把这一帧画面编码成三个不同分辨率的版本。
假设原始画面是1920×1080,编码器会输出:
- 高分辨率流:1920×1080,码率约2Mbps
- 中分辨率流:1280×720,码率约1Mbps
- 低分辨率流:640×360,码率约300Kbps
三路流的内容完全相同,只是分辨率和码率不同。它们会被分别打包成RTP数据包,通过网络发送给服务器(通常是SFU)。
三路流不是独立编码的。如果完全独立编码,编码器需要做三次完整的编码工作,CPU开销会非常大。实际实现中,编码器会先编码高分辨率流,然后基于高分辨率流的编码结果,通过降采样和参数调整生成中、低分辨率流。这样计算量会小很多。
SFU的选择性转发
SFU接收到A发来的三路流后,并不是把三路流都转发给每个接收者。SFU会根据每个接收者的订阅请求,选择转发哪一路。
B在手机上看会议,订阅了A的720p流,SFU就只转发720p给B;C的网络带宽不够,主动降级订阅了360p,SFU就转发360p给C;D把会议窗口最大化,正在全屏观看A的画面,订阅了1080p,SFU就转发1080p给D。
SFU本身不做任何编解码工作,只是根据订阅关系做数据包的路由转发。所以即使同时有上百个接收者,SFU的计算压力也不会太大。
接收端的动态切换
接收端的订阅不是固定的,可以随时切换。
D原本在全屏看A的1080p流,后来把窗口缩小了,客户端检测到显示区域变小,会自动向SFU发送新的订阅请求,改为订阅720p。SFU收到请求后,停止转发1080p,改为转发720p。
C原本网络很差只能看360p,后来连上了Wi-Fi,网络变好了,客户端检测到下行带宽充足,会升级订阅到720p甚至1080p。
这种切换是平滑的。客户端会先订阅新的流,等新流的数据开始到达并成功解码后,再取消订阅旧流。这样不会出现画面中断的情况。
三. WebRTC中的Simulcast多流传输实现
SDP协商
Simulcast不是WebRTC的专利,但WebRTC标准对Simulcast有完整的定义和支持。
在WebRTC连接建立过程中,通过SDP(Session Description Protocol)来协商Simulcast能力。
发送端在SDP的Offer中声明自己支持Simulcast,并列出准备发送的流的信息:
a=ssrc-group:SIM 1111111 2222222 3333333
a=ssrc:1111111 cname:user@example.com
a=ssrc:2222222 cname:user@example.com
a=ssrc:3333333 cname:user@example.com
这里的三个SSRC(Synchronization Source)分别代表高、中、低三路流。SIM标记表示这三路流是Simulcast关系——内容相同,只是质量不同。
接收端(或SFU)在SDP的Answer中确认支持Simulcast,并可以指定自己希望接收哪些流。
RID(Restriction Identifier)
WebRTC引入了RID机制来标识Simulcast中的不同流。发送端可以给每路流分配一个RID:
a=rid:h send
a=rid:m send
a=rid:l send
a=simulcast:send h;m;l
这里h、m、l分别代表高、中、低分辨率流(high、medium、low)。接收端在订阅时可以直接指定RID,比SDP中冗长的SSRC描述更简洁。
编码参数设置
在浏览器中使用WebRTC API时,可以通过RTCRtpSender的setParameters方法配置Simulcast的编码参数:
javascriptconst sender = pc.getSenders()[0];
const params = sender.getParameters();
params.encodings = [
{ rid: 'h', maxBitrate: 2000000, scaleResolutionDownBy: 1 },
{ rid: 'm', maxBitrate: 1000000, scaleResolutionDownBy: 2 },
{ rid: 'l', maxBitrate: 300000, scaleResolutionDownBy: 4 }
];
sender.setParameters(params);
scaleResolutionDownBy参数控制分辨率降低的倍数。如果原始分辨率是1920×1080,scaleResolutionDownBy: 2会输出960×540,scaleResolutionDownBy: 4会输出480×270。
maxBitrate限制每路流的最大码率。这个值不是固定的,实际码率会根据网络状况动态调整,但不会超过这个上限。
四. Simulcast vs SVC
技术原理的区别
除了Simulcast,还有一种技术叫SVC(Scalable Video Coding,可伸缩视频编码),也能实现类似的效果。两者有什么区别?
- Simulcast是编码多路独立的流。高、中、低三路流可以独立解码,互不依赖。
- SVC是在一路流中嵌入多个质量层级。基础层(Base Layer)包含低分辨率的画面,增强层(Enhancement Layer)包含额外的信息,把基础层提升到更高分辨率。解码时,只解码基础层可以得到低分辨率画面;解码基础层+增强层可以得到高分辨率画面。
带宽消耗
- Simulcast的发送端需要同时发送三路流,虽然有编码优化,但总上行带宽还是会比单路流高。假设高清流需要2Mbps,中清流1Mbps,低清流300Kbps,总上行带宽大约3.3Mbps。
- SVC只发送一路流,基础层+所有增强层的总码率可能是2.5Mbps左右。上行带宽压力比Simulcast小。
但实际情况是,如果网络中只有部分接收者需要高清,Simulcast可以只让这些接收者订阅高清流,其他人订阅低清。而SVC必须发送完整的基础层+增强层,即使某些接收者只需要基础层,增强层的数据也已经占用了发送端的上行带宽。
编码效率和兼容性
- SVC的编码效率稍差一些。同样的视觉质量,SVC编码的数据量可能比Simulcast的独立编码稍大。
更关键的问题是兼容性。Simulcast基于标准的H.264或VP8/VP9编码,所有设备和浏览器都支持。SVC需要编解码器的特殊支持,H.264的SVC扩展(H.264/SVC)和VP9的SVC模式并非所有平台都支持。硬件编解码器对SVC的支持尤其有限。
实际应用中的选择
- 目前主流的RTC服务大多使用Simulcast。WebRTC默认支持Simulcast,实现成熟,兼容性好。
- SVC在某些特定场景下有优势,比如单向直播(主播推一路流,观众根据网络状况解码不同层级)。但在多人会议这种双向互动场景中,Simulcast更灵活。
五. 多人会议中的优化策略
Simulcast不是开启就完事了,实际应用中还有很多优化空间。
按显示区域动态订阅
会议软件通常会有不同的布局模式:演讲者模式(一个大画面+多个小缩略图)、宫格模式(所有人平铺)、画廊模式(滚动查看)。
在演讲者模式下,正在发言的人的画面被放大显示,其他人是小缩略图。这时候应该订阅发言者的高分辨率流,其他人的低分辨率流。
用户切换到宫格模式,每个人的画面都是中等大小,这时候可以把所有人的订阅都调整到中分辨率。
这种切换需要客户端实时监测UI布局变化,计算每个视频画面在屏幕上的实际显示尺寸,动态调整订阅。
带宽自适应
客户端的下行带宽是有限的。10人会议,如果每个人都订阅1080p,总下行带宽需要18Mbps。如果用户的网络只有10Mbps下行,根本接收不过来。
客户端需要做带宽预算。先估算可用的下行带宽,然后分配给每路流。优先保证当前正在看的画面(大画面)是高清,其他画面降级到中清或低清。
当检测到下行带宽不足时,自动降级部分流的订阅。可能会把所有缩略图从720p降到360p,或者暂停某些不在屏幕可视区域的视频(比如滚动到屏幕外的参与者)。
关键帧请求优化
Simulcast中的三路流虽然内容相同,但关键帧(I帧)的生成是独立的。如果接收端从订阅720p切换到1080p,需要等待1080p流的下一个关键帧到达才能开始解码。
为了减少切换延迟,客户端在切换订阅时可以向发送端发送PLI(Picture Loss Indication)或FIR(Full Intra Request),请求立即生成一个关键帧。
但频繁请求关键帧会增加发送端的编码负担,也会占用更多带宽(关键帧的数据量远大于预测帧)。需要平衡切换流畅性和编码效率。
优先级控制
并非所有参与者的视频都同等重要。在一个会议中,正在发言的人、被pin(固定显示)的人、主持人,他们的视频优先级更高。
当带宽受限时,可以优先保证高优先级参与者的视频质量。降级或暂停低优先级参与者的视频。
有些RTC系统会根据音频活跃度自动判断优先级。正在说话的人(音频能量高)优先级提升,长时间静音的人优先级降低。
六. 发送端的编码挑战
Simulcast对发送端的要求比单路流高。
CPU和功耗
编码三路流的计算量比编码一路流要大,即使有编码优化,CPU占用也会明显增加。
在桌面电脑上这可能不是问题,但在手机上,CPU占用增加意味着耗电增加、发热增加。发热会导致CPU降频,编码性能下降,可能出现帧率下降甚至编码失败。
移动端的优化策略包括:只在需要时启用Simulcast(比如检测到有接收者订阅了低分辨率流),默认只编码一路;降低低分辨率流的帧率(比如高清30fps,低清15fps),减少编码负担;利用硬件编码器的多流编码能力(部分芯片支持同时编码多路流)。
上行带宽
虽然三路流的总码率经过优化,但上行带宽消耗还是会比单路流高。
如果发送端的上行带宽不够,强行发送三路流会导致丢包和延迟增加。这时候系统应该自动降级:只发送两路流(高+低),或者降低高分辨率流的码率。
一些实现会动态调整Simulcast的配置。网络好的时候发三路流,网络变差时停掉中分辨率流,只保留高和低两路,进一步变差就彻底关闭Simulcast,只发一路流。
编码器的限制
并非所有编码器都能高效支持Simulcast。
软件编码器(如libvpx、openh264)可以灵活配置多路流,但性能一般,CPU占用高。
硬件编码器性能好、功耗低,但能否同时编码多路流取决于芯片的支持。部分硬件编码器不支持Simulcast,或者支持的路数有限(比如只能同时编码两路)。
WebRTC会优先尝试使用硬件编码器,如果硬件不支持Simulcast,会自动降级到软件编码器。开发者也可以根据设备性能手动选择编码策略。
七. SFU的优化
SFU在Simulcast方案中承担选择性转发的工作,看起来简单,但实际实现也有很多细节。
流的缓存和切换
当接收端请求切换订阅(比如从720p切换到1080p)时,SFU不能立即停止转发720p。
因为网络传输有延迟,SFU停止转发720p后,客户端可能还要几十毫秒才能收到最后几个720p的包。如果此时1080p的数据还没到达(因为SFU也需要时间开始转发1080p),客户端会出现短暂的画面冻结。
优化的做法是SFU在开始转发1080p后,继续转发720p一小段时间(比如200ms),等1080p的数据稳定到达客户端后,再停止转发720p。这样切换过程是无缝的。
带宽估计
SFU需要估计每个接收端的下行带宽,才能智能地选择应该转发哪路流。
如果接收端主动上报自己的带宽状况(通过RTCP的REMB消息或Transport-CC反馈),SFU可以直接使用这个信息。
但如果接收端没有上报,或者上报的信息不准确,SFU需要自己做带宽估计。常见的方法是监测发送给该接收端的数据包的丢包率和延迟。如果丢包率上升或延迟增加,说明带宽不足,SFU可以主动降级转发的流。
负载均衡
大规模会议中,SFU的负载可能成为瓶颈。
假设100人会议,每个人都发送三路流,SFU需要接收300路流。如果每个人都订阅其他99人的视频,SFU需要转发的流数量是惊人的。
实际应用中会有优化:接收端不会真的订阅所有人的视频,只订阅当前屏幕上可见的(比如宫格模式下一屏显示9个人,只订阅这9个);SFU可以做分层架构,多个SFU节点协同工作;对于超大规模会议(数百人),可能会用MCU做部分流的混合,减少转发量。
八. 实际应用中的权衡
Simulcast不是在所有场景下都是最优选择。
在小规模会议(3-5人)中,Simulcast的收益有限。参与者少,每个人的画面都可以显示得比较大,大家的订阅需求差异不大。这时候启用Simulcast反而增加了发送端的编码负担和上行带宽消耗。
在网络环境很好的场景下(比如企业内网),所有参与者的带宽都很充足,设备性能也不错,也没必要用Simulcast。统一用高清流,简单高效。
Simulcast的价值在中大规模会议(10人以上),且参与者的网络和设备差异较大的场景。这时候不同人的订阅需求确实不同,Simulcast能显著提升整体体验。
另一个需要考虑的是移动端。手机的上行带宽、CPU性能、电池续航都比较有限。如果会议中有很多移动端用户,可能需要针对移动端做特殊配置:只编码两路流而不是三路,或者降低帧率减少编码负担。
声网RTC SDK支持大小流(双流)功能。SDK默认开启小流自适应模式,即按需发送小流,当有接收端订阅小流时才开始发送。开发者可以根据场景需求,选择始终发送小流、始终不发送小流,或保持自适应模式。开发者还可以通过API自定义大流和小流的分辨率、帧率、码率等参数。
总结
Simulcast多流传输通过让发送端编码多个分辨率的流,接收端按需选择,解决了多人会议中参与者网络和需求差异的问题。
WebRTC对Simulcast有完整的支持,通过SDP协商、RID标识、编码参数配置,可以灵活实现多路流的发送和接收。
相比SVC,Simulcast在兼容性和灵活性上有优势,是目前多人会议应用的主流选择。
实际应用中,需要根据显示区域、带宽状况、参与者优先级等因素动态调整订阅策略。发送端要平衡编码性能和上行带宽,SFU要做好流的选择和转发优化。
Simulcast不是万能的,在小规模会议或网络环境均匀的场景下,单路流可能更简单高效。技术选型需要根据实际业务场景做权衡。