30、媒体协商调试与排错:常见SDP错误、日志分析技巧、Wireshark抓包分析SDP与ICE

说实话,做WebRTC开发这几年,我最怕听到的一句话就是:“视频怎么黑屏了?”或者“为什么对方听不到我说话?”

这种问题,十有八九是媒体协商出了问题。SDP没对上,ICE没通,或者编解码器没匹配上。今天我就把压箱底的调试经验拿出来,跟你好好聊聊怎么快速定位这些坑。

30.1 常见SDP错误:那些年我踩过的坑

SDP(Session Description Protocol)是媒体协商的“身份证”。双方交换SDP,就是为了告诉对方:“我能支持这些编码,我打算用这个IP和端口收数据。”

但问题往往就出在这个交换过程中。

30.1.1 编解码器不匹配

这是最常见的错误。发起方说“我支持H.264和VP8”,接收方说“我只支持VP9”。结果就是——谁也说服不了谁。

典型表现: 视频通道建立成功,但一直黑屏或花屏。

排查方法: 抓取双方的SDP,对比 m=video 行中的 rtpmap 字段。

我遇到过的一个案例: 有一次,Chrome和Safari之间视频不通。查了半天,发现Safari只支持H.264,而Chrome默认优先使用VP8。解决方案是在Chrome端强制指定H.264编码。

30.1.2 ICE候选者不完整

ICE(Interactive Connectivity Establishment)负责找到双方都能用的网络路径。如果SDP里缺少候选者,连接就会失败。

典型表现: 媒体通道状态一直是 checking,然后超时。

排查方法: 检查SDP中的 a=candidate 行。正常情况下,至少应该有host、srflx、relay三种类型中的一种。

注意: 如果SDP里只有host类型的候选者,说明双方必须在同一个局域网内才能通信。跨公网时,必须要有srflx或relay候选者。

30.1.3 SSRC冲突

SSRC(同步源标识符)用于区分不同的媒体流。如果两个流用了相同的SSRC,接收端就会混乱。

典型表现: 音频或视频出现卡顿、跳帧。

排查方法: 在SDP中查找 a=ssrc: 字段,确保每个流的SSRC是唯一的。

30.2 日志分析技巧:从海量日志中捞出关键信息

WebRTC的日志量非常大。如果不掌握技巧,你会被淹没在信息的海洋里。我个人习惯用以下三个步骤来快速定位问题。

30.2.1 开启详细日志

在Chrome中,可以通过 chrome://webrtc-internals 查看实时日志。这里能看到所有PeerConnection的状态变化、SDP交换过程、ICE连接状态等。

小技巧: 我建议在测试时,把 chrome://webrtc-internals 的页面录屏。这样事后回放,能清楚看到每一步的变化。

30.2.2 关注关键事件

日志中,有几个事件是必须关注的:

  • oniceconnectionstatechange: 连接状态变化。从 checkingconnected 是正常的;如果变成 failed,说明ICE协商失败。
  • onaddstream / ontrack: 媒体流是否成功添加。如果没触发,说明SDP中的媒体描述有问题。
  • onsignalingstatechange: 信令状态变化。如果卡在 have-local-offerhave-remote-offer,说明SDP交换没完成。

30.2.3 使用过滤关键词

在日志中搜索以下关键词,能快速定位问题:

  • “Failed to set”:SDP设置失败,通常是因为格式错误或不兼容。
  • “ICE failed”:ICE连接失败,需要检查网络或STUN/TURN服务器。
  • “No common codecs”:没有共同的编解码器。
我曾经遇到的一个坑: 有一次,日志里一直报“Failed to set remote offer sdp”。查了半天,发现是SDP中的 a=ice-ufrag 字段拼写错误。少了一个字母,导致整个SDP被拒绝。

30.3 Wireshark抓包分析:从网络层面看透问题

有时候,应用层的日志看不出问题,那就得从网络层面下手。Wireshark是我最常用的工具。

30.3.1 抓取SDP包

SDP通常通过信令通道传输,比如WebSocket或HTTP。在Wireshark中,可以过滤 websockethttp 协议,找到包含SDP的包。

关键字段:

  • o=:会话发起者信息,包含会话ID和版本号。
  • m=:媒体描述,包含媒体类型(audio/video)和端口号。
  • a=:属性行,包含编解码器、ICE候选者、SSRC等信息。

30.3.2 分析ICE连接

ICE使用STUN和TURN协议进行连接。在Wireshark中,可以过滤 stunturn 协议。

重点关注:

  • STUN Binding Request/Response:检查是否成功获取到公网IP和端口。
  • ICE Connectivity Check:检查候选者对是否匹配。
  • STUN Error Response:如果收到错误响应,说明网络有问题。
注意: 如果抓包时发现STUN请求没有响应,很可能是防火墙或NAT设备阻断了UDP流量。这时候可以考虑使用TURN中继。

30.3.3 检查RTP/RTCP流

媒体协商成功后,RTP/RTCP包就开始传输了。在Wireshark中,可以过滤 rtprtcp 协议。

关键指标:

  • SSRC:确认RTP流对应的SSRC是否与SDP中一致。
  • Payload Type:确认编码类型是否与协商的一致。
  • Sequence Number:检查是否有丢包或乱序。
小技巧: 我习惯在Wireshark中设置 rtp 的着色规则。这样一眼就能看出哪些包是RTP,哪些是RTCP,方便快速定位问题。

30.4 知识体系图:媒体协商调试全景

下面这张图,是我根据多年经验总结的媒体协商调试流程。你可以把它当作一个检查清单,遇到问题时按图索骥。

媒体协商调试全景图 问题现象 黑屏/无声/卡顿 SDP检查 编解码器/ICE候选者/SSRC 日志分析 webrtc-internals Wireshark抓包分析 SDP包 / STUN / RTP流 常见问题与解决方案 • 编解码器不匹配 → 强制指定编码 • ICE候选者不完整 → 检查STUN/TURN配置 • SSRC冲突 → 重新生成SSRC • 防火墙阻断 → 使用TURN中继

30.5 实战案例:一次完整的排错过程

说了这么多理论,咱们来一个真实的案例。我记得有一次,一个客户反馈说视频通话经常断连,每次持续几分钟就断了。

第一步:查看日志

打开 chrome://webrtc-internals,发现ICE连接状态频繁在 connecteddisconnected 之间切换。这说明网络不稳定。

第二步:抓包分析

用Wireshark抓包,过滤 stun 协议。发现STUN Binding Request的响应时间越来越长,最后超时。这说明STUN服务器可能有问题。

第三步:检查配置

查看SDP中的 a=candidate 行,发现只有host和srflx类型的候选者,没有relay类型的。这意味着没有配置TURN服务器。

解决方案: 在ICE配置中添加TURN服务器。配置完成后,断连问题彻底解决。

经验总结: 很多网络问题,其实都是因为缺少TURN中继。我建议在生产环境中,一定要配置至少一个TURN服务器作为兜底方案。

30.6 调试工具推荐

最后,分享几个我常用的调试工具:

工具 用途 推荐指数
chrome://webrtc-internals 实时查看PeerConnection状态 ⭐⭐⭐⭐⭐
Wireshark 网络层抓包分析 ⭐⭐⭐⭐⭐
trickle-ICE 测试ICE候选者连通性 ⭐⭐⭐⭐
WebRTC Troubleshooter 在线诊断工具 ⭐⭐⭐⭐
我的习惯: 每次调试前,我都会先打开 chrome://webrtc-internals 和Wireshark。一个看应用层,一个看网络层,双管齐下,问题基本跑不掉。

好了,关于媒体协商的调试与排错,今天就聊到这里。记住,遇到问题别慌,按照SDP检查→日志分析→Wireshark抓包的顺序来,大部分问题都能解决。

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