一、SDP协议概述:一场通话的“自我介绍”

SDP,全称Session Description Protocol,会话描述协议。名字挺长,但说白了,它就是一份“通话说明书”。

我刚开始接触WebRTC时,总觉得SDP很神秘。后来发现,它其实就是一段纯文本,描述了“我想怎么跟你通话”。

举个例子。你打电话给对方,总得告诉对方:

  • 我用什么编码?是H.264还是VP8?
  • 我的IP地址和端口是多少?
  • 我支持哪些音频采样率?

这些信息,全都写在SDP里。没有它,双方根本没法建立连接。

核心要点:SDP不是传输媒体数据的协议,它只负责“协商”。就像两个人见面先握手,SDP就是那个“握手”的动作。

我记得有一次排查一个通话问题,双方都能发SDP,但就是没声音。最后发现,一方说“我用PCMU”,另一方说“我用PCMA”,编码不匹配。嗯,这就是SDP没协商好。

二、SDP的会话描述结构:一张清单

SDP的结构,说白了就是一行一行的键值对。每一行以单个字母开头,后面跟着等号和值。

我习惯把SDP想象成一张购物清单:

v=0
o=- 123456 2 IN IP4 192.168.1.1
s=-
t=0 0
m=audio 5004 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
c=IN IP4 192.168.1.1

每一行都有特定含义:

行标识 含义 示例
v= 协议版本 v=0
o= 会话发起者信息 o=- 123456 2 IN IP4 192.168.1.1
s= 会话名称 s=-
t= 会话时间 t=0 0
m= 媒体描述 m=audio 5004 RTP/AVP 0 8
a= 属性行 a=rtpmap:0 PCMU/8000
c= 连接信息 c=IN IP4 192.168.1.1

你想想看,这些信息缺一不可。少了c=行,对方就不知道往哪发数据。少了m=行,连媒体类型都不知道。

个人经验:我在调试时,经常先看m=行和a=行。这两行决定了媒体能否通。如果m=行里没有共同的编码,那基本没戏。

三、Offer/Answer模型:你出价,我还价

WebRTC的媒体协商,用的是Offer/Answer模型。说白了就是:

  1. Offer方:我支持这些能力,你看着办。
  2. Answer方:好,我从你列的能力里挑一个我能用的。

这个过程,我称之为“能力交换”。

具体流程是这样的:

  • 发起方创建Offer SDP,包含自己所有的媒体能力。
  • 接收方收到Offer后,创建Answer SDP,只包含自己支持且Offer里也有的能力。
  • 双方交换SDP后,开始传输媒体。

我曾经遇到过一个坑:Offer方发了10种编码,Answer方只回了1种。结果Offer方以为Answer方会回多种,自己没做降级处理。通话直接失败。

避坑指南:Answer方返回的编码,必须是Offer方列表里的子集。不能自己发明新编码。我曾经见过有人把Answer里的编码顺序改了,结果对方解析出错。

为什么会这样?因为SDP的解析是严格的。你改了顺序,对方可能认为你优先支持某个编码,但实际上你并不支持。

四、媒体能力协商:不只是编码

媒体能力协商,远不止选个编码那么简单。它还涉及:

  • 采样率:音频是8kHz还是48kHz?
  • 声道数:单声道还是立体声?
  • DTX:是否支持不连续传输?
  • FEC:是否支持前向纠错?
  • RTCP:反馈机制怎么配置?

这些信息,都藏在a=行里。比如:

a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10; useinbandfec=1

第一行说:我用Opus编码,48kHz采样率,双声道。

第二行说:最小包时长10毫秒,支持带内FEC。

我个人的习惯是,在Answer里尽量保留Offer里的所有a=行,只修改自己不支持的部分。这样能减少很多兼容性问题。

关键点:媒体能力协商的本质,是双方找到一个“最大公约数”。你支持A、B、C,我支持B、C、D,那我们就用B和C。

嗯,这里要注意:有些能力是“必须”的,有些是“可选”的。比如Opus编码的useinbandfec,如果对方不支持,你也不能强求。

五、SDP协商的完整流程

为了让你更直观地理解,我画了一张流程图:

SDP Offer/Answer 协商流程 发起方 (Offer) 接收方 (Answer) 1. 收集本地媒体能力 1. 等待接收Offer 创建Offer SDP 2. 等待接收Answer 2. 解析Offer,匹配能力 返回Answer SDP 3. 解析Answer,开始传输 3. 开始传输媒体数据 媒体流开始 整个协商过程在信令通道完成,不经过媒体服务器

你看,整个过程其实不复杂。但每一步都有坑。

我记得有一次,Offer方发了SDP后,Answer方迟迟不回。排查发现,是信令服务器把SDP截断了。嗯,SDP是纯文本,但长度可能很大,信令通道要注意分片。

小技巧:调试时,我习惯把SDP打印出来,用眼睛扫一遍。先看m=行,再看a=rtpmap,最后看a=fmtp。基本能定位90%的问题。

六、总结

SDP协议,说白了就是一份“通话说明书”。它用Offer/Answer模型,让双方交换媒体能力,最终找到一个共同支持的配置。

我个人觉得,理解SDP的关键在于:

  • 知道每一行代表什么
  • 明白Offer和Answer的关系
  • 熟悉常见的媒体能力参数

做到这三点,SDP就不再神秘了。

一句话记住:SDP不传媒体,只传“怎么传媒体”的约定。


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