RTC 技术的试金石:火山引擎视频会议场景技术实践

avatar
@字节跳动

视频会议场景一直被认为是 RTC 最具挑战性的场景,一方面,它对抗弱网、低端机适配、降噪、多人上麦等都有极高的要求,对 Web 端的要求也远高于其他场景;另一方面,有很多孵化自会议场景的技术能力最终都被复制到了其他场景。

RTC 在会议场景的独特挑战

为什么说“视频会议”场景对于 RTC 的技术挑战最大?相比于其他行业和场景,“视频会议”中的 RTC 到底独特在哪?

首先,会议场景的需求是更为复杂的,这里举 4 个例子。

「自由开麦」

在视频会议中,每一个参会方都可以自由选择是否打开自己的麦克风和摄像头,这是视频会议非常基础的功能,但随着参会人数的增加,技术实现会越发复杂。行业内 RTC 一般可以实现五十到上百人的自由开麦,超过了这个人数之后就需要主持人来控制麦位。飞书会议要求我们支持 1000 个参会方,如果 RTC 支持自由上麦的人数低于 1000,飞书会议的用户使用起来就会非常不方便(虽然所有参会人同时开麦的极端情况比较少见,但是业务的需求是希望主持人不要过多“干预”会议——不断地控制参会人上麦、下麦,把发言能力分配给想发言的人)。假设一场会议里有 1000 个参会方,但只有 50 个麦位可以发言,主持人就要把想说话的参会人不停地“挪”到这 50 个麦位之中。为了让主持人知道谁想发言,还需要引入一些沟通机制,整体操作成本非常高。RTC 为什么会限制拥有上麦能力的用户数量?如果不限制可以上麦用户的数量,发布/订阅流模型的算法复杂度就是 O(n^2),即,如果有 1000 人参会,就会产生 100 万 音视频流发布/订阅关系。短时间高频的上下麦操作会造成服务端信令风暴,所以上麦人数才需要加以限制。可是现实中,一些大型会议的规模往往会超过 1000 人,甚至达到几千、上万,我们不该因为技术的限制而牺牲用户的体验。

「自由布局」

视频会议一般会提供多种视图布局类型供参会方选择,从 11 全屏,到 22 四宫格,33 九宫格,到 77 四十九宫格……这还只是普通的宫格,还会有一些其他布局,比如演讲者模式、侧边栏模式等。画面布局类型的丰富让每个参会者都可以自己选择自己喜欢的布局,但这样一来,同一个会上,有开四宫格的,有开九宫格的,有开演讲者模式的,视频发布者就需要决策到底发布什么样的分辨率。如果发布的分辨率过大,对于选择多宫格的订阅方来说,分辨率就过剩了,同时还造成了极大的下行带宽和设备性能压力——试想一下,一个订阅方同时拉了 49 路 1080P 的视频,什么样的神仙设备和带宽都扛不住;如果发布的分辨率过小,对于全屏或者演讲者模式这样的大窗口来说,清晰度就会不足,用户体验会受到影响。严格来说,每一种布局都应该有一个最合适的分辨率。在多人会议中,如何在有限的带宽与设备性能下,尽量提供灵活多样的画面布局,是一个很大的挑战。

「屏幕共享」

这个功能大家比较容易理解,它的挑战在于,屏幕共享虽然也是视频流,但是它的视频画面特点和我们摄像头拍摄的视频画面特点是不一样的。简单来说,屏幕共享对画面的要求更清晰,要能看清楚很小的文字,但是对于帧率的要求并不高。对于编码器来说,需要决策什么时候编高帧率的视频,什么时候编低帧率的视频,这是关键。

「Web 入会」

很多时候,视频会议软件的用户是“临时用户”,比如用视频会议去参加一场面试,或者是合作伙伴用你们公司的会议软件来参加一场会议…这些“临时用户”可能并不希望去安装一个会议 App,用 Web 入会就是一个非常好的选择。但是 Web 对音视频有很多限制,而对视频会议的需求和体验的要求一点都没少,怎么才能把 Web 入会的体验尽量追上 Native 的体验?

除了业务需求更加复杂以外,视频会议场景所面临的环境也更为极端。

过去,开视频会议都是在专业的会议室里开,有很多专业的会议硬件设备来支撑会议体验,环境是相对比较好的。但现在,开会环境早已不限于会议室了,会议环境的多样性让 RTC 面临了很多新的挑战。这几年,疫情让我们居家办公的时间更多了,在家里开视频会议成为了很普遍的场景;一些经常出差的人——他们往往也是会比较多的人——在路上、车上、高铁上甚至飞机上通过手机参加视频会议也非常普遍。

会议环境多样性为 RTC 带来的挑战主要可以分为以下四大类:

首先是极端弱网,俗称“用户网络差”。这种情况非常常见,尤其是不在公司会议室里开会,弱网情况更常见;

其次是弱设备,也就是“设备性能不足”。如果参会设备不是专业视频会议硬件,就会承担更多的性能压力,尤其当参会人开启美颜或者虚拟背景这样高消耗的功能之后,原本可以开会的设备也会出现性能不足。现在在视频会议中使用虚拟背景是一个非常高频的功能,大家看我现在视频的背景就是一个虚拟背景。

再者就是会议场景的噪声类型会更多,除了会议场景常见的键盘声之外,如果你不是在会议室开会,就会伴随各种各样的噪声:空调的声音、开关门的声音、隔壁装修的声音、附近人说话的声音、小孩的哭闹声,室外的喧嚣声……

最后一个挑战是光线差。离开专业会议室的环境之后,可能会面临严重的光线不足、背光等问题——本来家里的光线布局就不是为了居家开会所设计的,更不要说在户外或者交通工具上开会了。

从技术角度看,RTC 技术最初就是从视频会议中抽象剥离出来的,后来逐渐应用到会议以外的领域,所以很多 RTC 的新场景其实就是从视频会议中迁移出来的。换句话说,RTC 在视频会议场景的「独特性」,其实也可以认为是一种「领先性」。

从最近几年的行业发展来看,不断有从会议场景技术溢出到其他行业的案例。之前特别热门的「大班小组课」,其实就是会议中的「分组会议 Breakout Room」。再比如现在很火的 「3D 空间音效」,其实最初的应用是高级视频会议产品中的「听声辨位」,HP 2005 年发布的 Halo 就支持这个功能。

最后说说「千方会议」。我们在去年 6 月已经对外介绍了我们做的“千人上麦”能力,在今年 2 月份正式对外发布了这个功能。当时很多朋友不理解我们为什么要做那么大的上麦并发,实际上是因为,我们看到不仅视频会议有这个需求,其他场景也陆续出现了这个需求,像在线教育大班课中的齐声朗读或者抢答,大型吃鸡游戏中的世界语音,还有现在正在发生的大型 VR 社交,这些场景需要自由上麦的人数很容易突破几百甚至上千。既然「千方会议」可以支持大型视频会议,何不做成 RTC 的标准能力,来解锁各行各业中“自由上麦”人数的瓶颈,发挥更大的价值呢?顺便提一句,目前我们还在进一步突破上麦人数上限,实现「万方会议」甚至更多。

「千方会议」过去已经和大家介绍过了,今天不再重点展开。接下来和大家分享视频会议对 RTC 的几个新的挑战和我们的思考实践。

复杂光线下的视频体验

前面提到,很多用户入会时所处的位置可能并没有很好的光照条件,比如晚间的户外,光线会严重不足;比如在室内,如果光源的位置不佳,会形成逆光或者侧光。恶劣的光照条件会严重影响视频体验,但我们一般人开会也不会像专业主播一样准备专用的打光设备,因此,一旦光线不好,拍摄效果就会差,而一旦拍摄基础效果差,仅仅靠视频后处理技术是没有办法很好地解决视频体验问题的。

为了解决这些问题,我们引入了一系列的相机技术,包括自动对焦、自动曝光这些比较基本的相机技术。RTC 场景和其他场景有个不一样的地方,画面中一般都是人像占据主体,而当画面中人像占据主体时,如果不做特别处理,由于摄像头本身是“平均测光”的,当人像处于逆光环境时,由于背景很亮,会导致曝光不足,人脸会显得过暗。因此,我们在 AE 的基础上又增加了人脸检测算法,即 FaceAE,当检测到人脸时,把“平均测光”优化为“根据人脸检测结果”来做曝光处理,解决画面过曝、欠曝的问题。为了实现最佳效果,我们与国内外很多手机和芯片厂商保持良好的合作,把硬件的相机功能和我们自研的算法进行深度结合,让每一款设备都达到最佳性能。目前我们已经对线上 18000+ 款机型进行了适配,覆盖低中端各类机型。

我们使用了一些知名会议或社交 App 来和我们的拍摄效果做对比,大家可以感受一下基于 FaceAE 算法优化过的相机效果。第一组对比图是一个户外傍晚背景,画面中有一盏路灯,可以看到右边使用 FaceAE 算法优化过的采集效果,人脸更亮,天也更蓝,画面整体感觉更舒服。第二组是室内暗光场景,左边是个黑脸,右边人脸的亮度就比较正常;第三组是白天逆光场景,这种场景的背景很亮,普通 AE 给的曝光就会不足,人脸会显得非常黑,而使用 FaceAE 优化过的相机效果就会比较亮,五官也能看清晰;第四组是室内侧光场景,这种场景照出来很容易阴阳脸,可以看到左边图上一半的脸都是黑的,眼睛都看不见在哪儿,而右边虽然不可避免还是存在阴阳脸,但画面更亮,五官都能看清了。

以上是我们仅仅靠相机采集优化的效果,在没有开启任何美颜算法的情况下,就能达到比较理想的画质效果。而且,由于 FaceAE 调用的都是系统底层的能力,没有使用算法,不会引入额外的性能开销。当然,开启美颜之后,还能再锦上添花。

前面提到会议场景的技术溢出,「相机采集优化」也是如此,它对于其他非会议场景也有非常广泛的应用。在视频社交场景中,参与平权聊天的大部分用户都是非专业主播,大家就是临时上线聊天,不会特别准备好的光源或打光设备;在直播连麦场景,主播是专业武装的,但连麦的观众或场外嘉宾往往是非专业主播,也不大会考虑光线的问题;在互动课堂场景,老师端一般有较好的开播条件,但学生端的条件就会差一些;还有一个是我们最近发现的很有趣的场景,也是我们遇到的一个真实场景——健身小班课,它和普通的“互动课堂”场景有点像又有些不一样,虽然健身老师可以算得上是“专业主播”,但传统主播用的打光设备没办法照顾到整体授课的场景,图上的瑜伽老师在客厅开播,客厅连着阳台,形成了一个大逆光场景,导致瑜伽老师的脸完全是黑的,影响与学员的互动效果。

屏幕共享的优化

屏幕共享是视频会议场景最常用的功能之一,用户对于共享文字/PPT 的要求一般是高清晰度,对于共享视频内容的要求一般是高流畅。我们比较容易做到根据共享内容的文件属性来决定是“清晰度优先”还是“流畅度优先”的编码策略,比如共享 PPT 时自动切换为“清晰模式”,共享视频时自动切换为“流畅模式”,但这样设计会遇到一些问题:如果用户的 PPT 里嵌入了一段视频,在播放这段视频时理应追求“流畅模式”;如果用户视频其实是一段 PPT 的教学录屏,里面有大量的时间在播放静止的文字和画面,这时候理应是“清晰模式”。也就是说,我们共享的内容,它是是静止的还是运动的,是由用户决定的,而不是程序可以决定的;我们也不可能要求用户在共享的过程中手动地去不停选择切换当前的编码模式,这样会严重影响用户体验,而且用户很可能会忘记切换。

业务层面不能通过用户的输入来解决问题,这个挑战就落到了 RTC 上,RTC 要如何帮助用户及时调整最佳模式呢?

我们研究出了一个“智能编码模式”,在屏幕共享的过程中,让 RTC 自动识别用户传入的视频内容类型,并且不断自动调整最佳的策略。

我们来看一段视频。视频里的一个参会人在共享屏幕,一开始,他在浏览网页,共享画面是静止的图片和文字,所以分辨率非常高,帧率和码率非常低;然后参会人打开了一个视频网站,共享内容变成了一段视频,对应的帧率和码率慢慢地爬升,为了平衡性能,对应的分辨率也在慢慢地下降,帧率最后爬升到了 30 帧;然后他又换了一段视频播放,这段视频只有中间部分在动,运动部分占据画面比较小,所以帧率没降,但码率慢慢降低了;最后,他又回到了最初的网页,帧率和码率逐渐下降,而分辨率又慢慢地回升到了高清模式。这段视频演示了在共享内容类型切换时“智能编码模式”的自动调整策略。

“智能编码模式”带来的一个重要收益就是线上平均分辨率的提升。一些共享内容原来被系统认为是“视频”而采用了“流畅模式”,现在被算法纠正成了“高清模式”(实际上视频会议场景共享静态内容的概率更大),线上平均分辨率有了翻倍的提升。同时,因为系统永远选择最合适的编码策略,因此线上屏幕共享场景下的整体 CPU 消耗降低了 20%。

我们来看看「屏幕共享」在非会议场景的应用。过去我们认为「屏幕共享」只应用在会议场景,随着着“线下活动线上化”的趋势,「屏幕共享」在会议以外的应用也越来越多了。在线教育就不多说了,它本来就是视频会议场景的一个子类,除了普通的“屏幕共享”以外,在线教育还有一个“云端录屏”的需求——把软件的 UI 一起录下来回看或作为直播对外分享,本质上这也是一种特殊的“屏幕共享”——通过在云端模拟一个虚拟学生上课,在云端打开应用软件的界面来进行「屏幕共享」。在远程协助场景,通过「屏幕共享」,子女可以告诉不会使用手机或智能电视的父母如何操作,甚至直接远程操作;在 VR 直播教学场景中,老师通过 VR 设备在虚拟空间进行操作,学生通过 VR 设备跟随老师的视角观看和学习,沉浸式、实时互动式的屏幕共享可以极大地提升教学效果。

多宫格视图体验的提升

多宫格视图也是视频会议中的基本需求,它让尽可能多参会者的视频被播放出来,可以提升参会互动性,但也非常容易引起客户端性能和带宽的不足,因为你要订阅的视频流变多了。对此,RTC 一般会提供动态“弱网降级“和“性能降级”,但在视频会议中,一般的弱网降级和性能降级是不够的。

这个场景主要有三个特点:

一是每个用户都可以自由选择自己喜欢的视图布局;

二是不同布局对应不同阶梯的分辨率;

三是任何一路流都可能会面临从高到低各种档位的分辨率的订阅请求。

目前行业里 RTC 普遍支持「大小流」,也就是两档分辨率,但两档分辨率在视频会议中远不够用,而增加档位又会大大增加性能开销,如何既能灵活支撑用户自定义会议视图布局,又能兼顾设备和带宽性能?

针对这个场景,我们设计了「10 级档位的 Simulcast」。既然两档分辨率不够,我们就来增加档位嘛。这里的主要难点在于,对于发布者来说,他相当于要做 10 路视频流的编码,这对于发布者的性能消耗是巨大的,绝大部分设备的性能是不够的。所以在实现的时候,我们会对档位进行聚合分组,最后分成四档,分组的原则是“按分辨率订阅人数的权重排序,尽量照顾更多人的体验需求”。也就是说,我们优先选择订阅人数多的分辨率进行编码,订阅人数少的排在后面。如果设备性能跑满了,档位不够分,就归并到最接近的已编码的分辨率档位。除此以外,动态弱网降级和动态性能降级也会与 Simulcast 结合,如果订阅端订阅太多流或者性能不足了,那么就自动降到下一个档位。相比大小流两个档位, 多档位的 Simulcast 降级会比较平滑,即不是直接从 1080P 降到 90P 这样的低分辨率,而是一档一档地逐档降级,直到降到一个最合适的档位。

我们来看「Simulcast」的线上数据表现。「Simulcast」的主要作用是提升实时画面的清晰度,尤其是多宫格视图的清晰度。我们看到,22 宫格的清晰度从 360P 提升到了 540P,33 宫格的清晰度从 180P 提升到了 270P,一些中高端手机全屏模式下的清晰度从 360P 提升到了 720P,线上平均分辨率提升了 16%。在提升清晰度的同时,我们也要平衡一些其他的指标。在实时性方面,端到端延时与原先水平保持持平;在流畅性方面,视频百秒卡顿率也没有下降。「Simulcast」的最大挑战是给发布端带来的性能开销,但我们看到性能开销的上涨是非常轻微的,基本不影响发布端的性能。

我们再看一下「Simulcast」在会议以外场景的应用。比如连麦场景,随着连麦的人数越来越多,“多视图布局”的需求也应运而生,在社交场景,我们叫它“动态麦位”。在“万物互联”的物联网生态中,各种类型的设备都在使用 RTC,小到手表,大到智慧电视,中间还有手机、Pad、电脑,电视机也有各种尺寸,想象一下,如果我们用手机和父母、小孩通话,父母使用电视,小孩使用手表,如果让电视和手表订阅相同分辨率的同一路视频是极不合适的,这个场景也适合「Simulcast」方案。

实现会控的关键技术

第四个话题是关于「如何做好会控」,对于 RTC 来说,做好会控的关键是什么?

在会控中,和 RTC 相关的一个难点是“音视频状态和用户状态的一致性”的问题。比如一个用户在系统上显示是麦克风开启的状态,如果状态是错误的,实际上他是无法上麦的。反过来,系统上显示他已经闭麦了,但实际上他还在上麦,如果他说了一些不希望被会上其他参会者听到的话或者声音,就会涉及到严重的隐私泄漏问题。还有一个难点是“用户状态变化的及时性”,比如主持人要让某个人闭麦,当他操作闭麦该人的动作之后,需要能够马上、真正地把麦闭掉,一旦及时性做得不好,不仅让参会人的体验不好,还可能造成主持人无法及时控场的问题。

这两个问题的关键在于“信令的可靠性”,我们如何保证信令必达的同时,还拥有极低的延时,并且与音视频状态同步?

我们的解决方案是,让信令复用 RTC 音视频流的传输链路与弱网对抗策略,确保音视频和信令的到达率相同,保证音视频状态的一致。

我们为信令定义了几个指标,一个是 200ms 到达率,一个是总到达率。总到达率我们做到了 100%——要确保“消息必达”,这也是信令的基本要求。而且,我们还要做到“低延迟”的“消息必达”,这就要求信令是在一定的时间范围内到达的,否则即使信令到达了,也会失去一部分的意义。我们选择了「200ms 到达率」这个指标,目前这个指标的线上数据表现是 98.6%,也就是说,在 98.6% 的情况下,信令可以在 200ms 之内到达目的地。

我们再看一下延时方面的指标。目前,「端到端平均延时」指标表现是 51 ms,但「平均延时」这个这个指标其实比较宽松,我们会看一个更严格的指标,就是「端到端延时九十分位值」,简称「PCT 90」,我们线上 PCT 90 的指标表现是 117ms,也就是说,线上 90% 的用户的端到端消息能够在 117ms 以内到达。能够做到这样的到达率和延时,主要就是因为我们的信令复用了 RTC 的传输链路。复用 RTC 传输链路还有一个很重要的好处 ,就是保证音视频数据和信令数据的延时和到达率是一致的,这样,用 RTC 信令来实现会控就不会出现状态不一致的问题,因为极端弱网是不可避免的,最极端的弱网就是断网,我们现在说到达率是 100%,前提是网络还是通的,如果断网了,任何信令都不可能传输了,而且数据上还无法统计到。但是,如果音视频和信令采用同一条链路,假设真的断网了,音视频传输和信令传输都无法到达,要断一起断。这样的话,不管是什么样的网络情况,音视频状态和用户状态永远都是一致的,我们做会控的目的也就达到了。

我们打磨的「实时信令」在其他领域也有广泛的应用。我们刚刚说到会控,其实在很多 RTC 领域中,多多少少都存在一些会控的逻辑,像互娱社交场景中也会存在房间管理,如果一些主播、连麦嘉宾、上麦观众说了一些不合适的话,或者做了一些不合适的行为,管理员就需要制止,简单点就是禁言或踢人,如果制止不成功或不够及时,可能会引起更严重的问题。除了会控以外,「实时信令」也可以用到一些新的玩法中。这里举一个「一起看抖音」的场景,抖音上就有这个功能,两个朋友之间可以连麦一起刷视频,“主态”刷到哪儿“客态”的视频进度就跟到哪儿,两边的视频延时低于 100ms,而实现视频滑动状态主客态同步业务逻辑的技术就是「实时信令」。

Web 端实现复杂算法的新解

最后一个话题是关于「Web 端实现复杂算法的新解」。我们先看一下 Web 端有哪些性能消耗的“杀手”。我们知道,RTC 的编码是很耗性能的,但和美颜、特效、虚拟背景比起来还是小巫见大巫。这些功能在视频会议场景中已经成为“刚需”,几乎每个居家办公的参会人都会使用,我们要如何既保证客户端设备性能,又达到媲美 Native 的效果呢?

我们做了一系列的思考和尝试。

第一种是业内的普遍做法——在 Web 本地加载这些算法。Web 本地运行算法对于设备 CPU 的消耗都非常大,而且由于 Web 浏览器本身存在性能瓶颈,哪怕设备再好,在 Web 端做特效的效果都可能打折扣,一些复杂的特效甚至可能无法运行。浏览器的兼容性也是一个问题。还有一个问题是比较容易被忽略的,由于 Web 会把代码和模块下载到本地运行,如果在本地加载特效算法就会增加包体,支持的算法越多,包体就越大,它会影响页面加载速度,算法的丰富性也会受到限制。

我们也研究了业务端是如何解决这个问题的。行业里,业务端会使用虚拟摄像头的方案。虚拟摄像头自带美颜功能,Web 通过虚拟摄像头来采集视频,这个采集的视频已经经过了特效处理,因此浏览器不再需要有额外的性能消耗。但这种操作有个问题——用户必须安装虚拟摄像头,这和 Web 端追求“免安装即用”的便捷性理念是违背的。一般会采取这种方案的用户是专业主播,他们本来就在电脑中安装了很多美颜、虚拟摄像头的软件,可能是因为临时换一个网页开播的平台做直播所以使用虚拟摄像头,像参加面试、临时会议这种场景,普通人可能都不知道有“虚拟摄像头”,因此这种方案的适用性是比较局限的。

通过结合 RTC 的优势,我们探索出一种新的解法——边缘渲染。边缘渲染的原理是,当发布者在本地采集了视频之后,不是直接向订阅端发送流,而是先发送到 RTC 边缘,在边缘进行云端美颜和渲染,再发送给对端,同时也发回给发布端用于本地预览。这对“边缘”的要求很高,边缘要尽可能多,才能在边缘就快速把特效解决了。「边缘渲染」的好处是对本端几乎没有额外的性能消耗,完全不依赖本地设备算力,可以运行更酷炫、更复杂的算法。大家可能会担心「边缘渲染」会增加发布者本地预览以及发送到对端的延时,我们统计了一下线上数据,开启边缘渲染只比普通音视频通话增加了 30ms 的延时,本地预览延迟低于 200 ms,实时帧率可以达到 30+ fps。

我们来看一下实际效果。视频左边是未渲染的预览画面,右边是经边缘渲染之后再返回本地的预览效果,延迟控制在了 200ms 以内,轻微的延迟基本不会影响正常的发言和交流。同时,像这样的虚拟头套是一个比较消耗性能的算法,「边缘渲染」的方案突破了 Web 运行精细特效算法的性能瓶颈。

从视频会议场景孵化出的「边缘渲染」能力也可以用到其他应用场景。比如在一些美妆、电商场景,可以支持用户免下载软件,通过云渲染的方式即可体验试妆、试戴效果。像图上的一些万圣节特效、魔法变身特效、老年特效都是一些比较耗算力的特效算法,通过云端渲染,在低端机上也可以方便地实现。

作者:杨若扬,火山引擎 RTC 产品负责人