本文目录导读:

SDP 是一种格式,用于描述多媒体会话的初始化参数,它本身不传输媒体数据,而是告诉通信的双方:“我们即将开始的通话/视频会议将使用什么格式、什么编码、什么网络地址和端口。”。
SDP 描述的核心信息可以概括为以下几点:
- 会话元信息:会话的名称、目的、发起者、活跃时间等。
- 网络信息:媒体数据要发送到哪里(IP 地址、端口号)。
- 媒体信息:要传输什么类型的媒体(音频、视频、文本等)。
- 编码信息:使用哪种编解码器(H.264 视频、Opus 音频)、采样率、比特率等。
- 传输协议:使用什么协议来传输媒体数据(RTP/AVP、RTP/SAVP)。
SDP 的工作原理(通常与信令协议配合)
SDP 通常作为信令协议(如 SIP、WebRTC 中的信令通道、RTSP)的 payload(负载)进行交换,工作流程大致如下:
- 提议(Offer):发起方 A 创建一个 SDP 描述(Offer),描述它希望如何建立会话,这个 Offer 包含它支持的所有功能(例如多种编码解码器、不同的网络端口)。
- 应答(Answer):接收方 B 收到 Offer 后,解析 SDP 内容,选择其中它支持的、最好的组合(例如从 A 支持的编解码器中选择一个),然后生成一个 SDP 应答(Answer)。
- 建立会话:双方都收到并解析了对方的 SDP 后,就明确了媒体流的方向、地址、端口和编码方式,然后开始实际的媒体数据传输。
SDP 的文本格式与关键字段
SDP 描述是一个纯文本的、由多行组成的结构,每行都以一个单字母的类型开头,后面跟着等号 和具体的值,行与行之间没有严格的顺序要求(除了会话级和媒体级描述的顺序),但通常按照逻辑排列。
一个典型的 SDP 描述长这样:
v=0
o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
s=SDP Seminar
i=A Seminar on the Session Description Protocol
u=http://www.example.com/seminars/sdp.pdf
e=j.doe@example.com (Jane Doe)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 99
a=rtpmap:99 h264/90000
我们逐个解释这些关键行:
会话级描述(Session-level description)
这些行影响整个会话。
v=0(Version): SDP 协议的版本,目前一直是 0。o=<username> <session-id> <version> <network-type> <address-type> <unicast-address>(Origin): 会话的发起者和唯一标识。o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5jdoe:用户名。2890844526:会话 ID(全局唯一)。2890842807:版本号(每次修改会递增)。IN:网络类型(Internet)。IP4:地址类型。47.16.5:发起者的 IP 地址。
s=<session-name>(Session Name): 会话名称,通常是必填的,s=SDP Seminar。i=<session-information>(Information): 会话描述信息(可选)。u=<uri>(URI): 指向更多信息的 URI(可选)。e=<email-address>(Email): 负责人的电子邮件(可选)。c=<network-type> <address-type> <connection-address>(Connection Information): 默认的连接地址,如果媒体描述里没有自己的c=行,就使用这个,可以是单播地址或组播地址。c=IN IP4 224.2.17.12/127(组播地址)
t=<start-time> <stop-time>(Time): 会话的活跃时间,通常是 NTP 时间戳,0 0表示不限制时间。t=2873397496 2873404696。a=<attribute>(Attribute): 扩展属性,非常重要的字段,可以是会话级,也可以是媒体级。a=recvonly(只接收)a=sendrecv(发送和接收 - 默认)a=sendonly(只发送)a=inactive(不激活)a=group:<group-type>(用于将多个媒体流分组)
媒体级描述(Media-level description)
这些行描述一个具体的媒体流(如音频流、视频流),一个会话可以有多个媒体描述块,每个块以 m= 行开始。
-
m=<media-type> <port> <transport-protocol> <fmt-list>(Media Description): 媒体描述。m=audio 49170 RTP/AVP 0audio:媒体类型(音频)。49170:接收媒体数据的端口号。RTP/AVP:传输协议(RTP over UDP,使用 AVP profile)。0:payload 类型号,此处0对应 PCMU(G.711 mu-law)音频。
m=video 51372 RTP/AVP 99video:媒体类型(视频)。51372:端口号。RTP/AVP:传输协议。99:一个动态 payload 类型号,需要通过后面的a=rtpmap具体定义。
-
a=rtpmap:<payload-type> <encoding-name>/<clock-rate>[/<encoding-parameters>](RTP Mapping): 将动态 payload 类型号映射到具体的编解码器。a=rtpmap:99 h264/90000- 这表示 payload 类型
99对应 H.264 视频编码,时钟频率为 90000 Hz(视频的标准时钟频率)。
- 这表示 payload 类型
- 对于音频,可能这样:
a=rtpmap:96 opus/48000(Opus 编码,48kHz 采样)a=rtpmap:0 PCMU/8000(静态 payload 类型0通常不需要指定,但也可以写出来)
-
a=fmtp:<payload-type> <format-specific-parameters>(Format Parameters): 编解码器的特定参数。a=fmtp:99 profile-level-id=42e01f;packetization-mode=1这指定了 H.264 使用的 profile 层级和打包模式。
-
a=sendrecv/a=recvonly/a=sendonly/a=inactive: 这些属性可以出现在媒体级,定义该媒体流的方向。 -
a=ptime:<packet-time>: 建议的媒体包时间(毫秒),用于音频。 -
a=maxptime:<max-packet-time>: 允许的最大媒体包时间。 -
a=candidate:<...>(ICE Candidates): 在 WebRTC 等场景中,用于 ICE(交互式连接建立)协议,提供可能的网络路径信息。 -
a=ice-ufrag:<username-fragment>和a=ice-pwd:<password>: ICE 的身份验证信息。 -
a=fingerprint:<hash-function> <fingerprint>: DTLS(数据包传输层安全性)指纹,用于安全认证。 -
a=setup:<role>: 在 DTLS-SRTP 握手中的角色 (active,passive,actpass)。 -
a=mid:<identification-tag>: 媒体流标识符,用于关联不同的媒体 (如音频和视频)。 -
a=group:<group-type> <mid-1> <mid-2>...: 将多个媒体流(通过a=mid定义)分组,例如在 FID(流隔离)或 BUNDLE(多个流复用同一 RTP 会话)中。
完整的例子
一个更复杂的 WebRTC 风格的 SDP Offer 例子:
v=0
o=- 4611123934502425859 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:uhs9
a=ice-pwd:yj5k8x6l2h8l4h3l2h8l4h3l2h8l4h3
a=fingerprint:sha-256 1A:2B:3C:4D:5E:6F:... :AB:CD
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ptime:20
a=maxptime:60
m=video 9 UDP/TLS/RTP/SAVPF 100 101 102 96 97 98
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:uhs9
a=ice-pwd:yj5k8x6l2h8l4h3l2h8l4h3
a=fingerprint:sha-256 1A:2B:3C:4D:5E:6F:... :AB:CD
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=sendrecv
a=rtcp-mux
a=rtpmap:100 VP8/90000
a=rtpmap:101 VP9/90000
a=rtpmap:102 H264/90000
a=rtpmap:96 H265/90000
a=rtpmap:97 AV1/90000
a=rtpmap:98 theora/90000
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 profile-level-id=42e01f;level-asymmetry-allowed=1
关键解读:
a=group:BUNDLE audio video:这是 BUNDLE 机制,将音频和视频两个媒体流复用在一个 RTP 会话中。m=audio 9 UDP/TLS/RTP/SAVPF ...:音频媒体,端口9是占位符,实际通过 ICE 协商。UDP/TLS/RTP/SAVPF表示使用 DTLS-SRTP 加密后的 RTP,后面跟着一堆支持的 payload 类型。m=video 9 UDP/TLS/RTP/SAVPF ...:视频媒体,同样使用端口9(BUNDLE)。a=ice-ufrag和a=ice-pwd:ICE 凭据,用于连通性检查。a=fingerprint:DTLS 指纹,用于建立安全通道。a=setup:actpass:在 DTLS-SRTP 握手中,本端可以充当客户端(active)或服务端(passive),由对端决定。a=rtpmap:111 opus/48000/2:定义了 payload 111 是 Opus 编码,48kHz采样,2个声道。a=fmtp:111 minptime=10;useinbandfec=1:Opus 的具体参数:最小包时长 10ms,支持带内前向纠错。a=rtcp-fb:100 nack pli:请求发送方对 VP8 (payload 100) 启用 NACK 反馈,特别是 Picture Loss Indication (PLI) 请求。a=fmtp:102 profile-level-id=42e01f;level-asymmetry-allowed=1:H.264 (payload 102) 的特定参数,指定 profile 和级别。
SDP 的工作流程总结(以 WebRTC 为例)
- 发起方(Offerer):
- 创建一个 Offer SDP,列出它支持的编解码器、网络偏好、安全信息等。
- 通过信令通道(如 WebSocket)将 Offer 发送给接收方。
- 接收方(Answerer):
- 收到 Offer,解析它。
- 生成一个 Answer SDP,从 Offer 中选出它支持的最佳组合(比如共用 Opus 音频和 VP8 视频)。
- Answerer 也会添加自己的 ICE 候选地址、DTLS 指纹等信息。
- 通过信令通道将 Answer 发送回发起方。
- ICE 协商:
- 双方交换 ICE 候选地址(
a=candidate)。 - 通过 STUN 或 TURN 服务器尝试建立直接或中转的 UDP 连接。
- 双方交换 ICE 候选地址(
- DTLS 握手:
- 一旦 UDP 连接建立,双方通过 DTLS 进行握手,验证
a=fingerprint,建立加密通道。
- 一旦 UDP 连接建立,双方通过 DTLS 进行握手,验证
- SRTP 加密媒体传输:
- DTLS 握手完成后,生成 SRTP (安全实时传输协议) 密钥。
- 双方开始通过建立的加密通道发送和接收 RTP 媒体数据包。
关键点回顾
- 描述性,非传输性:SDP 只描述会话,不传输媒体数据。
- 提议/应答模型:核心是“提议”和“应答”的协商过程。
- 文本格式:易于人类阅读和调试。
- 可扩展性:通过
a=属性行,可以向 SDP 添加各种扩展(如 ICE, DTLS, RTCP-FB 等)。 - 与信令协议绑定:SDP 通常被封装在 SIP, WebRTC 信令, RTSP 等协议中传输。
希望这个详细的解释能帮助你理解 SDP 是如何描述会话的,如果你有更具体的问题(例如某个特定字段的含义),欢迎继续提问。
标签: 会话描述