摄像头实时流测试 — 对方真正看到的画面真实质量如何
你在摄像头预览中看到的画面是本地采集视图——通过 getUserMedia 交付的摄像头帧——而不是传感器原始输出。对方看到的画面是经过 WebRTC 协商、压缩、可能降级的网络流。本文解释 WebRTC 编码协商的原理、如何在 RTCPeerConnection 上使用 getStats 测量真实流参数,以及如何修复预览不告诉你的质量损失。请注意,本站摄像头工具仅检查本地采集轨道和浏览器帧率,不测量出站 WebRTC 编码流。
你坐在视频通话里,自己的窗口显示清晰明亮的 1080p 画面。然后同事说你画面模糊、不断卡顿。同一个摄像头,同一个照明,同一台电脑,两个完全不同的画面。
大多数人不知道的:这个差距通常不是硬件故障或驱动问题——偶尔驱动有问题也会引起,但更常见的是——是摄像头产出的画面和浏览器真正发送的画面之间的区别。一个常见场景:有人花两个小时重装摄像头驱动,因为 Zoom 显示的画面很模糊——直到打开 chrome://webrtc-internals 才发现浏览器基于带宽估计已经协商到 480p15,而不是摄像头或驱动的问题。预览在第二阶段接入管线,显示通过 getUserMedia 交付的摄像头帧,未经 WebRTC 压缩。浏览器可能已应用缩放、色彩转换或约束处理,但此阶段没有 WebRTC 编码。其他参与者收到的是经过 WebRTC 协商、压缩、可能降级的流。
这个编码层在用户界面完全不可见,正常运行时没有任何提示。本文解释摄像头传感器和通话伙伴屏幕之间发生了什么,以及如何测量实际发出的流而不是相信预览。

预览不等于实际流
视频通话的管线完全在你的感知之外运行。每帧画面经过以下阶段:
- 摄像头传感器捕获帧,浏览器通过 getUserMedia() 按请求的分辨率和帧率交付,此过程可能包含缩放、色彩转换和约束处理。
- 浏览器通过 getUserMedia 接收帧,交给 WebRTC 引擎。
- WebRTC 编码器用协商好的编码器、分辨率、帧率和码率压缩帧。
- 编码帧被拆成 RTP 包通过网络发送。
- 接收者解码包还原成画面。
你的预览在第二阶段接入管线,显示通过 getUserMedia 交付的摄像头帧,未经 WebRTC 编码。浏览器可能应用缩放、色彩转换或约束处理,但无 WebRTC 压缩。通话伙伴看到的流来自第三阶段。编码器基于你通常看不到的条件做决策。
编码器静默协商三个参数,每个都可能在中途改变而不通知:
- 分辨率——可能从 1920x1080 降到 1280x720 或 640x480。
- 帧率——可能从 30 降到 15 或更低。
- 码率——编码器每秒允许消耗的比特数,决定整体压缩程度。
SDP 在你发出第一帧之前就开始谈判了
协商在发送第一帧之前就开始了。平台和浏览器交换 SDP 提议和应答,列出双方支持的编码器、分辨率和帧率,两端达成一致。在 Windows 上的 Chrome 125,我观察到 SDP 应答优先提供 VP9,然后是 H.264、VP8;在 macOS 上的 Safari 17,H.264 排首位。这些观察是在各自一台机器上做的,没有受控网络环境,因此只展示了一种可能的顺序,不构成通用规则。
编码器选择只是开始。通话开始后,第二个机制接手:带宽估计。WebRTC 持续监控双向网络路径,运行拥塞控制算法(最常见的是 Google Congestion Control),在滚动基础上做三项测量:
- 丢包率,接收方通过 RTCP 反馈消息报告。
- 往返时间,发送数据包到收到到达确认之间的延迟。
- 吞吐量,数据实际穿越连接的有效速率。 算法将这些测量值输入模型,估算网络当前能承载多少带宽。估算值变成目标码率交给编码器,编码器据此调整输出。循环持续且快速:估算下降时,编码器在不到一秒内以更低码率重新编码。
阈值因具体拥塞控制算法而异。持续丢包超过约百分之五可能触发目标码率降低——具体行为因算法、编解码器和平台而异,不存在从丢包率到输出分辨率的通用映射(Google: WebRTC Congestion Control Whitepaper, 2019;RFC 8888 Transport Wide CC),但确切阈值因算法和实现不同。1080p 30 fps 通常需要约四到六兆上传,但取决于编码器、编码设置和场景复杂度。

流隐藏的三种故障模式
码率的陷阱
症状:预览完美,CPU 空闲。对方看到模糊画面,本地录制优秀,通话很差。
诊断:浏览器估计网络无法承载完整流,限制了码率。瓶颈是上传带宽或中继能力,不是摄像头。测速并与四到六兆对比。
丢包阈值
症状:通话静止画面可以,运动时卡顿。音频流畅视频卡顿,每隔几秒冻结。
诊断:丢包间歇超过百分之五,拥塞控制器反复削减目标码率,编码器丢帧。帧率通常最先下降——从 30 降到 15 帧减半数据量,但某些实现可能优先降低分辨率,取决于编码器和平台。检查 Wi-Fi 干扰或 VPN 引入的丢包。
关键帧冻结
症状:加入通话后前两到五秒,对方看到冻结画面,之后恢复清晰。
诊断:视频编码器发送两种帧。关键帧编码整幅画面,每 1 到 10 秒一次,取决于平台和配置。差分帧只编码变化。如果差分帧的包丢失,接收者等待下一个关键帧重新同步。

现在就打开 chrome://webrtc-internals
停止猜测。实际数据可能不好看,但它反映真实情况。WebRTC 提供统计接口精确报告编码行为(MDN: getStats() Reference)。一个典型对比:空闲时 outbound-rtp framesPerSecond 是 30;同一台电脑开视频会议时可能掉到 18——而本地预览仍然显示 30。调用 getStats 获取 RTCPeerConnection 对象,过滤 outbound-rtp 条目。找到关键值:
- framesPerSecond(media-source 条目)——摄像头交付给编码器的帧率。低于 30 时采集链路本身有问题——这往往是 USB 带宽争用问题,我们的 USB 带宽争用指南讲解了如何诊断。
- framesPerSecond(outbound-rtp 条目)——编码器实际产出的帧率。低于输入率时编码器在丢帧。
- frameWidth 和 frameHeight(outbound-rtp 条目)——编码分辨率。任何差异都是静默降级。
- bytesSent(outbound-rtp 条目)——总编码数据。间隔一秒采样两次,计算差值乘 8 得真实码率。
- packetsSent 和 packetsLost——注意 outbound-rtp 条目的 packetsLost 不一定有值;丢包率更可靠地从 remote-inbound-rtp 条目读取。
- currentRoundTripTime(candidate-pair 条目)——网络延迟。
不同浏览器可能报告略有不同的字段名称或部分统计缺失,可用浏览器内置的 WebRTC 内部页面交叉验证。
你不需要写代码。Chrome 和 Edge 内置了 chrome://webrtc-internals 统计查看器,捕获所有 WebRTC 连接。在加入会议前打开它,检查视频发送者的 outbound-rtp 条目。本站的摄像头测试工具显示通过 getUserMedia 协商的本地采集轨道的分辨率和帧率——这是摄像头能交付给浏览器的有用基线,但不是出站 WebRTC 编码流的测量,后者需要 peer connection 或浏览器的 WebRTC 内部页面。
Zoom、Meet、Teams:三台不同的摄像头
同一个摄像头、同一台电脑、同一个网络,在不同应用中结果不同。
- Zoom 通常优先稳定性。根据版本、账户类型和会议设置的不同,可能限制输出分辨率,为保持音频和屏幕共享稳定而牺牲视频质量。1080p 摄像头在 Zoom 上可能传输 720p 或更低。
- Google Meet 倾向于根据实测带宽调整,提前降分辨率,恢复也快。其行为更忠实地跟随实际网络状态,好坏参半。
- Microsoft Teams 有自己的编码和后处理管线。根据版本和会议设置,图像可能在原始 WebRTC 协商之外进一步被压缩。
- 浏览器原生 WebRTC 发送协商流,无平台策略叠加,最接近硬件和网络在纯 WebRTC 下的实际交付能力。平台策略因版本、账户类型和会议配置而异,应视为一般倾向而非固定规则。
比较 Zoom 和 Meet 通话不是摄像头测试,是平台编码测试。先用纯 WebRTC 测原始流,如果清晰而某个平台差,是平台策略问题。
七步走:干净的流
- 先测量。打开 getStats 或摄像头测试,记录分辨率、帧率和码率。
- 检查带宽。720p 需要至少一兆上传(Google WebRTC Blog: Bandwidth Estimation, 2016),1080p 需要四兆。用有线连接;Wi-Fi 丢包是常见原因。
- 改善照明。照明好的主体压缩效果更好。面向窗户或用柔光光源。
- 关闭视频降噪。环境安静且光线充足时,某些平台的激进降噪会明显软化编码流中的细节。本地预览不会显示这个差异,只有编码流会。检查具体平台设置以确认可用控制项。
- 关闭虚拟背景。背景分割增加 CPU/GPU 处理负载,可能迫使编码器降低分辨率或帧率。
- 检查编码器。VP9 每比特质量最高;H.264 编码更快。
- 测试不同平台。如果一个好而另一个差,是平台策略约束。
总结
这是实话:你看到的预览窗口是本地采集的友好视图,不等于对方实际收到的流。对方看到的是完全不同的视频——经过协商、压缩、被网络条件和平台策略塑造的。如果你曾经困惑为什么摄像头在自己屏幕上很清晰,但在通话里却很差,你现在有了答案,也有了测量工具。
打开 chrome://webrtc-internals。参加下一次会议。观察 outbound-rtp 条目。如果 frameWidth 或 framesPerSecond 低于你在摄像头设置里指定的值,降级正在发生——原因通常与带宽有关,但 CPU 负载、编码器选择、平台策略和约束配置也可能导致或加重降级。