超大规模会议技术优化策略 轻松实现 500 人线上流畅沟通
但是 500 人同时线上开会,对于资源消耗比较高。而传统的 WebRTC 架构并不擅长超过 200 人以上的会议场景。在面对超大规模会议室、聊天室、直播等各种复杂场景时,对流进行按需合流,可以降低带宽占用和设备压力;对流进行有选择的订阅分发,有助于扩展各种组合场景。针对 App 具体的应用场景,可以配合订阅分发模式,组合使用 SFU 和 MCU 架构。下来我们将详细分析一下大规模会议的资源优化策略。
1.超大规模会议架构对比
SFU 方式灵活,只要降低带宽就可以实现大规模会议的要求。
2.超大规模会议中存在的挑战
这里我们来对比一下 20 人与 200 人同时参加音视频会议时,对服务端造成压力的差距:
20 人
各端流量:
20*(1Mbps+32Kbps)=20.64Mbps
服务端上行流量:
20*(1Mbps+32Kbps)=20.64Mbps
服务端下行流量:
20*(20-1)*(1Mbps+32Kbps)=392.16Mbps
200 人
各端流量:
200*(1Mbps+32Kbps)=206.4Mbps
服务端上行流量:
200*(1Mbps+32Kbps)=206.4Mbps
服务端下行流量:
200*(200-1)*(1Mbps+32Kbps)=41.07Gbps
从对比结果中可以看出,服务端下行流量直接上升了一个量级。如果采用视频按需订阅,音频选择出音量最大的几路可以大大降低下行流量。比如每个客户端订阅 4 路视频,服务器只需下发 4 路音量最大的音频,服务端下行流量只需要 200*4*(1Mbps+32Kbps)=800+25.6=825.6Mbps,可以极大缓解服务器压力。
若要解决上面的问题,建议通过按需订阅与转发、音频流量两个方面来制定策略,在保证效果的前提下,降低服务端的压力。
3.按需订阅与转发以及音频流量优化策略
按需订阅与转发的方式有:
➀支持单独订阅某个人的某路视频或某路音频。
➁接收端仅订阅正在说话的人的视频,音频全部订阅。
➂融云 SDK 支持发送端视频编码支持大小流。接收端按需订阅大流或小流。大流的清晰度高,码率高;小流的清晰度低,码率低。这样当接收端想观看清晰视频的时候订阅大流;对清晰度要求不高的时候订阅小流。另外,弱网下自动切换大小流,可以保证视频的流畅性。
3.2 音频流量优化策略
针对音频全部订阅有以下几种优化音频流量的方法。
3.2.1 发送端静音时不发送数据
3.2.2 调整音频码率
通过设置客户端上音频码率,降低客户端上行的音频码率。当音频路数跟多的时候,限定每一路的音频码率后,总的音频码率会减少很多。SDP 设置方式 b=AS:码率。下面是摘自 RFC3556 的原文:
3.2.3 服务器下发音量 Top N 路
客户端收到音频流,在音频解码后,默认一般仅混流播放音量最大的 3(WebRTC 中的 kMaximumAmountOfMixedAudioSources 值)路声音。所以避免不必要的音频包的转发可以减少服务流量的。步骤如下:
➀发送端通过 Audio Level 标识音频能量。
➁音频包进入 SFU 转发队列,先进入计算队列,定期弹出 Top N 的音频包。
➂只有有效音频包,会进入到下行分发队列。
下面介绍音频如何转发音量最大几路的方法实践。
4. 音频 Top N 选择
4.1 客户端处理
客户端会计算出音量大小,并把值记录在 RTP 包中。所以客户端需要开启 audio-level 的 RTP 扩展, 如下: a=extmap:1urn:ietf:params:rtp-hdrext:ssrc-audio-level 开启这个 RTP 扩展后,WebRTC 客户端机会计算 audio 包的音量大小。这个音量大小计算方法 RFC6464 有明确定义。WebRTC 中的计算方法为 modules/audio_processing/rms_level.cc 的 ComputeRms 方法:
客户端告诉服务器音频包的音量大小。服务器收到音频包后不用做解码,就能知道从客户端上来的音频包的音量值,为后面的服务器音频包下发策略奠定了基础。
4.2 服务器处理
下面用 Publisher 表示发布者的音频流,Subscriber 表示订阅者的音频流。RtpAudioPacket 表示一个音频包。RtpAudioPacket 里有个 mute 属性,标记这个音频包时是否静音。
在没有音频根据音量大小转发的逻辑前,Publisher 和 Subscriber 的处理关系如下。
Subscriber1、Subscriber2、Subscriber3 订阅 Publisher1、Publisher2、Publisher3。Publisher 发上来的音频包都会转发给各自的订阅者。
音频根据音量大小转发的逻辑如下:
➀AudioLevelHandler 表示每个 Publisher 的音频处理单元。AudioLevelHandler 里有两个音频包缓冲队列,计算队列 calculate_queue 和发送队列 send_queue。Publisher 的音频包先进入计算队列 calculate_queue 中。有个定时计算任务 AudioLevelCalculator。AudioLevelCalculator 会每隔一个音频打包时间 ptime 进行一次对所有 Publisher 的计算队列里音频包的 audio_level 均值(因为均值表示这个 Publisher 收到的若干个音频包的音量)做排序计算,选出音量值最大的几路。这几路的音频包 RtpAudioPacket 的 mute 被标记为 false,而其他音频包标记为 true。
➁排序后,这些音频包会从计算队列里移入到发送队列 send_queue 中。
➂之后音频包从 send_queue 出队,转发给 Subscriber。Subscriber 中的 MuteHandler 有以下两个作用:
a. 根据 RtpAudioPacket 的 mute 属性,mute 为 true 时,这个音频包直接被吞掉,false 表示转发给订阅者。
b. 因为下发给订阅者的音频包 RTP 序号 SeqNum 不是连续的,需要做连续化处理。
下面图中 Subscriber1、Subscriber2、Subscriber3 订阅 Publisher1、Publisher2、Publisher3。假设 Publisher1 收到的当前音量最大,最终只有它的音频包会转发给 Subscriber1、Subscriber2、Subscriber3。
4.3 级联的考虑
比如下面的图中,Subscriber4 通过级联服务器连接到当前 MediaServer 上。Publisher1、Publisher2、Publisher3 的音频包都会直接转发级联服务器。由级联服务器负责计算 Top N 音频包的计算下发给 Subscriber4。
下面是这部逻辑的伪代码:
4.4 音频下发策略优化
现实中人的说话是有停顿的。比如停顿前后人声比较大,如果简单的排序下发音频包,客户端会收到连续的非静音包。经测试,这样的体验并不理想,因此需要加入平滑处理。这里 history 为过去若干次的音频是否进入 Top N。音频包是最大的几路中的,加入 history 队列尾部加入 true,转发表示此次声音大而发。否则,加入 history 队列尾部加入 false。因为本次静音,还需判断过去的静音情况,若 history 中有 true 值,转发可表示过去一小段说过话,所以需要转发。若 history 中全为 false, 不转发则表示本次声音不大,过去一小段声音也不大,所以不转。
4.5 其他相关策略
➀当会议中的人数相对比较的少的时候,音频包为上面所述的正常转发。而当多个 Publisher 的订阅人数超过某个阈值(比如 50),此时 MediaServer 发的音频码率很大,对应客户端也要收相应的音频流量。这时可以走超大会议音频最大几路转发逻辑。而当会议中多个 Publisher 的订阅人数下降到阈值之下,再回归正常的转发逻辑。
➁经过选取最大几路流的下发方式,音频流量已经大大降低了。而在此基础上实际设置的选取路数做少许冗余,可以多发一些有音量的音频包,提高接收方体验。
➂当参会者增加时,相应的 MediaServer 也需要动态调度。通过把参会者音视频流打到多个 MediaServer 上,通过级联的方式解决问题,保证每台 MediaServer 服务器上的 CPU、内存、带宽的正常。
5. 总结
以上是基于超大规模会议技术优化进行的策略方面的探索。其主要思想是视频按需订阅,音频降低不必要的流量。其中涉及客户端音量值的上传、服务器端音量选择、级联、优化体验、减少音频流量等多个方面。研发过程中,超大会议需要多测试,才能暴露其中的问题,从而提高最终的会议体验。
评论