【网络通信 -- 直播】网络通信协议简介 -- SDP
SDP 协议,会话描述协议(Session Description Protocol),用于描述多媒体会话的协议,主要用于描述需要向对方通告的有关会话特征信息的格式;
【1】SDP 结构
会话级参数,会话中的共性参数,即会话所涉及的所有多媒体信息流都具有的参数类型与参数值,对会话所涉及的所有多媒体信息流起作用;
媒体级参数,会话中的个性参数,即不同的多媒体流具有不同的参数类型与参数值,对会话中特定的多媒体信息流起作用;
SDP 的一般结构如下
【2】SDP 语法
SDP 通过若干个文本行传输会话描述信息,每一文本行格式为"字段=值",其中字段用一个字符表示,值取决于对应的字段,在"字段"与"="之间以及"="与"值"之间不允许插入任何空格;
【2.1】必须字段
字段 | 含义 | 说明 | 补充 |
v | 协议版本号 | 标志某个会话描述结构的开始,以及前一个会话描述结构的结束 | |
o | 会话创建者及会话标识符 | 用于给出会话标识信息 | |
s | 会话名 | 用于显示会话信息 | |
t | 会话时间 | 给定会话开始和结束时间 | |
m | 媒体 | 给定多媒体信息流类型、发送多媒体信息流端口号、传输协议以及多媒体信息流编码格式等 | 可用于标识某个特定媒体描述符的开始; 可用于会话级描述信息和媒体级描述信息之间以及不同媒体描述信息之间的分隔字段; |
【2.2】可选字段
说明,若某个可选字段同时出现在会话级以及某个特定的媒体级,则就该特定媒体而言,媒体级所设定的字段值可以取代会话级设定的字段值;
字段 | 含义 | 说明 | 补充 |
i | 会话信息 | 给定会话的文本描述 | |
u | URI | 给定某个 Web 主页的 URI (统一资源标识符) | 只用于会话级别 |
e | E-mail 地址 | 给定会话组织者的 E-mail 地址 | 只用于会话级别 |
p | 电话号码 | 给定会话组织者的电话号码 | 只用于会话级别 |
c | 连接信息 | 给定连接相关信息 | 包括连接类型、网络类型和连接地址等 |
b | 带宽信息 | 给定以 kbit/s 为单位的带宽信息 | 用于会话级时指定整个会话所需的带宽;用于媒体级时指定该多媒体所需的带宽 |
r | 重复时间 | 若需要周期性地启动某个会话,指定启动会话的频率 | |
z | 时域调整 | 若会话是周期性启动且该会话的参与者位于不同时域,则需要进行时域调整 | |
k | 密钥 | 给定密钥或提供密钥的机制 | |
a | 属性 | 描述作用于会话或媒体的其他属性 |
【2.3】字段顺序
SDP 规定的字段顺序如下
(1) 会话级
v(协议版本号)
o(会话创建者)
s(会话名)
i(会话信息,可选)
u(统一资源标识符,可选)
e(E-mail 地址,可选)
p(电话号码,可选)
c(连接信息,可选)
b(带宽信息)
t(时间描述)
r(重复信息,可选)
z(时域调整,可选)
k(密钥,可选)
a(属性,可选)
(2)媒体级
m(媒体描述)
i(媒体信息,可选)
c(连接信息,可选)
b(带宽信息,可选)
k(密钥,可选)
a(属性,可选)
【2.4】子字段
字段=<子字段 1 的值><子字段 2 的值>......<子字段 n 的值>
【2.5】常用字段描述
- 协议版本(v=)
v=0
SDP的版本(Protocol version number),当前规范版本为 0;
- 来源(o=)
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
会话所有者有关的参数(Owner/creator and session identifier)
- <username> 会话发起者的名称。如果不提供则用"-"表示,用户名不能包含空格;
- <sess-id> 主叫方的会话标识符;
- <sess-version> 会话版本号。用0标识的居多;
- <nettype> 网络类型。IN表示Internet网络类型,目前仅定义该网络类型;
- <addrtype> 地址类型。目前支持IPV4和IPV6两种地址类型;
- <unicast-address> 会话发起者的IP地址;
- 会话名称(s=)
s=<session name>
本次会话的标题或会话的名称(Session name);
- 计时(t=)
t=<start-time> <stop-time>
会话的起始时间和结束时间(Time session starts and stops);
- 媒体说明(m=)
m=<media> <port>/<number of ports> <proto> <fmt> ...
媒体行,描述了发送方所支持的媒体类型等信息(Media information)。
- <media> 媒体名称(audio/video)。表示包含音频类型或视频类型;
- <port>/<number of ports> 流传输端口号。表示在本地端口xxxx上发送音频/视频流;
- <proto> 流传输协议。举例说明:
- RTP/SAVPF 表示用UDP传输RTP包;
- TCP/RTP/SAVPF 表示用TCP传输RTP包;
- UDP/TLS/RTP/SAVPF 表示用UDP来传输RTP包,并使用TLS加密;
- 最后的 SAVPF 还有其他几种值:AVP, SAVP, AVPF, SAVPF;
- AVP 意为 AV profile
- S 意为 secure
- F 意为 feedback
- <fmt> 从第四位开始都是媒体格式描述
- 连接数据(c=)
c=<nettype> <addrtype> <connection-address>
媒体的连接信息(Connection information),每个媒体描述中至少包含一个 c = 字段,或者在会话描述中包含一个 c = 字段;
- <nettype> 网络类型。IN表示Internet网络类型,目前仅定义该网络类型;
- <addrtype> 地址类型。目前支持IPV4和IPV6两种地址类型;
- <unicast-address> 会话发起者的IP地址;
- 属性(a=)
a=<attribute> | <attribute>:<value>
属性(attribute)是扩展SDP的主要手段,分为会话级属性和媒体级属性:
- 会话级属性:添加在第一个媒体描述之前,传达的信息适用于整个会议而不是单个媒体;
- a=group:BUNDLE audio video 通过mid标识符把多个媒体属性连接起来;
- a=msid-semantic: WMS ma 表示是webrtc媒体流(Webrtc Media Streams);
- 媒体级属性:媒体描述中添加有关媒体流的信息;
- a=mid:audio 上述BUNDLE中用到的媒体标识;
- a=msid:ma ta 连接不同的媒体描述,使用相同的MediaStreams;
- a=sendonly 表示媒体发送端,其他类型:recvonly,sendrecv,inactive;
- a=rtcp:9 IN IP4 0.0.0.0 用来传输rtcp地地址和端口;
- a=rtcp-mux 表示rtp,rtcp包使用同一个端口来传输;
- a=ice-xxx:xxx ice协商过程中的安全验证信息;
- a=fingerprint:xxx 表示dtls协商过程中需要的认证信息;
- a=setup:actpass 表示本客户端在dtls协商过程中,可以做客户端也可以做服务端;
- a=rtpmap:111 opus/48000/2 负载类型111,编码格式opus,48000是时钟,2是通道数;
- a=rtcp-fb:111 nack 支持丢包重传;
- a=rtcp-fb:111 nack pli 支持关键帧丢包重传;
- a=rtcp-fb:111 transport-cc 表示opus编码支持使用rtcp来控制拥塞;
- a=fmtp:111 minptime=10;useinbandfec=1;maxplaybackrate=16000 对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性;
- a=ssrc:1370113029 cname:NMediaAudio cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,用于音视频同步;
- a=candidate:1 1 udp 2013266431 x.x.x.x 43342 typ host generation 0 表示候选人的传输地址;
【3】SDP 示例
v=0
// sdp 版本号,一直为0,rfc4566 规定
o=- 7017624586836067756 2 IN IP4 127.0.0.1
// o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
// username 若没有则使用-代替,7017624586836067756 是整个会话的编号,
// 2 代表会话版本,如果在会话过程中有改变编码之类的操作,重新生成 sdp 时,sess-id 不变,sess-version 加 1
s=-
// 会话名,若没有则用-代替
t=0 0
// 两个值分别是会话的起始时间和结束时间,0 代表没有限制
a=group:BUNDLE audio video data
// 需要共用一个传输通道传输的媒体,若没有这一行,音、视频数据就会分别单独用一个 udp 端口发送
a=msid-semantic: WMS h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
// WMS 是 WebRTC Media Stream 简称,这一行定义了客户端支持同时传输多个流,一个流可以包括多个track,
// 若定义了该属性则a=ssrc行就会有msid,mslabel等属性
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
// m=audio 说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中一现在一般不使用,
// 如果设置为0,代表不传输音频;
// UDP/TLS/RTP/SAVPF表示用户传输音频支持的协议,udp,tls,rtp代表使用udp来传输rtp包并使用tls加密,
// SAVPF代表使用srtcp的反馈机制来控制通信过程;
// 111 103 104 9 0 8 106 105 13 126表示本会话音频支持的编码
c=IN IP4 0.0.0.0
// 该行表示用来接收或者发送音频使用的IP地址,webrtc使用ice传输,不使用这个地址
a=rtcp:9 IN IP4 0.0.0.0
// 用来传输rtcp的地址和端口,webrtc中不使用
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
// 以上两行是ice协商过程中的安全验证信息
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
// 该行是dtls协商过程中需要的认证信息
a=setup:actpass
// 以上这行代表本客户端在dtls协商过程中,可以做客户端也可以做服务端,参考rfc4145 rfc4572
a=mid:audio
// 在前面BUNDLE行中用到的媒体标识
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
//该行指出要在rtp头部中加入音量信息,参考 rfc6464
a=sendrecv
//该行标识双向通信,另外几种类型是recvonly,sendonly,inactive
a=rtcp-mux
// 该行指出rtp,rtcp包使用同一个端口来传输
// 下面几行都是对m=audio这一行的媒体编码补充说明,指出了编码采用的编号,采样率,声道等
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
// 以上两行说明opus编码支持使用rtcp来控制拥塞,
// 参考https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=fmtp:111 minptime=10;useinbandfec=1
// 对opus编码可选的补充说明,
// minptime代表最小打包时长是10ms,
// useinbandfec=1代表使用opus编码内置fec特性
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:126 telephone-event/8000
a=ssrc:18509423 cname:sTjtznXLCNH7nbRw
// cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,
// 用于音视频同步
a=ssrc:18509423 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C 15598a91-caf9-4fff-a28f-3082310b2b7a
// 该行定义了ssrc和WebRTC中的MediaStream,AudioTrack之间的关系,msid后面第一个属性是stream-id,第二个是track-id
a=ssrc:18509423 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:18509423 label:15598a91-caf9-4fff-a28f-3082310b2b7a
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
// 参考m=audio,含义类似
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
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-hol ... de-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
// ccm是codec control using RTCP feedback message简称,意思是支持使用rtcp反馈机制来实现编码控制,
// fir是Full Intra Request简称,意思是接收方通知发送方发送完全帧
a=rtcp-fb:100 nack
// 支持丢包重传,参考rfc4585
a=rtcp-fb:100 nack pli
// 支持关键帧丢包重传,参考rfc4585
a=rtcp-fb:100 goog-remb
// 支持使用rtcp包来控制发送方的码流
a=rtcp-fb:100 transport-cc
// 参考上面opus
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
// h264编码可选的附加说明
a=rtpmap:116 red/90000
// fec冗余编码,一般如果sdp中存在该行,rtp头部负载类型就是116,否则就是各编码原生负载类型
a=rtpmap:117 ulpfec/90000
// 支持ULP FEC,参考rfc5109
a=rtpmap:96 rtx/90000
a=fmtp:96 apt=100
// 以上两行是VP8编码的重传包rtp类型
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=101
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=107
a=rtpmap:98 rtx/90000
a=fmtp:98 apt=116
a=ssrc-group:FID 3463951252 1461041037
// 在webrtc中,重传包和正常包ssrc是不同的,上一行中前一个是正常rtp包的ssrc,后一个是重传包的ssrc
a=ssrc:3463951252 cname:sTjtznXLCNH7nbRw
a=ssrc:3463951252 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:3463951252 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:3463951252 label:ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:1461041037 cname:sTjtznXLCNH7nbRw
a=ssrc:1461041037 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C ead4b4e9-b650-4ed5-86f8-6f5f5806346d
a=ssrc:1461041037 mslabel:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
a=ssrc:1461041037 label:ead4b4e9-b650-4ed5-86f8-6f5f5806346d
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
a=setup:actpass
a=mid:data
a=sctpmap:5000 webrtc-datachannel 1024
参考致谢
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。
【1】多媒体传输网络与VOIP系统设计
【2】SDP -- RFC4566
【3】SDP协议