基于WebAssembly构建Web端音视频通话引擎
文/田建华
编辑/LiveVideoStack
大家好,我叫田建华。今天分享的主题是基于WebAssembly构建Web端音视频通话引擎。今天将从背景、WebAssembly引擎、方案落地和问题及展望四个方面展开介绍。
-01-
背景
随着网络基础设施的升级,音视频传输技术的迭代,以及音视频消费习惯的转变,多媒体技术从最开始的点播和直播发展到了现在的超低延时直播和实时音视频互动。在发展过程中Web RTC奠定了技术基础。
这是WebRTC的架构示意图。WebRTC提供了丰富的Web API。音视频采集、音视频编解码、音视频前后处理、音视频的传输和渲染都因WebRTC得以实现。在开发音视频Web端应用时,由于WebRTC的应用,开发难度降低,成本也减少很多。WebRTC也存在一些不足。首先WebRTC不能自定义编解码器,另外WebRTC不能复用现有的服务框架以及优化能力,最后WebRTC的可定制化程度较低。
有没有新的Web技术作为替代来解决WebRTC的问题呢?下面将列举一些可以使用的新技术。
WebAssembly是一种运行在现代浏览器中的新型代码,并且提供新的性能特性和效果。其设计目标是快速、高效、可移植、可读、可调试、安全和不破坏网络。使用WebAssembly可以解决JavaScript在复杂场景的性能问题,例如3D 游戏、计算机视觉、图像视频编辑等以及大量的要求原生性能的其他领域。一些原先使用JavaScript的场景中使用WebAssembly可以显著提高使用效率。得益于WebAssembly体积小的特性,使用WebAssembly还可以解决下载、解析JavaScript应用程序成本高的问题。
WebCodecs为开发人员提供了一种使用浏览器中已经存在的媒体组件的方法,不仅可以解决编码器低延时问题,还可以提供更灵活的配置接口。右边的图片是视频编码器的配置项,可以看出有很多可以配置的选项都被提供出来,例如软硬件编码的选择、VBR/CBR的选择、质量优先/低延时优先等都可以选择配置。H264编码使用HighProfile时,WebCodes配置项里可以很容易的支持,在编码层面提供非常大的便利。
WebTransport是一个全新的可插拔的通信协议,支持可靠和非可靠传输。在一些需要可靠传输的应用中可以使用WebTransport。WebTransport的目标是更快速、更高效、安全和低延时。WebTransport可以解决链接迁移的问题。WebTransport拥有灵活的拥塞控制以及更好的弱网能力。在应对队头阻塞时,有可以使用更加灵活的传输方式。
-02-
WebAssembly引擎
新技术和新架构致力于给用户提供更多的可能性。自定义编解码器、自定义传输方式、自定义数据加密、自定义音视频前后处理和自定义QoS操作均已在可以实践的项目中落地。
这是整个WebAssembly引擎的架构图。WebAssembly引擎主要包含WebSDK、用户调度中心、WebTransport/WebSocket Gateway集群和后台TRTC服务集群和调度四大模块。因为后台的TRTC服务可以直接复用,所以主要的工作是WebSDK和WebGateway的开发。
WebSDK提供了Client、LocalStream、RemoteStream等接口。Client为用户提供可操作的方法。LocalStream提供音视频的数据回调。RemoteStream提供远端用户的音视频数据回调。总线负责整个WebSDK的运行。底层包括日志上报、质量上报、异常检测、状态回复、采集渲染、Wasm SDK、WebCodecs、WebTransport/WebSocket等。橙色部分是主要使用的技术。其中WebCodecs和WebTransport/WebSocket是浏览器提供的方法,只需要用好即可。
WebAssembly SDK分为五大模块。音频处理包含回声消除、AI降噪和增益三部分。协议封装解封装包含视频协议封装解封装、视频包协议分装解封装和FEC。下行质量控制包含视频Jitterbuffer、视频NetEQ、FEC恢复/NACK和音视频同步。除此之外还有上下行质量统计、拥塞控制、音频编码和音频解码四个部分。
最左侧浅色部分是JS层。上下是WebCodecs层,中间是Wasm,最右边是网络传输部分。JS业务层采集到音视频数据之后,交给WebAssembly进行音频的前处理。之后会由WebCodecs编码,封装之后通过网络发送。从网络搜集到数据之后,也会在WebAssembly解封装和进行一些音视频的后处理。完成之后交由WebCodecs解码和JS渲染。在实际使用过程中,音视频编码是在WebAssembly SDK中实现。
-03-
方案落地
腾讯云新的SDK已经在一些金融客户、行业用户和信创项目得到了广泛应用。
右上角图片中,前四个是WebAssembly用户,后面两个是WebRTC用户。他们同时加入一个房间。在内存使用率方面,WebAssembly和WebRTC差不多,但CPU使用率WebAssembly更低。这样,WebAssembly就拥有了更加灵活的可操作性。在两人进房,编码码率为1Mbps,帧率为30帧,RTT 10ms的场景下,多次截图,从采集到渲染,端到端的延时在100ms内。可以看出使用WebAssembly进行超低延时通讯也是可靠的。
从最开始的技术探索到方案落地,SDK经过了很多次的技术迭代。一开始SDK只是用单线程,但在实际使用过程中发现了各种各样的问题。例如定时器精度差、单核跑高、UI阻塞底层等。之后我们引入了Worker,主线程只负责采集、渲染等操作,其他的都交由Worker操作。
UI收集到用户的操作指令之后,通过PostMessage交付给Worker线程。Worker搜到数据也会通过PostMessage响应给主线程。信令的封装解封装、推拉流、状态统计、WebCodecs编解码和WebAssembly SDK音视频处理等都是由Worker进行。现在的架构中有两个Worker,其中一个负责上行,另一个负责下行。在这里我们还引入Worklet减少音频数据的拷贝,以提升音频数据的传递效率。在特殊场合可以使用SharedArrayBuffer传递视频数据,以减小视频数据的性能影响。
后台RTC服务主要采用的是复用的现网架构。在服务端采用BBR算法和更激进的拥塞控制已收获更低延迟的弱网体验。同时根据丢包、Jitter情况,适当调整弱网策略。最后,我们还设计根据网络情况自适应FEC策略。
在WebAssembly开发过程中遇到问题怎么办?答案是调试。WebAssembly的调试非常方便,提供了可视化界面。
调试程序使用C++开发。在调试过程中,会先在浏览器安装如图所示的插件,安装好之后需要一些简单的配置。配置完成以后就可以进行调试。启动应用程序之后会自动加载wasm文件和源文件。右图以opus编码为例。左边是源码栏,里面有一个断点。中间是很详细的变量信息,右下角是堆栈调用关系。和普通的C++程序一样,在编译时需要添加-g选项。缺少的话就会因为找不到源码目录而不能调试。
-04-
问题及展望
我认为WebAssembly的高度自定义是其最大的优点。自定义音视频编码方式、自定义加解密、国密支持、自定义3A都已经支持。使用WebAssembly进行国密支持,其性能可以得到数10倍的提升,自定义3A中的AI降噪已经投入到生产,实际落地,支持200多种噪声的处理。QoS调优可以自定义或可复用现有系统的QoS策略。更简单的服务器逻辑使得可复用后台服务逻辑。WebAssembly拥有更快更安全的网络传输,WebTransport有更好的防火墙穿透能力。
WebAssembly同样也存在一些问题。WebAssembly引入了WebAssembly、WebCodecs和WebTransport三个新的模块。WebAssembly拥有更好的复杂性,增加开发难度,需要更多的技术积累。WebTransport不能在Safari浏览器中运行,WebCodecs目前只能在Chrome和Edge94以上以及最新的 safari版本运行,WebTransport也只能在Chrome和Egde97以上以 版本运行,这些问题都带来一定的兼容性问题。另外WebTransport上行拥塞控制算法暂不支持调整。这里我们有考虑过通过协商的方式解决上行拥塞控制,但浏览器作为客户端时,会直接将协商结果忽视掉,所以这里只能等官方的支持实现。
在实现过程中,团队也遭遇了很多的挫折。底层逻辑被UI阻塞的问题被我们引入Worker解决。我们还发现WebCodecs OPUS编码只支持60ms编码,只支持60ms会带来实时性和兼容性的问题,所以我们尝试在WebAssembly实现音视频的编码。除此之外,在共享标签页时发现不采集的情况。该问题的主要原因是标签页在静止的时候不会被浏览器采集。我们在SDK活跃的前提下,增加标签页减活机制,通过逻辑策略进行一系列饱和操作,保证标签页在不活跃时也能正常屏幕共享。另外,回声有时会无法消除。声音对时间非常敏感,采集和渲染是会有较大的延迟,这样就会产生回声。我们调整了音频的播放控件和传输策略,通过worklet播放,可以更加精准计算采集和播放的延迟。再配合回声消除算法,该问题得以解决。目前我们也在探索能否使用AI进行回声消除。最后,H264大小码流也会有问题。使用WebCodecs在腾讯会议场景进行硬编时,会出现大小码流输出同样分辨率的情况。尝试多次发现,这些问题是由硬编带来的。所以在小满流编码时,会强制采用软编的baseline,这样就可以得到一个很小的分辨率。这里仅仅例举出其中的一小部分的问题,还有很多问题必须在实际使用和落地过程中才会发现。
未来,我们希望会有更开放的Web技术。WebTransport更加完善、将提供更灵活的拥塞控制算法,WebGPU也会开放硬件能力,WebAssembly的SIMD的也将更好支持。同时,更加复杂的应用场景,支持更加高度的自定义也是未来目标的一部分。云游戏、自定义加解密、远程桌面、空间音频、音视频前后处理等越来越多的场景都可以自定义。
谢谢大家!
微信扫码关注该文公众号作者