WebRTC 中的客户端 CPU 管理

在 WebRTC 中,客户端 CPU 管理并不常见。你会在“高端”应用中看到它,但在其他地方却很少见。为什么?因为我们都专注于网络问题,试图通过优化来解决。人们认为,一旦 CPU 过载,网络统计数据也会受到影响,然后自动修正。

这种情况确实会发生。

但并非总是如此。

而且修正速度不够快。

本文让我们深入探讨一下 WebRTC 中客户端 CPU 管理这个复杂问题。

WebRTC 中的客户端 CPU 管理

关键要点

  • WebRTC 中的客户端 CPU 管理经常被忽视,人们往往更关注网络问题。
  • 同时监控网络和 CPU 可以提升用户体验并预防性能问题。
  • 我们可以通过分析视频编码时间、解码时间和使用 WebRTC 指标的质量限制来估算 CPU 负载。
  • 计算压力 API 旨在提供对 CPU 状态更深入的洞察,但目前仍处于实验阶段。
  • 使用 rtcStats 等工具有助于收集指标并有效解决 CPU 负载问题。

WebRTC客户端资源管理

若要了解 WebRTC 客户端的运行状态与行为,需重点关注网络、CPU和内存这三个方面,且优先级依次为:

  • 若网络传输量过大——你完蛋了
  • 若网络传输量过小——你错失了提升媒体质量的机会

多数人很可能止步于此。我们往往满足于WebRTC对可用带宽的透明适配机制。

为什么?因为仅针对网络进行精细调优极其困难,而且当你这样做时,还会无意中“解决”CPU和内存问题。原因很简单:网络层的解决方案(降低比特率)同样能缓解CPU和内存压力。

不过,这种方法也存在一些问题:

  • 问题发现得越早,就能越早解决。
    • “修复时间”也正是用户注意到问题的时间。
    • 所以,如果你间接地发现了问题,那很可能是在问题发生之后,比你直接查找问题时发现得晚得多。
    • 最终结果?用户体验低于行业平均水平。
  • 有时候,网络统计信息并不能帮你找到问题所在,也不能帮你解决问题。真的不行。
    • 在这种极端情况下,媒体质量会很差。
    • 用户会抱怨
    • 你需要更长时间才能得出存在真正问题的结论。

因此,我的做法如下:

  • 主动监控网络和 CPU 使用情况
  • 从一开始就要确保网络不会因为过度扩张的心态而超负荷运转——在开始优化之旅前,我会尽量平衡视频的发送和接收数量。

搞懂网络这回事……很简单(?)

当要解决客户端 WebRTC 网络问题时,事情其实很简单——至少一开始是这样。

你可以检查三大指标:丢包率、往返时间和抖动

对所有传入和传出的媒体流执行此操作。通过这些指标,基本就能推断出媒体质量状况。

但这里有个关键点——你需要记住两个容易被忽略的漏洞:

  1. 现在你知道网络存在问题,媒体质量受到影响。但你不知道根本原因——那么你打算如何为用户解决这个问题呢?
  2. 如果能够更早地知道可能存在问题,那么在问题显现之前就改变行为来解决问题岂不是更有意义吗?

所以说,网络指标固然重要,但还不够。

你需要更多的数据。其中一些数据需要通过了解CPU负载情况来获取。

为什么我们无法从 Web 浏览器获取 WebRTC CPU 状态

隐私。

网络浏览器功能太强大了。当你使用浏览器时,你连接的服务器会掌握很多关于你的信息。它知道你所在的位置、你使用的操作系统、屏幕分辨率等等。

在想要更多了解用户并能够完全识别用户的供应商与想要尽可能保持用户匿名性的网络浏览器供应商之间,存在着一场猫捉老鼠的游戏,他们只在每个步骤中分享必要的信息。

这种观点认为,浏览器每增加一项新功能,厂商就能获得更多信息,从而更容易识别用户。因此,这里存在一种平衡。例如,之前发现 WebRTC 存在漏洞,任何人都可以开始绘制本地网络地图——后来通过在关键位置使用 mDNS 地址,有效遏制了这种漏洞的传播。

CPU 使用率在某种程度上也类似。人们普遍认为,了解 CPU 使用率百分比不利于保护用户隐私。这也是为什么详细的 CPU 信息不会直接通过 JavaScript 传递给开发者的主要原因之一。

因此,我们只能采用粒度较低的解决方案,通过估算 CPU 状态来进行处理。而像往常一样,getStats()函数将是我们最好的帮手。

估算 WebRTC 客户端 CPU 状态的 3 种方法

由于缺乏直接方法,我们只能估算 CPU 负载。实现方式有几种,这里分享三种最常见的方法,也可视为该领域的最佳实践。

多数情况下,你需要综合运用所有方法……

请记住——我们无法精确得知“当前CPU负载达90%”,只能判断CPU“工作强度可能超出预期”。因此需要进行估算……

视频编码时间

对于 WebRTC 客户端而言,最耗费资源的任务是视频编码(此处暂不考虑应用相关的 AI 技术)。正因如此,它成为判断 CPU 负载最直观的指标。

核心思路在于:若能掌握单帧视频编码所需时间,便可评估 CPU 的负荷程度。我们真正关注的并非 CPU 使用率百分比,而是现有资源中有多少投入了视频编码。

如何实现?

通过 getStats 获取 totalEncodeTime(总编码时间)并除以 framesEncoded(编码帧数),所得结果即为单帧视频的平均编码耗时。

让我们好好利用这一点:

  • 若以 30 fps 运行,则需确保每帧视频约33毫秒(1000/30≈33)送达网络
  • 若视频帧编码耗时超过33毫秒,则超出我们的能力范围——编码速度已落后于网络传输需求
  • 同时需为编码之外的任务“预留”部分CPU资源。因此每帧编码时间应远低于33毫秒
  • 经验法则是:对于多数应用场景,三分之一的时间是合理基准。因此单帧编码时间若能控制在12毫秒或更短则理想,超出此值即为警报信号(12毫秒源于33/3=11)

视频解码时间

视频处理的另一部分是视频解码。

因此,我们对视频解码也采用同样的方法——用总解码时间除以解码帧数。结果就是解码单个视频帧的平均时间。

与编码过程类似,我们将根据每秒帧数来计算我们的意图。不过,这里除以 4 而不是 3 更合理——解码器比编码器需要的资源更少。

对于“正常”的 30 fps 流,我们会密切关注任何高于 9 毫秒(33/4 = 8.25)的情况。

这里有几点需要说明:

  • 如果视频信号被强行传输,解码器将无能为力。因此,如果你想降低比特率、帧率或分辨率,则需要请求远程端进行调整——这可以通过 WebRTC 提供的机制实现,也可以通过 WebRTC 之外的信令实现。
  • 在SFU群组调用中,可能存在多个解码器。请在您的假设和计算中考虑这一点。
  • 有时,视频编码器并不存在。在这种情况下,视频解码时间将是衡量 CPU 负载的最佳指标。

质量限制

我将这个指标放在最后:

一方面,它是最直观的指标,能清晰提示因 CPU 问题导致的状况恶化。

另一方面,它仅适用于存在外发视频的场景。哦,如果视频处于静音状态,该指标同样失效。

此处所指显然是 getStats 中的 qualityLimitationReason 指标。

其使用逻辑相当直观——针对每个编码视频帧,它会说明该帧被“限制”的原因(即“嘿,这里是libWebRTC,因X因素不得不降低视频编码器的比特率”)。具体原因包括:

  • none:没有任何限制
  • network:网络状况不佳,因此我们不得不降低码率(这是带宽估算机制)
  • cpu:你此刻阅读此文的原因。用户 CPU 负荷过高,需要减轻压力
  • other:一个笼统的概括性词语,我不记得见过。

你会怎么做?只需检查是否因 CPU 问题触发,并确保此类情况不频繁发生。假设实际场景中该问题会自行缓解(毕竟无法控制设备在空闲时的行为),但仍需持续监控,确保问题并非源于你这边的编码逻辑(比如某个AI功能过度迎合用户,反而因CPU超载搞砸了用户体验)。

WebRTC 中 CPU 负载监控的未来

目前我们掌握的只是估算值。试图通过启发式方法和从 getStats() 中获取的线索来推测实际情况。要是能有更优越、更直接的方法该多好?

当然……

但现实并非如此。至少现在还不是。

谷歌 Chrome 浏览器已经运行了一段时间的名为“Compute Pressure API”的测试项目。该项目的目的是允许 Web 应用程序注册一个专门的计算压力回调函数,该函数可以指示 CPU 的状态。

根据试验文档页面的描述,其主要应用场景是视频会议和视频游戏。

对我们大多数人而言,现在使用这个新 API 还为时过早——它能否成为所有网页浏览器的官方 API 也尚难预料。但这无疑是值得持续关注并期待其落地的事物。

在此之前?请继续使用 getStats() 中的指标,并构建自己的策略来应对它们。

rtcStats 方法在 CPU 负载故障排除中的应用

使用rtcstats.com,我们在这里对 CPU 负载所做的工作相当简单:

  1. 我们会收集所有 getStats() 指标,所以应该涵盖所有情况。
  2. 本文提到的三种技术都存在一些共同的观察结果:解码时间长、编码时间长和CPU占用率高。
  3. 我们观察到的其他问题涵盖了更多与视频质量相关的问题,这使得关联分析和查找根本原因变得更加容易。
  4. 我们正在关注 Compute Pressure API,一旦它变得合理,我们也会添加对它的支持。

我有没有提到,rtcStats 的大部分工作都是开源且免费使用的?

既然你知道了问题所在,你该如何解决它呢?我们需要检查一下 CPU。不能只依赖网络统计数据。从现在开始,你打算如何处理这件事?

作者:Tsahi Levent-Levi
原文:https://bloggeek.me/client-side-cpu-webrtc/

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/64688.html

(0)

相关推荐

发表回复

登录后才能评论