会话描述协议(Session Description Protocol 或简写 SDP)描述的是流媒体的初始化参数。此协议由 IETF 发表为 RFC 2327。

SDP 完全是一种会话描述格式,它不属于传输协议。

SDP 用于描述多媒体通信会话,包括会话建立、会话请求和参数协商。SDP 不用于传输媒体数据,只能用于两个通信终端的参数协商,包括媒体类型、格式以及所有其他和会话相关的属性。SDP 以字符串的形式描述上述初始化参数。

一、SDP 组成

SDP 是由多行文本组成的一个纯文本协议,如果将SDP从语义上分解成不同组件来描述一个多媒体会话信息,那么SDP由以下部分组成:

  • 会话信息
  • 网络信息
  • 媒体信息
  • 安全信息
  • 服务质量和分组信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

+---------------------+
| v= |
+---------------------+
+---------------------+ +---------------------+
==== | Session Metadata | ===== | o= |
| +---------------------+ +----------------------
| +---------------------+
| | t= |
| +---------------------+
|
|
| +---------------------+
| | c= |
| +---------------------+
| +---------------------+
==== | Network Description | =====
| +---------------------+
| +---------------------+
| | a=candidate |
| +---------------------+
|
|
| +---------------------+
| | m= |
| +---------------------+
| +---------------------+ +---------------------+
==== | Stream Description | ===== | a=rtpmap |
| +---------------------+ +----------------------
| +---------------------+
| | a=fmtp |
| +---------------------+
| +---------------------+
| | a=sendrecv.. |
| +---------------------+
+---------------+
| SEMANTIC |
| COMPONENTS OF |
| SDP |
+---------------+
| +---------------------+
| | a=crypto |
| +---------------------+
| +---------------------+ +---------------------+
==== |Security Descriptions| =====| a=ice-frag |
| +---------------------+ +----------------------
| +---------------------+
| | a=ice-pwd |
| +---------------------+
| +---------------------+
| | a=fingerprint |
| +---------------------+
|
|
|
| +---------------------+
| | a=rtcp-fb |
| +---------------------+
| +---------------------+ +---------------------+
==== | Qos,Grouping | | |
| Descriptions | =====| a=group |
+---------------------+ +----------------------
+---------------------+
| a=rtcpmux |
+---------------------+

二、SDP 格式

SDP 由多行组成,每行的的格式如下:

1
<type>=<value>
  • <type>: 区分大小写,代表特定的属性,例如v代表 SDP 版本。
  • <value>:UTF8 编码的文本,具体格式与类型有关。
  • =两边不允许存在空格。
  • =*表示该项是可选的。

下面是 WebRTC(branch_76)的一个真实 SDP 样本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// -------------------------------- 【Session Metadata部分】 --------------------------------

// sdp版本号
v=0

// o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
// username如何没有使用-代替,3967017503571418851是整个会话的编号,2代表会话版本,如果在会话过程中有改变编码之类的操作,重新生成sdp时,sess-id不变,sess-version加1
o=- 3967017503571418851 2 IN IP4 127.0.0.1

//会话名
s=-

// 会话的起始时间和结束时间,0代表没有限制
t=0 0

// 表示需要共用一个传输通道传输的媒体,通过ssrc进行区分不同的流。如果没有这一行,音视频数据就会分别用单独udp端口来发送.
a=group:BUNDLE audio video

// WMS是WebRTC Media Stream简称;
// 这一行定义了本客户端支持同时传输多个流,一个流可以包括多个track.
// 一般定义了这个,后面a=ssrc这一行就会有msid,mslabel等属性.
a=msid-semantic: WMS stream_id


// -------------------------------- 【Stream Description部分】 --------------------------------

// ------------ audio部分 -------------

// m意味着它是一个媒体行.
// m=audio说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中现在一般不使用,如果设置为0,代表不传输音频,
// UDP/TLS/RTP/SAVPF是表示用户支持来传输音频的协议,udp,tls,rtp代表使用udp来传输rtp包,并使用tls加密
// SAVPF代表使用srtcp的反馈机制来控制通信过程
// 后面的111 103 104 9 102 0 8 106 105 13 110 112 113 126表示本会话音频支持的编码,后面几行会有详细补充说明.
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 0 8 106 105 13 110 112 113 126

// 表示你要用来接收或者发送音频使用的IP地址.
// webrtc使用ice传输,不使用这个地址
c=IN IP4 0.0.0.0

// 用来传输rtcp的地址和端口,webrtc中不使用
a=rtcp:9 IN IP4 0.0.0.0

// 下面2行是ice协商过程中的安全验证信息
a=ice-ufrag:kSq0
a=ice-pwd:pWLGrCTwFNq6rm249ZEasHPY

// 通知对端支持trickle,即sdp里面描述媒体信息和ice候选项的信息可以分开传输
a=ice-options:trickle

// dtls协商过程中需要的认证信息
a=fingerprint:sha-256 A0:D6:B2:63:1B:69:0E:91:01:C3:88:A9:92:6F:E7:EF:5B:36:52:66:08:DF:94:A0:FE:0C:C9:06:BF:2C:38:A2

// 代表本客户端在dtls协商过程中,可以做客户端也可以做服务端, 参考rfc4145 rfc4572
a=setup:actpass

// 前面BUNDLE行中用到的媒体标识
a=mid:audio

// 指出要在rtp头部中加入音量信息,参考 rfc6464
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level

// 指出是双向通信,另外几种类型是recvonly,sendonly,inactive
a=sendrecv

// 指出rtp,rtcp包使用同一个端口来传输
a=rtcp-mux

// 下面十几行都是对m=audio这一行的媒体编码补充说明,指出了编码采用的编号,采样率,声道等
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
// 下面一行对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/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
// cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,用于音视频同步
a=ssrc:2603526440 cname:AyMDWB+q6ApWdpfU
a=ssrc:2603526440 msid:stream_id audio_label
a=ssrc:2603526440 mslabel:stream_id
a=ssrc:2603526440 label:audio_label



// ------------ video部分 -------------

m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:kSq0
a=ice-pwd:pWLGrCTwFNq6rm249ZEasHPY
a=ice-options:trickle
a=fingerprint:sha-256 A0:D6:B2:63:1B:69:0E:91:01:C3:88:A9:92:6F:E7:EF:5B:36:52:66:08:DF:94:A0:FE:0C:C9:06:BF:2C:38:A2
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 red/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 ulpfec/90000
a=ssrc-group:FID 1563406656 4103641903
a=ssrc:1563406656 cname:AyMDWB+q6ApWdpfU
a=ssrc:1563406656 msid:stream_id video_label
a=ssrc:1563406656 mslabel:stream_id
a=ssrc:1563406656 label:video_label
a=ssrc:4103641903 cname:AyMDWB+q6ApWdpfU
a=ssrc:4103641903 msid:stream_id video_label
a=ssrc:4103641903 mslabel:stream_id
a=ssrc:4103641903 label:video_label

2.1 协议版本

第一行v=0定义了 sdp 协议的版本号。

2.2 会话发起者

第二行

1
o=- 3967017503571418851 2 IN IP4 127.0.0.1

定义了会话发起者的信息,格式如下:

1
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
  • username:发起者的用户名,不允许存在空格,如果应用不支持用户名,则为-
  • sess-id:会话 id,由应用自行定义,SDP 规范建议使用 NTP(Network Time Protocol)时间戳。
  • sess-version:会话版本,用途由应用自行定义,只要会话数据发生变化时(比如编码)sess-version 随着递增即可。SDP 规范建议使用 NTP 时间戳。
  • nettype:网络类型,比如 IN 表示 Internet。
  • addrtype:地址类型,比如 IP4、IV6
  • unicast-address:域名,或者 IP 地址。

2.3 会话名

1
s=<session name>

必选,有且仅有一个s=字段,且不能为空。可以赋一个空格(即s= ),或者-

2.4 连接信息

1
c=<nettype> <addrtype> <connection-address>

每个 SDP 至少需要包含一个会话级别c=字段,或者在每个媒体描述后面各包含一个c=字段,(媒体描述后的c=会覆盖会话级别的c=)。例如,在上面的示例 SDP 样本中,就不存在会话级别的连接信息。

  • nettype:网络类型,比如 IN,表示 Internet。
  • addrtype:地址类型,比如 IP4、IP6。
  • connection-address:如果是广播,则为广播地址组;如果是单播,则为单播地址;

2.4.1 何为会话级别和媒体级别

会话级部分以v =行开始,到第一个媒体级部分结束。
每个媒体级部分以m =行开始,持续到下一个媒体级(即下一个m=)。

2.5 媒体描述信息

SDP 可以同时包含多个媒体描述信息(如音频、视频等),格式如下:

1
m=<media> <port> <proto> <fmt> ...

示例:

1
2
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
  • media:媒体类型,包括 video、audio、text、application、message 等。
  • port:传输媒体流使用的端口,具体含义取决于使用的网络类型(在c=中声明)和使用的传输协议(proto)。
  • proto:传输协议,具体含义取决于c=中定义的地址类型,比如c=IP4,那么这里的传输协议运行在 IP4 之上。
  • fmt:媒体格式的描述,可能有多个。根据proto的不同,fmt的含义也不同。比如proto为 RTP/SAVP 时,fmt 表示 RTP payload 的类型。如果有多个,表示在这次会话中,多种 payload 类型可能会用到,且第一个为默认的 payload 类型
    数字0~95是静态负载类型;96~127是动态负载类型,需要在后面使用附近属性a = rtpmap:指定具体的格式参数。具体的每个数字代表的负载类型和含义可以参考:Real-Time Transport Protocol (RTP) Parameters
    如上例中的 audio 类型的111表示使用 opus 编码。

2.6 附加属性

附加属性用于扩展 SDP,有 2 种作用范围:会话级别、媒体级别:

  • 媒体级别:媒体描述(m=)后面可以跟任意数量的 a= 字段,对媒体描述进行扩展。
  • 会话级别:在第一个媒体字段(media field)前,添加的 a= 字段是会话级别的。

有下面 2 种格式:

1
2
a=<attribute>
a=<attribute>:<value>

2.7 时间

用于声明会话的开始、结束时间,格式如下:

1
t=<start-time> <stop-time>

如果<stop-time>是 0,表示会话没有结束的边界,但是需要在<start-time>之后会话才是活跃(active)的;如果<start-time>是 0,表示会话是永久的。

SDP for the WebRTC > WebRTC:会话描述协议 SDP > WebRTC 中的 SDP 协议