7、SDP 调试:在 webrtc-internals 中查看 SDP Offer/Answer,分析编解码器协商结果。
说实话,很多做 WebRTC 的同学,遇到音视频不通的第一反应就是去翻日志、打 console。但我要说,你错过了一个宝藏——webrtc-internals。这个 Chrome 自带的内部页面,能直接把 SDP Offer/Answer 的完整内容甩在你面前。我当年排查一个跨浏览器互通问题,就是靠它一眼看出了编解码器优先级不匹配的猫腻。
今天我们就来聊聊,怎么在 webrtc-internals 里看 SDP,以及如何分析编解码器协商结果。嗯,这活儿其实不难,但细节挺多。
7.1 打开 webrtc-internals
先说说怎么进这个页面。你只需要在 Chrome 地址栏输入:
chrome://webrtc-internals
回车之后,你会看到一个实时更新的调试面板。它会把当前页面所有的 PeerConnection 状态都列出来。我个人习惯是,在打开这个页面的同时再发起通话,这样能抓到完整的协商过程。
7.2 找到 SDP 信息的位置
进入 webrtc-internals 后,你会看到左侧有一列 PeerConnection 实例。点击任意一个,右侧会展示一大堆数据。往下翻,找到 "SDP" 相关的区域。
这里通常会有两个关键字段:
- createOffer / createAnswer:显示本地生成的 SDP
- setLocalDescription / setRemoteDescription:显示实际设置到连接中的 SDP
我建议你直接看 setLocalDescription 和 setRemoteDescription,因为这才是真正生效的 SDP。有时候你生成的 Offer 和最终设置的会有细微差别,比如 ICE 候选被过滤了。
7.3 解读 SDP 中的编解码器信息
拿到 SDP 文本后,重点看 m= 行。这是媒体描述行,格式大概是:
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 127 125 124 114
这一行后面的数字,就是 RTP payload type。每个数字对应一种编解码器。具体对应关系,往下看 a=rtpmap 行:
a=rtpmap:96 VP8/90000
a=rtpmap:97 rtx/90000
a=rtpmap:98 VP9/90000
a=rtpmap:99 H264/90000
你看,96 是 VP8,98 是 VP9,99 是 H264。这里要注意,数字的顺序就是优先级顺序。排在越前面的,浏览器越倾向于使用它。
7.4 分析协商结果是否正常
拿到双方的 SDP 后,怎么判断协商是否成功?我一般看三点:
- 是否有共同的编解码器:Offer 里列了一堆,Answer 里只保留双方都支持的。如果 Answer 的 m= 行后面只剩一个数字,说明只协商成功了一种。
- 实际使用的编解码器:看 Answer 中 m= 行的第一个数字。比如 Answer 里是
m=video 9 UDP/TLS/RTP/SAVPF 96,那最终用的就是 VP8。 - 是否有异常参数:比如 H264 的 profile-level-id 不匹配,会导致黑屏。我遇到过好几次,Offer 里写的是
a=fmtp:99 profile-level-id=42e01f,但 Answer 里变成了42e00d,结果视频就是出不来。
7.5 实战:用 SDP 分析编解码器优先级
假设你希望优先使用 H264,但实际协商出来却是 VP8。怎么查?
第一步,看 Offer 中 m= 行的顺序。如果 H264 的 payload type 排在 VP8 后面,那浏览器默认就会优先选 VP8。你需要调整 Offer 的生成逻辑,或者通过 RTCRtpSender.setParameters() 来指定。
第二步,看 Answer 中是否真的包含了 H264。有时候远端设备不支持 H264,那 Offer 里排再前面也没用。这时候 webrtc-internals 里会显示 Answer 的 m= 行里没有 H264 的 payload type。
第三步,检查是否有 a=extmap 或 a=ssrc 行被丢弃。有些浏览器或网关会过滤掉不认识的扩展头,导致协商结果和预期不符。
7.6 用 SVG 梳理 SDP 协商流程
下面这张图,是我自己总结的 SDP 编解码器协商的核心逻辑。你看一眼,应该就能明白整个过程。
7.7 常见问题与排查思路
最后,我整理了几个我在项目中遇到过的典型问题,你可以对照着排查:
| 现象 | SDP 中可能的原因 | 排查方法 |
|---|---|---|
| 视频黑屏但音频正常 | H264 profile-level-id 不匹配 | 对比 Offer/Answer 的 fmtp 行 |
| 协商出来的编解码器不是期望的 | Offer 中优先级顺序不对 | 调整 m= 行 payload type 顺序 |
| 一方收不到视频流 | Answer 中缺少对应的 payload type | 检查 Answer 的 m= 行是否包含该编解码器 |
| 视频花屏或马赛克 | rtx 或 fec 参数缺失 | 查看 a=rtpmap 中是否有 rtx 和 red |
嗯,说白了,SDP 调试就是一场「找不同」的游戏。你把 Offer 和 Answer 并排放在一起,一行一行对比,总能发现问题。我个人习惯是把两段 SDP 复制到文本对比工具里,比如 Beyond Compare 或者 VS Code 的 Diff 插件,效率会高很多。
grep -E "^(m=|a=rtpmap)" sdp.txt
好了,关于 SDP 调试和编解码器分析,今天就聊到这儿。记住,webrtc-internals 是你最好的朋友,别只把它当摆设。下次遇到音视频问题,先打开它看看 SDP,说不定问题就迎刃而解了。