SDP
概念
- SDP 是一种描述多媒体通信会话的文本格式(基于 MIME,RFC 4566)。
- 本身 不传输数据,仅用于在会话建立阶段传递信息。
- 常与 SIP(VoIP)、RTSP、WebRTC 等协议配合使用。
用途
- 描述媒体类型(音频、视频等);
- 指定编解码器、媒体格式;
- 提供媒体的传输信息(IP 地址、端口、传输协议等);
- 协商媒体能力(能力协商);
- 描述时钟信息(同步);
- 支持多路流(多 track)。
结构
字段 | 含义 | 示例 | 说明 |
---|---|---|---|
v= |
协议版本 | v=0 |
始终为 0,表示 SDP 的版本 |
o= |
会话起始者 | o=john 2890844526 2890842807 IN IP4 192.0.2.1 |
包含用户名、会话 ID、版本号、网络类型、地址类型和 IP 地址 |
s= |
会话名称 | s=Example Session |
必填项,但可为任意字符串 |
i= |
会话信息 | i=A demo of SDP |
可选项,对会话的简要描述 |
u= |
URI | u=http://example.com |
可选项,指向更多信息 |
e= |
电子邮件地址 | e=john@example.com |
可选项 |
p= |
电话号码 | p=+1 555 555 5555 |
可选项 |
c= |
连接信息 | c=IN IP4 203.0.113.1 |
指定媒体的传输地址(可用于全局或每个媒体段) |
b= |
带宽信息 | b=AS:2000 |
可选,AS 表示应用带宽,单位 kbps |
t= |
会话活动时间 | t=0 0 |
表示会话起止时间,0 0 表示无限期 |
r= |
重复时间 | r=604800 3600 0 90000 |
可选项,描述周期性会话 |
z= |
时区调整 | z=2882844526 -3600 2898848070 0 |
可选项,调整为夏令时等 |
k= |
加密密钥 | k=clear:password |
已弃用,不推荐使用 |
a= |
属性字段 | 多种形式 | 详见下文“属性字段详解” |
m= |
媒体信息 | m=audio 49170 RTP/AVP 0 |
定义媒体类型、端口、传输协议和 payload type |
y= |
会话标识符(非标准) | - | 某些系统私有扩展 |
f= |
格式参数(非标准) | - | 某些系统私有扩展 |
WebRTC中的SDP
在 WebRTC 中,SDP(Session Description Protocol) 是用于完成多媒体会话协商的关键格式,尽管 WebRTC 本身并不强依赖 SDP 协议(也有 ORTC 替代方案),但当前主流实现如 Chrome、Firefox、Safari 都基于 SDP 的 Offer/Answer 模型进行媒体协商。
基本结构
WebRTC 中 SDP 文本结构遵循 SDP 规范(RFC 4566)+ 一些扩展,主要由两部分组成:
- Session-level(全局)字段:描述整个会话的元数据;
- Media-level 字段:每个音频、视频流的参数(每个 m= 开头段落)。
常见结构如下:
v=0 # SDP版本
o=- 12345 2 IN IP4 0.0.0.0 # 会话起始者
s=- # 会话名(必须字段)
t=0 0 # 时间
a=group:BUNDLE 0 1 # BUNDLE分组
a=msid-semantic: WMS # Media Stream 语义
m=audio 9 UDP/TLS/RTP/SAVPF 111
...
m=video 9 UDP/TLS/RTP/SAVPF 96
...
SDP字段
会话级别字段(Session-Level)
字段 | 示例 | 说明 |
---|---|---|
v= |
v=0 |
版本号,固定为 0 |
o= |
o=- 123456 2 IN IP4 127.0.0.1 |
会话拥有者:用户名、会话ID、版本、IP等 |
s= |
s=- |
会话名,必须存在但可为 - |
t= |
t=0 0 |
时间,0 0 表示永远有效 |
a=group:BUNDLE 0 1 |
表示将 media MID 为 0 和 1 的媒体复用到一个 DTLS/ICE 通道 | |
a=msid-semantic: WMS |
表示支持 MediaStream 概念 | |
a=ice-lite |
某些场景中表示是 ICE Lite 模式的端(如 SFU) |
媒体描述字段(Media-Level)
m= 行:媒体定义
m=audio 9 UDP/TLS/RTP/SAVPF 111
含义:
audio
:媒体类型9
:端口(通常为 9,占位,由 ICE 协商真实端口)UDP/TLS/RTP/SAVPF
:传输协议,表示使用 SRTP over DTLS111
:payload type,用于后续a=rtpmap
对应实际编解码器
ICE 相关字段(NAT 穿透)
字段 | 示例 | 说明 |
---|---|---|
a=ice-ufrag |
a=ice-ufrag:F7gI |
ICE用户名 |
a=ice-pwd |
a=ice-pwd:x9cml/Yz... |
ICE密码 |
a=candidate: |
a=candidate:1 1 udp 2130706431 192.168.1.2 5000 typ host |
描述网络候选地址(host, srflx, relay) |
a=end-of-candidates |
表示候选地址发送完毕 | |
a=ice-options:trickle |
表示支持 trickle ICE(边发送边收集候选) |
DTLS 安全字段(加密通道)
字段 | 示例 | 说明 |
---|---|---|
a=fingerprint: |
a=fingerprint:sha-256 AB:CD:... |
DTLS 指纹,用于身份验证 |
a=setup: |
a=setup:actpass |
指示 DTLS 握手的角色:active / passive / actpass (默认) |
媒体流属性
字段 | 示例 | 说明 |
---|---|---|
a=mid:0 |
媒体 ID,与 group:BUNDLE 搭配使用 |
|
a=sendrecv |
表示媒体方向,其他有 sendonly , recvonly , inactive |
|
a=rtpmap: |
a=rtpmap:111 opus/48000/2 |
映射 Payload Type 到 编解码器名称 |
a=fmtp: |
a=fmtp:111 minptime=10;useinbandfec=1 |
格式参数(如 Opus 的 FEC) |
a=rtcp-mux |
表示 RTP 和 RTCP 使用同一端口 | |
a=rtcp-rsize |
表示使用 Reduced-Size RTCP |
媒体同步与标识
字段 | 示例 | 说明 |
---|---|---|
a=msid:stream1 track1 |
MediaStream ID 和 Track ID,用于 Web 应用层标识流 | |
a=ssrc:<ssrc-id> cname:<value> |
a=ssrc:1234 cname:abcd |
标识 RTP 流的同步源 SSRC 及同步名字 |
a=ssrc:<id> msid:<stream-id> <track-id> |
指定 track 对应的 ssrc |
rtpmap
功能
描述 RTP 载荷类型(Payload Type)对应的编解码器信息。
SDP 中的 a=rtpmap
用于将 动态载荷类型(PT)编号 映射到 实际的编解码器名称、采样率、声道数 等信息。
语法格式
a=rtpmap:<payload-type> <codec-name>/<clock-rate>[/<channels>]
作用总结
- 明确指定每个 PT 对应的编解码器;
- 告诉接收方如何解析接收到的 RTP 包;
- 提供采样率和声道信息(音频)或 RTP 时钟频率(视频);
示例
a=rtpmap:111 opus/48000/2
说明 PT 111 表示 Opus 编码,采样率 48kHz,双声道。
fmtp
功能
提供编解码器的格式化参数(Format Parameters)。
SDP 中的 a=fmtp
是 rtpmap
的扩展,用于定义该编解码器的具体参数,如打包方式、Profile、Level、纠错支持等。
语法格式
a=fmtp:<payload-type> <parameter1>=<value1>; <parameter2>=<value2>; ...
作用总结
- 指定编解码器的高级参数;
- 协商功能特性(如 H264 的
packetization-mode
); - 确保发送端和接收端兼容配置,避免播放异常;
示例(H.264):
a=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
含义:
- 允许编码解码器使用不同的 Level;
- 使用 NALU 分片打包方式;
- 使用 H.264 Baseline profile level 3.1
Payload Type列表
Payload Type | Codec | 示例 rtpmap |
示例 fmtp |
用途 |
---|---|---|---|---|
111 |
Opus | a=rtpmap:111 opus/48000/2 |
a=fmtp:111 minptime=10; useinbandfec=1 |
音频,WebRTC 默认 |
103 |
ISAC (16kHz) | a=rtpmap:103 ISAC/16000 |
— | 音频 |
104 |
ISAC (32kHz) | a=rtpmap:104 ISAC/32000 |
— | 音频 |
9 |
G722 | a=rtpmap:9 G722/8000 |
— | 音频(静态) |
0 |
PCMU | a=rtpmap:0 PCMU/8000 |
— | 音频(静态) |
8 |
PCMA | a=rtpmap:8 PCMA/8000 |
— | 音频(静态) |
96 |
VP8 | a=rtpmap:96 VP8/90000 |
— | 视频,兼容性好 |
98 |
VP9 | a=rtpmap:98 VP9/90000 |
a=fmtp:98 profile-id=0 |
视频,高压缩率 |
102 |
H264 | a=rtpmap:102 H264/90000 |
level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f |
视频(通常会配多个) |
109 |
H264 | a=rtpmap:109 H264/90000 |
同上 | 视频(动态 PT) |
100 |
RTX (VP8) | a=rtpmap:100 rtx/90000 |
a=fmtp:100 apt=96 |
VP8 重传流 |
101 |
Telephone-event | a=rtpmap:101 telephone-event/8000 |
— | DTMF |
示例
v=0
o=private 51472368 2 IN IP4 0.0.0.0
s=PlaySession
t=0 0
a=ice-lite
a=group:BUNDLE 0 1
a=msid-semantic: WMS live/xxx
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=ice-ufrag:02150669
a=ice-pwd:xxx
a=fingerprint:sha-256 3C:BF:C9:FA:D7:BD:14:F5:99:EA:11:0E:4D:80:70:FA:B0:58:FC:95:B2:C3:52:47:87:83:4E:CF:8A:C8:79:1F
a=setup:passive
a=mid:0
a=sendonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:111 opus/48000/2
a=ssrc:849342908 cname:zzz
a=ssrc:849342908 label:audio-41rt248x
a=candidate:0 1 udp 2130706431 112.118.101.218 16938 typ host generation 0
a=candidate:1 1 udp 2130706431 127.0.0.1 16938 typ host generation 0
a=candidate:2 1 udp 2130706431 112.20.4.5 16938 typ host generation 0
m=video 9 UDP/TLS/RTP/SAVPF 109
c=IN IP4 0.0.0.0
a=ice-ufrag:02150669
a=ice-pwd:xxx
a=fingerprint:sha-256 3C:BF:C9:FA:D7:BD:14:F5:99:EA:11:0E:4D:80:70:FA:B0:58:FC:95:B2:C3:52:47:87:83:4E:CF:8A:C8:79:1F
a=setup:passive
a=mid:1
a=sendonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:109 H264/90000
a=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=ssrc:849342909 cname:xxx
a=ssrc:849342909 label:video-6v319bim
a=candidate:0 1 udp 2130706431 112.118.101.218 16938 typ host generation 0
a=candidate:1 1 udp 2130706431 127.0.0.1 16938 typ host generation 0
a=candidate:2 1 udp 2130706431 112.20.4.5 16938 typ host generation 0
会话级字段(全局)
v=0
- SDP 协议版本,始终为 0。
o=private 51472368 2 IN IP4 0.0.0.0
- o=用户名(private);
- 51472368:会话ID;
- 2:版本号(每次修改递增);
IN IP4 0.0.0.0
:网络类型和地址(一般占位符,实际由 ICE 决定)。
s=PlaySession
- 会话名称,可为任意字符串。
t=0 0
- 表示 SDP 会话有效期为永久(起始时间 = 截止时间 = 0)。
a=ice-lite
- 表示该端是 ICE-lite 模式(常用于服务端,如 SFU,表示只被动响应 ICE 协商,不发起连接)。
a=group:BUNDLE 0 1
- 表示启用 BUNDLE,将 MID 为 0(音频)和 1(视频)的媒体流复用在同一个传输通道上(节省端口/资源)。
a=msid-semantic: WMS live/xxx
- 表示使用 MediaStream 语义,流名为
live/xxx
,供 JavaScript 层识别 track 属于哪个 stream。
音频媒体段(m=audio)
m=audio 9 UDP/TLS/RTP/SAVPF 111
- 音频媒体,端口为占位符
9
(真实由 ICE 协商); UDP/TLS/RTP/SAVPF
:表示使用 DTLS 加密的 SRTP;111
是 payload type,后续用rtpmap
指定编码类型。
c=IN IP4 0.0.0.0
- 网络地址(无实际含义,占位,真实通过 ICE 协议确定)。
a=ice-ufrag:02150669
a=ice-pwd:xxx
- ICE 协商用户名片段和密码,用于 STUN 交互过程。
a=fingerprint:sha-256 3C:BF:...:1F
a=setup:passive
- DTLS 指纹,用于验证传输安全性;
setup:passive
表示此端 不发起 DTLS 握手,对端应 actpass/active。
a=mid:0
- 媒体流的唯一标识(用于 BUNDLE 映射)。
a=sendonly
- 表示此媒体方向是只发送(如服务端推流)。
a=rtcp-mux
a=rtcp-rsize
- 使用 RTP 和 RTCP 端口复用;
- 使用缩减大小的 RTCP(节省带宽)。
a=rtpmap:111 opus/48000/2
111
编解码器为 Opus,48kHz 采样,双声道。
a=ssrc:849342908 cname:xxx
a=ssrc:849342908 label:audio-41rt248x
- SSRC(同步源 ID)= 849342908,用于标识此 RTP 流;
cname
:跨媒体同步标识;label
:track label(供 JS 层识别)。
a=candidate:...112.118.101.218...
- 提供 ICE 候选地址:
typ host
表示本地 IP;- generation 0 表示首次协商;
- 提供了多个候选,包括公网、私网地址。
视频媒体段(m=video)
m=video 9 UDP/TLS/RTP/SAVPF 109
- 视频媒体流,使用 PT = 109;
- 支持 SRTP over DTLS。
a=rtpmap:109 H264/90000
- PT 109 映射为 H.264 编解码器,90kHz 时钟。
a=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
- 描述 H264 的特性参数:
level-asymmetry-allowed=1
:允许解码器水平不对称;packetization-mode=1
:分片模式,必需用于 WebRTC;profile-level-id=42e01f
:表示 Baseline Profile Level 3.1。
a=ssrc:849342909 cname:xxx
a=ssrc:849342909 label:video-6v319bim
- 视频 RTP 流 SSRC;
label
标识该 track。
a=ice-ufrag:02150669
a=ice-pwd:xxx
a=fingerprint:sha-256 ...
- 和音频共享相同的 ICE 参数;
- 多路复用(BUNDLE)场景下,音视频媒体共享 ICE 通道(节省资源)。
a=mid:1
a=sendonly
a=rtcp-mux
mid:1
:媒体 ID;sendonly
:只发送视频;rtcp-mux
:复用 RTP/RTCP;