是时候再次了解实时通信 (RTC) 的未来了。我们多次触及的一个领域是使用 WebCodecs 和 WebTransport 作为 WebRTC 的 RTCPeerConnection 的替代方案。为了简洁起见,我们将这种方法称为 W&W。主持人 Chad 邀请到了三位嘉宾:
- Microsoft 和 Skype 的首席架构师、W3C 工作组联合主席 Bernard Aboba
- Meta 视频软件工程师、Media Over QUIC 小组成员 Jordi Cenzana-Ferret
- W3C 的网络和电视专家 François Daoust
这三人将会分享他们关于 W&W 的实验和经历,并对 W&W 的未来进行展望。
主持人:Chad Hart
嘉宾:Bernard Aboba、Jordi Cenzano Ferret、François Daoust
视频地址:https://www.youtube.com/watch?v=lyOSQW6ic_I
内容整理:杨晓璇
为什么在 WebRTC 以外研究新的方法?
WebRTC 已经取得了长足的进步——无论是在实际优化方面,还是在提高控制方面。我们真的需要像 W&W 这样的新颖方法吗?
Chad:“首先,我想问一下 WebRTC 出了什么问题?为什么要把所有这些精力投入到这些新技术和新方法上?想要完成但目前还做不到的事情是什么?新技术的未来是什么?”
Bernard:“我想要说的是,这项工作中的很多想法都是从扩展 WebRTC 开始的。例如,Insertable Streams 和 Breakout Box,两者都是基于流的 API。这些想法已被 WebTransport 采纳。因此,在我看来,其中很大一部分是扩展了 WebRTC,同时也添加了新的功能,可以将 WebRTC 与其他东西结合起来。”
“我看到了一些有趣的实验,例如现在我们在 WebCodecs 中进行了 HEVC 解码,也许可以将其与 WebRTC 结合起来。所以我不会说这是一个非此即彼的问题,但我认为 Jordi 将特别谈到的一个领域是低延迟流媒体。我认为 WebRTC 并不擅长某些事情,例如缓存和 DRM 等超低延迟流媒体功能,这些功能可以通过 WebCodecs 和 WebTransport 来完成,我们肯定会深入探讨这一点。”
“我想澄清一下,WebRTC 不擅长低延迟流媒体的原因之一——可以使用数据通道发送 CMAF,例如在低延迟流中。但 QUIC 是一种更好的传输方式。这就是 WebTransport 所带来的效果。而且,至少目前,数据通道在工作人员的测试中不起作用。”
回顾 WebCodecs+WebTransport 架构
Jordi 制作了一个全面的 demo,使用 WebCodecs 和 WebTransport 实现超低延迟流媒体。
Jordi:“这是我实现的demo。同样,唯一的目的是学习并尝试证明我们在 MoQ(Media over QUIC) 工作组中讨论的那些想法是可行的并且有效。我实现的只是一个 JavaScript 应用程序,它利用 WebCodecs 和 WebTransport 捕获来自摄像头和麦克风的数据并将其发送。它压缩视频和音频数据,并以不同的 QUIC 流发送每个视频和音频帧。QUIC 流是可靠的。所以基本上,该帧中的所有数据都保证到达中继。”
“最有趣的功能之一是它是可缓存的——或者我们计划它是可缓存的。所以基本上,我实现的是利用 quic-go 和 Adrian Cable 的 WebTransfer 实现。我实现了一个缓存(CDN 节点),用于缓存编码器发送的所有对象。”
“另一方面,这是一个利用 WebCodecs 的 JavaScript 应用程序——我实现了一个只从中继接收信息的播放器。MoQ 从中继到玩家是基于推流的。它接收该信息并对其进行解码并将其渲染到画布和 AudioContext 中。下面是应用程序的框图。”
“下面分开进行介绍,首先是编码器。从顶部开始,我们有 getUserMedia—— 捕获视频和音频——像素和 PCM 样本。我们在这里进行一些调整,因为我们希望音频和视频同步。我们建议使用者在捕获该样本时使用世界时钟计时标记信息。当使用者在播放器中想要倒带或突出显示该内容时,这非常方便。然后我们将其发送到 WebCodecs,这遇到了 WebWorkers,它有一个编码器——用于视频的 H.264 和用于音频的 Opus。最后,我们为此演示创建了一个打包器。它的目的不是标准化任何新的打包程序,而是使得创建自己的简单打包器比导入零碎的 MP4 或 FLV 库更容易。MoQ 可能会使用 Fragmented MP4。在 WebWorker 内部,它打开一个 WebTransport 会话,将流发送到中继。在这里需要指出的是,发送顺序不可用,或者至少在我实现此演示时,它在浏览器中尚不可用。这个demo 都是没有发送顺序的。WebTransport 有一个 sendOrder 选项来按顺序接收数据。”
“中继比较简单。它接收 WebTransport 会话的 URL。因此该 URL 包括入口点 (moqingest) 和流标识符 (STREAMID)。我从 WebTransport 接收这些对象。我们将这些对象保存在内存一段时间,时间由编码器指定。到目前为止,这是典型的 CDN 行为。然后,播放器只需打开到该入口点的会话。URL包括一些参数,这些参数用于倒带,还用于通知中继器抖动缓冲区,以便中继器做出更好的决定。”
“cache key 是什么?我们谈论 CDN 或中继时,了解 cache key 是什么很重要。cache key 包括我们从 WebTransport 会话中获取的流 ID。然后我们添加媒体类型——在这种情况下,我们只有视频和音频,但它可以是视频一、视频二、视频三。序列 ID (seqId) 来自头文件。序列 ID 基本上是对象的数量或者视频帧的数量和音频帧的数量。这样就为每个对象创建了一个唯一的标识符,在本例中,为每个帧创建了一个唯一的标识符。所以这个实现是每帧每个对象一个帧,但是 MoQ 足够灵活,如果想每帧放置一个 GOP,完全可以。基本上,它只是给出一个描述。”
“最后是播放器。播放器针对 CDN 或中继打开 WebTransport 会话。再次,使用我们之前看到的 URL 中的 STREAMID。播放器开始接收音频和视频帧。请记住,中继将数据推送给播放器。播放器知道是视频还是音频。播放器将每个帧发送到正确的管道。我们进行了去抖动,因为请记住,我们每帧发送一个独立的 QUIC 流,因此无法保证到达顺序。它是可靠的,但不能保证如果将不同的 QUIC 流推送到网络的顺序。因此,我们需要一些去抖动,以确保解码器按顺序看到帧。”
“口型同步的音频和视频对齐本身就是一个完整的主题,这是我花最多时间的领域。这可以得到很大改善。但无论如何,这里我们做了一些补偿来对齐音频和视频。”
“最后一点——我们将音频发送到音频循环缓冲区。基本上,它是音频工作进程和主线程之间的共享内存。最后,audioWorkletProcessor 消耗来自该共享内存的 PCM 样本。”
Chad:“这是一个很好的架构概述。我认为深入研究流以及它与 Breakout Box 和 MediaCaptureTransform 的配合可能会有所帮助。”
关于流的使用
WebRTC 的 Web 部分主要由万维网联盟 (W3C) 定义。然而,还有另一个 Web 标准机构,即 Web 超文本应用程序技术工作组 (WHATWG),它具有 WebSockets、全屏 API 和 Streams 等规范,将在此处介绍。
François:“WHATWG Streams 是管理流的通用机制,这个名字选得对。Streams 的好处是它们负责处理不同步骤中的排队问题。所以最终会得到一个具有不同步骤的管道。这些步骤将通过流(通常是转换流)连接。Streams 负责处理步骤之间的排队机制。如果转换需要一些时间,那么队列将由 Streams 协议本身管理。”
“比基本排队更重要的是,它包括背压机制。因此,这意味着如果有一些需要更长的时间来处理的内容并且它无法跟上发送的内容,流将向上游节点发送背压信号,并且它们将停止生成新的数据块。这使得它成为一个出色的 API,可以在处理音频和视频时使用,而音频和视频本身就是一种流。”
“我一直在更多地研究客户端上的实际视频处理,除了改善传输问题之外,Jordi 和 Bernard 一直在谈论这一点,我们看到越来越多的用例需要实时处理。因此这意味着他们需要实时更改视频帧的内容。这意味着这些网络应用程序需要访问像素本身。这就是我们研究扩展 WebRTC 并扩展方式的原因之一——为 Web 应用程序提供新的机制,以便它们可以操纵这些框架。”
“WebCodec 允许访问原始媒体。最终,得到的是一组可以使用的多米诺骨牌,并且可以在客户端上以任何希望的方式组装来操纵这些流。我们已经看到了 Jordi 的例子。该图也遵循这一点。因此,如果从相机中获取 getUserMedia,这里重要的是本质上的结果——能从中得到什么。getUserMedia 提供 MediaStreamTrack。但是无法直接使用 MediaStreamTrack 处理视频帧——需要其他东西来做到这一点。需要将其转换为实际的 JavaScript 流,因为 getUserMedia 默认情况下不使用流。因此,将把它提供给 MediaStreamTrackProcessor,它将提供视频帧流,然后可以按照希望的任何方式进行处理。”
Chad:“谢谢。既然您来到这里,您能给我们介绍一下您发现的挑战吗?”
François:“当然。我的实验实际上更多的是在客户端上进行处理,而不是通过网络进行传输。我想评估我们可以使用实时 Video Frame 做什么?我们真的可以实时处理吗?性能怎么样?如果我使用 JavaScript 处理帧,典型的性能会是怎样?如果我使用 WebAssembly 处理框架?如果我使用 WebGPU 或 WebGL 处理一帧,会发生什么?”
“为了做到这一点,首先需要能够评估性能。评估性能,从每一个处理步骤中是可行的,但是对于端到端,就相对困难,特别是因为从渲染的角度来看,无法跟踪 VideoFrame 直到它呈现在屏幕上。我使用的解决方法是,我基本上将视频帧的时间戳编码为实际视频帧之上的叠加层。我正在使用 requestVideoFrame 回调来获取该视频帧。然后了解它何时被渲染并从中提取编码的时间戳,以便我或多或少地跟踪它。但这并不绝对完美,并且使用 requestVideoFrame 并不能保证获得所有帧。可能会错过其中一些帧,因为它在主线程上运行,当它过载时可能会错过一些帧。另外,我不清楚我是否能够真正正确地测量 WebGPU 性能。使用 WebGPU,把一些工作交给 GPU,最终得到的是Canvas内容,但并不真正知道 Canvas 内容何时更新。只知道当要使用它时,浏览器会同步,所以它会等到工作完成,但也许浏览器实际上不会等到工作完成。”
“我遇到的另一个问题是将视频帧发送给其他工作人员。当有一个视频帧流时,有一个问题是,在工作人员之间,流是可传输的,这很棒,但流中的块本身不会传输,而是被序列化。序列化的问题是它并没有真正复制实际的原始像素,但它要求发送者调用 videoFrame.close(),因为视频帧需要显式关闭。它们的生命周期如下图所示。”
“这并不容易做到,因为我们不知道发送何时实际完成(传输何时发生),因为 Streams API 中无法做到这一点。目前有一个正在进行的提议,即在序列化流的基础上扩展流并允许传输块。我很高兴这个实验至少促使一些人在这方面取得了进展。”
AV1 SVC 实验
Chad:“现在轮到 Bernard 讲讲他的经历。”
Bernard:“请允许我澄清一下,据我所知,现在有一些商业产品使用 WebCodecs,但没有使用 WebTransport。因此,在我的实验中,我专注于 AV1,因为我想了解它的进展情况。我可以展示一个运行的例子。”
“这是一个 AV1 以全高清、每秒 30 帧运行的示例。我认为这将非常具有挑战性,但它实际上对编码和解码都有效。它几乎可以在我尝试过的大多数硬件上运行——一台 Mac 和一堆 Windows 机器。最大的问题是承载性能。我对传输很感兴趣,所以我使用了时间 SVC(可扩展视频编码),这样就不需要传输所有帧。”
“François 提到,只有一个非常非常小的时间窗口,但必须让所有事情通过,所以不能在传输上等待太久。因此,我在顶部实现了部分可靠性。因此一般来说,帧的 RTT 相当紧,但 I 帧除外,它花费的时间要长得多。我发现其原因是 QUIC 中的拥塞窗口太小,无法在单次往返中发送 I 帧,所以需要多次往返。拥塞窗口和 I 帧之间有这种奇怪的相互作用。”
“我发现的另一件事是,正如 Francois 提到的,我使用 RVFC(request Video Frame Callback)来尝试获取视频信号从源端到显示端所经历的总延迟。在 RVFC 中,我认为这由演示时间减去捕获时间来表示,使用媒体时间作为唯一标识符。但是可以看到这里有一些奇怪的现象。首先,在下图中,出现了相当有规律的峰值。帧 RTT 没有显示出相同的峰值,或者可能确实显示出相同的峰值,但没有那么糟糕。也就是说线路速度和实际图像渲染的速度存在显着差异。如果浏览器可以立即处理传入的流,那么这些数字应该是相同的。事实上,它们并非如此,而且它们在更高的分辨率下差异更大,这表明浏览器的处理在这里很重要。这是一件有趣的事情,需要跟进的事情之一是了解系统中哪些峰值发生以及 WHATWG 流上是否存在排队。”
Jordi 遇到的挑战与实验数据
Chad:“Jordi,您能谈谈您的实验结论吗?您对哪些感到满意,哪些还需要改进?”
Jordi:“关于我在实现这个 demo 时哪些不起作用以及哪些具有挑战性:音频和视频同步很困难,正如 François 所提到的,视频时间戳在编码和解码阶段中存在,但音频时间戳则不然。那么如果想对齐视频和音频,就会遇到困难,因为音频可能会被丢弃。视频也是如此,但由于视频具有唯一的时间戳,因此只需要重传所需部分。音频更具挑战性。如果它丢失了某些东西,需要确切地知道丢失了多少内容以补偿那些丢失的时间戳并基本上对齐它们。所以,这是我遇到的主要挑战之一。我想我或多或少解决了这个问题,但有很多我不满意的地方。我希望音频时间戳与视频时间戳相同。”
“还有一件小事也让我的实验富有挑战——概念验证(PoC)。我意识到 AudioFrame 是不可转让的。尽管音频数据(即编码数据)是可传输的。这对性能造成很大影响。
“还有另一件小事,我花了几个小时才弄清楚——那可能是六个月前的事,所以也许它已经解决了。当我尝试使用使用硬件加速的默认设置进行视频解码时,没有任何效果。我遇到了非常奇怪的性能问题——本来一切好好的,然后它突然停止工作,或者它会开始变得超级慢。我到处都添加了计时器,所有计时器似乎都指向 webcodecs 视频解码器,所以我最终将硬件加速设置更改为 prefer_software,然后就解决了。这就是我遇到的挑战。”
“我上周做了这个 demo。现在我在旧金山,我在俄勒冈州有一个中继服务器。我测量了大约 36 毫秒的往返时间。”
“然后我通过从旧金山到俄勒冈州的直播进行了演示,结果如下图。端到端延迟非常好。没有掉帧,非常顺滑,时间是 140 毫秒。”
“我提高了分辨率和比特率。然后延迟有点高,是380 毫秒。”
“我还做了另一个完全相同的实验,但我把中继放在欧洲的法兰克福。延迟为 500 kbps,将端到端延迟增加到近 700 毫秒。”
未来与展望
Chad:“目前 Jordi 和 Bernard都有一些实验数据,但 W&W 完全投入实际使用,还需要时间。最后,我们可以讨论下一步做什么以及我们如何实现这一目标。”
Bernard:“TPAC 即将在 W3C 中出现,François,所以我们或许应该讨论一下如何聚集。这并不容易。我们描述的许多问题都是群体之间的问题。WebCodecs 和 MSE 归媒体工作组所有。WebCodecs 已在 Chrome 中发布。WebCodecs 正在 Safari 中开发,仅用于视频。WebTransport 已在 Chrome 中发布,最近刚刚在 Firefox 114 中发布。然后一堆其他 API 大部分都在 Chrome 中。BreakoutBox 在 Chrome 中,Insertable Streams 在 Chrome 中。我认为 Safari 中都有这两个版本。然后是渲染 API。我仍然想说,WebGPU 还不成熟,但它正在发展。WHATWG Streams,完全属于另一个标准机构。所以这里肯定存在很多协调的挑战。”
François:“我们没有提到的一个方面是媒体人喜欢 HDR 内容。目前网络对 HDR 的支持并不是很好。所以还有另一个维度,那就是 Canvas 的扩展、WebGPU 的扩展、ECMAScript 的扩展。”
Chad:“这对于 Jordi 和 Bernard 来说可能更像是一个问题——作为供应商,为什么要推动 W&W 的发展,最终想要构建一个应用程序吗?这背后有商业驱动吗?”
Bernard:“Jordi 谈到的那种场景——低延迟流媒体开放,但也只是在会议中,可以进行 François 一直在谈论的所有视频处理。要知道,机器学习现在非常重要,从 Web 应用程序中获得所需的性能并不容易。所以,人们期望消除噪声、期待各种视频效果——在短暂的时间窗口内完成所有这些,特别是转向 AV1 和 HEVC 等新编解码器时,这是相当具有挑战性的,所以肯定有动力。”
“我个人的观点是,开发人员和反馈循环之间的联系并不像应有的那么紧密。我整天听开发人员的讲话。我收到很多投诉,但也许没有我应该收到的那么多。”
Jordi:“如果 QUIC 上的多媒体成功,我们的想法是它将覆盖很多用例,从 Bernard 提到的视频会议、直播开始。我认为如果它成功了,而且我显然希望它成功,那么它可能会极大地简化当前世界上的流媒体。拥有一个可以覆盖所有用例、适用于 CDN 端、适用于播放器端的单一协议。这也关系到开发人员的效率,不需要学习 WebRTC、RTMP、SRT 等等,只需选择适合的目前情况的,然后进行 N 次转换。”
“我真心希望 MoQ 能够成功,虽然现在还处于早期阶段。我认为现在我们已经准备好接受采用了,但还没有实现。但毫无疑问,如果成功的话,这可能会给流媒体世界带来巨大的帮助。”
Bernard:“是的,我认为我们要做的是,Jordi,我们将通过协议简化您的生活,并通过 API 使其变得更加复杂。”
Jordi:“好吧,是的,这是一种看待问题的方式。但我们希望 API 比协议更好。”
结语
非常感谢 Bernard、François 和 Jordi 花费大量时间进行准备,分享他们的经验。希望大家将继续关注他们的各种项目,看看 W&W 如何发展成熟。
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。