28、WebRTC调试:Chrome webrtc-internals、日志分析、常见问题排查

做WebRTC开发,最头疼的是什么?不是写代码,是出了问题不知道从哪查。我见过太多人,代码写得挺溜,一遇到卡顿、黑屏、连不上,就抓瞎了。

今天这篇,我就把压箱底的调试方法掏出来。说白了就三招:Chrome自带的webrtc-internals、日志分析、常见问题排查套路。这三样玩熟了,大部分问题你都能自己搞定。

核心观点:调试WebRTC,不要靠猜。数据会说话,webrtc-internals就是你的听诊器。

WebRTC 调试三板斧 🔍 webrtc-internals • ICE连接状态 • 候选者类型 • 比特率/丢包率 • RTT 往返时延 • 帧率/分辨率 • 编解码器协商 • 丢包重传统计 • 音频/视频轨道 📋 日志分析 • chrome://webrtc-logs • 应用层日志 • 信令日志 • 网络层日志 • 关键时间戳 • 错误码解析 • 日志级别设置 • 日志导出工具 🛠 常见问题排查 • 连接建立失败 • 音视频卡顿 • 黑屏/花屏 • 回声/噪音 • 带宽不足 • 编解码不匹配 • 防火墙/NAT • 浏览器兼容

一、webrtc-internals:你的第一现场

Chrome浏览器里藏着一个神器——chrome://webrtc-internals。你打开它,再打开你的WebRTC应用,所有底层数据就全摆在你面前了。

我个人习惯,每次调试必开这个页面。它比任何第三方工具都靠谱,因为数据直接来自浏览器内核。

1.1 怎么看懂这些数据

打开后你会看到一堆表格和图表。别慌,重点看这几个:

指标 正常范围 异常信号
googRtt < 200ms > 500ms 说明网络拥堵
googFrameRateReceived 24-30 fps < 15 fps 会明显卡顿
googFrameWidth/Height 640x480 或更高 突然下降说明带宽不足
packetsLost < 1% > 5% 画面会花
googAvailableSendBandwidth 与码率匹配 远低于码率时必卡

小技巧:我习惯把googRtt和packetsLost这两个指标放在一起看。RTT高不一定丢包,但丢包率高RTT一定高。如果两者都高,基本可以断定是网络问题。

1.2 ICE候选者类型

在webrtc-internals里,找到IceCandidatePair相关的行。你会看到三种候选者类型:

  • host:本地内网IP,延迟最低
  • srflx:NAT映射后的公网IP,常见于家庭网络
  • relay:通过TURN服务器中转,延迟最高

嗯,这里要注意:如果最终选中的是relay类型,说明P2P打洞失败了。我曾经排查过一个项目,用户反馈视频卡顿,一看webrtc-internals,所有连接都走了TURN服务器。后来发现是STUN服务器配置错了,修好之后延迟从300ms降到了30ms。

二、日志分析:把问题挖出来

webrtc-internals看的是实时数据,但有些问题需要看历史记录。这时候就要靠日志了。

2.1 Chrome内置日志

在地址栏输入chrome://webrtc-logs,你会看到所有WebRTC会话的日志文件。每个文件都包含:

  • ICE连接建立过程
  • SDP协商细节
  • 编解码器选择
  • 网络状态变化
  • 错误信息

我一般会先搜ERRORWARNING关键字。有一次,用户反馈连不上,日志里反复出现ICE_FAILED。顺着时间戳往前看,发现是STUN请求超时了。最后定位到是防火墙封了UDP 3478端口。

2.2 应用层日志

除了浏览器日志,你自己的应用也要打日志。我建议至少记录:

// 信令交互日志
[2025-01-15 10:23:45] SEND offer: {sdp: "...", type: "offer"}
[2025-01-15 10:23:46] RECV answer: {sdp: "...", type: "answer"}

// ICE状态变化
[2025-01-15 10:23:47] ICE state: checking -> connected
[2025-01-15 10:23:48] ICE state: connected -> completed

// 媒体流状态
[2025-01-15 10:23:49] Remote video track added: id=xxx, kind=video
[2025-01-15 10:23:50] Remote audio track added: id=yyy, kind=audio

注意:日志里不要打印完整的SDP,太长了。只打印关键字段,比如ice-ufrag、ice-pwd、编解码器名称。不然日志文件会大到吓人。

三、常见问题排查套路

下面这几个问题,是我在项目中遇到最多的。每个都附上排查步骤。

3.1 连接建立失败

现象:双方都创建了PeerConnection,但就是连不上。

排查步骤:

  1. 打开webrtc-internals,看ICE状态是不是一直卡在checking
  2. 检查STUN/TURN服务器配置是否正确。我见过有人把URL写成了stun://而不是stun:
  3. 看候选者类型,如果只有host类型,说明NAT穿透失败了
  4. 检查防火墙,确保UDP端口没有被封

避坑指南:我曾经遇到一个案例,STUN服务器配置完全正确,但就是连不上。最后发现是DNS解析出了问题——STUN服务器的域名解析到了错误的IP。所以,记得先ping一下你的STUN/TURN服务器。

3.2 音视频卡顿

现象:画面一卡一卡的,声音断断续续。

排查步骤:

  1. 看webrtc-internals里的googFrameRateReceived,如果低于15fps,就是帧率问题
  2. packetsLost,如果超过5%,就是丢包问题
  3. googRtt,如果超过500ms,就是延迟问题
  4. 检查带宽:googAvailableSendBandwidth是否小于当前码率

说白了,卡顿就三个原因:丢包、延迟、带宽不足。你对着这三个指标查,一定能找到根因。

3.3 黑屏/花屏

现象:能看到对方,但画面是黑的或者花的。

排查步骤:

  1. 先确认摄像头权限是否开启。在Chrome地址栏左边有个锁图标,点开看看摄像头权限
  2. 看webrtc-internals里track相关的行,确认视频轨道是否正常
  3. 检查编解码器协商结果。如果一方只支持H264,另一方只支持VP8,那就没画面
  4. 花屏通常是丢包严重导致的,看packetsLostgoogNacksReceived

小技巧:黑屏问题,我习惯先看onaddstreamontrack回调有没有触发。如果没触发,说明媒体流根本没传过来。这时候查信令,看SDP里有没有视频描述。

3.4 回声/噪音

现象:对方能听到自己的回声,或者有持续的噪音。

排查步骤:

  1. 检查是否开启了回声消除:echoCancellation: true
  2. 检查音频设备:是不是用了外放而不是耳机
  3. 看webrtc-internals里音频相关的googEchoCancellation是否生效
  4. 如果用了自定义音频处理,检查有没有引入额外的延迟

嗯,这里要注意:回声消除不是万能的。如果物理上音箱和麦克风离得太近,算法也救不了。我建议用户用耳机,这是最彻底的解决方案。

四、调试工具链总结

最后,我把常用的调试工具整理成一张表:

工具 用途 使用场景
chrome://webrtc-internals 实时查看WebRTC内部状态 所有调试场景,必开
chrome://webrtc-logs 查看历史会话日志 排查偶发问题
Wireshark 抓包分析网络层 怀疑网络问题
Chrome DevTools Network面板 查看信令请求 信令交互异常
getStats API 编程方式获取统计 需要自动化监控

你想想看,有了这些工具,大部分问题都能在10分钟内定位。剩下的,无非是查文档、看源码、或者去社区问。但前提是——你得先学会看数据。

我个人觉得,调试WebRTC最忌讳的就是瞎猜。什么「我觉得是网络问题」、「我觉得是编解码问题」——别猜,去看数据。webrtc-internals里每一行数据都在告诉你真相。

最后一句:调试不是玄学,是科学。数据不会骗人,但你的直觉会。


公众号:蓝海资料掘金营,微信deep3321