SDP(Session Description Protocol)是一種通用的會話描述協議,主要用來描述多媒體會話,用途包括會話聲明、會話邀請、會話初始化等。html
WebRTC主要在鏈接創建階段用到SDP,鏈接雙方經過信令服務交換會話信息,包括音視頻編解碼器(codec)、主機候選地址、網絡傳輸協議等。web
下面先簡單介紹下SDP的格式、經常使用屬性,而後經過WebRTC鏈接創建過程生成的SDP實例進行進一步講解。網絡
SDP的格式很是簡單,由多個行組成,每一個行都是以下格式。session
<type>=<value>
其中:app
<type>
:大小寫敏感的一個字符,表明特定的屬性,好比v
表明版本;<value>
:結構化文本,格式與屬性類型有關,UTF8編碼;=
兩邊不容許存在空格;=*
表示是可選的;如下面的SDP爲例:tcp
v=0 o=alice 2890844526 2890844526 IN IP4 host.anywhere.com s= c=IN IP4 host.anywhere.com t=0 0 m=audio 49170 RTP/AVP 0 a=rtpmap:0 PCMU/8000 m=video 51372 RTP/AVP 31 a=rtpmap:31 H261/90000 m=video 53000 RTP/AVP 32 a=rtpmap:32 MPV/90000
v=
格式以下,注意,沒有子版本號。ide
v=0
o
格式以下,其中,username、session-id、nettype、addrtype、unicast-address 一塊兒,惟一標識一個會話。網絡傳輸協議
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
各字段含義以下:編碼
-
。IN
表示Internet
。IP4
、IV6
s=
必選,有且僅有一個s=
字段,且不能爲空。若是實在沒有有意義的會話名,能夠賦一個空格,即s=
。加密
s=<session name>
格式以下:
c=<nettype> <addrtype> <connection-address>
每一個SDP至少須要包含一個會話級別的c=
字段,或者在每一個媒體描述後面各包含一個c=
字段。(媒體描述後的c=
會覆蓋會話級別的c=
)
IN
,表示 Internet。IP4
、IP6
。舉例01:
c=IN IP4 224.2.36.42/127
舉例02:
c=IN IP4 host.anywhere.com
m=
SDP可能同時包含多個媒體描述。格式以下:
m=<media> <port> <proto> <fmt> ...
其中:
c=
中聲明)和使用的協議(proto,在m=
中聲明)。proto:傳輸協議,具體含義取決於c=
中定義的地址類型,好比c=
是IP4,那麼這裏的傳輸協議運行在IP4之上。好比:
舉例,下面表示媒體類型是視頻,採用SRTP傳輸流媒體數據,且RTP包的類型多是12二、102...119,默認是122。
m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119
對於 RTP/SAVP,須要注意的是,payload type 又分兩種類型:
a=fmtp:
裏進行定義。(a=
爲附加屬性,見後面小節)舉例,下面的SDP中:
opus/48000/2
。H264/90000
。m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126 a=rtpmap:111 opus/48000/2 m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119 a=rtpmap:122 H264/90000
a=
做用:用於擴展SDP。
有兩種做用範圍:會話級別(session-level)、媒體級別(media-level)。
有以下兩種格式:
a=<attribute> a=<attribute>:<value>
格式1舉例:
a=recvonly
格式2舉例:
a=rtpmap:0 PCMU/8000
t=
做用:聲明會話的開始、結束時間。
格式以下:
t=<start-time> <stop-time>
若是<stop-time>
是0,表示會話沒有結束的邊界,可是須要在<start-time>
以後會話纔是活躍(active)的。若是<start-time>
是0,表示會話是永久的。
舉例:
t=0 0
下面例子來自騰訊雲WebRTC服務的遠端offer。
// sdp版本號爲0 v=0 // o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address> // 用戶名爲空,會話id是8100750360520823155,會話版本是2(後面若是有相似改變編碼的操做,sess-version加1),地址類型爲IP4,地址爲127.0.0.1(這裏能夠忽略) o=- 7595655801978680453 2 IN IP4 112.90.139.105 // 會話名爲空 s=- // 會話的起始時間,都爲0表示沒有限制 t=0 0 a=ice-lite // 音頻、視頻的傳輸的傳輸採起多路複用,經過同一個RTP通道傳輸音頻、視頻,能夠參考 https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54 a=group:BUNDLE 0 1 // WMS是WebRTC Media Stram的縮寫,這裏給Media Stream定義了一個惟一的標識符。一個Media Stream能夠有多個track(video track、audio track),這些track就是經過這個惟一標識符關聯起來的,具體見下面的媒體行(m=)以及它對應的附加屬性(a=ssrc:) // 能夠參考這裏 http://tools.ietf.org/html/draft-ietf-mmusic-msid a=msid-semantic: WMS 5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV // m=<media> <port> <proto> <fmt> ... // 本次會話有音頻,端口爲9(可忽略,端口9爲Discard Protocol專用),採用UDP傳輸加密的RTP包,並使用基於SRTCP的音視頻反饋機制來提高傳輸質量,1十一、10三、104等是audio可能採用的編碼(參見前面m=的說明) m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126 // 音頻發送者的IP4地址,WebRTC採用ICE,這裏的 0.0.0.0 可直接忽略 c=IN IP4 0.0.0.0 // RTCP採用的端口、IP地址(可忽略) a=rtcp:9 IN IP4 0.0.0.0 // ice-ufrag、ice-pwd 分別爲ICE協商用到的認證信息 a=ice-ufrag:58142170598604946 a=ice-pwd:71696ad0528c4adb02bb40e1 // DTLS協商過程的指紋信息 a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19 // 當前客戶端在DTLS協商過程當中,既能夠做爲客戶端,也能夠做爲服務端,具體可參考 RFC4572 a=setup:actpass // 當前媒體行的標識符(在a=group:BUNDLE 0 1 這行裏面用到,這裏0表示audio) a=mid:0 // RTP容許擴展首部,這裏表示採用了RFC6464定義的針對audio的擴展首部,用來調節音量,好比在大型會議中,有多個音頻流,就能夠用這個來調整音頻混流的策略 // 這裏沒有vad=1,表示不啓用這個音量控制 a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level // 表示既能夠發送音頻,也能夠接收音頻 a=sendrecv // 表示啓用多路複用,RTP、RTCP共用同個通道 a=rtcp-mux // 下面幾行都是對audio媒體行的補充說明(針對111),包括rtpmap、rtcp-fb、fmtp // rtpmap:編解碼器爲opus,採樣率是48000,2聲道 a=rtpmap:111 opus/48000/2 // rtcp-fb:基於RTCP的反饋控制機制,能夠參考 https://tools.ietf.org/html/rfc512四、https://webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02/ a=rtcp-fb:111 transport-cc a=rtcp-fb:111 nack // 最小的音頻打包時間 a=fmtp:111 minptime=20 // 跟前面的rtpmap相似 a=rtpmap:126 telephone-event/8000 // ssrc用來對媒體進行描述,格式爲a=ssrc:<ssrc-id> <attribute>:<value>,具體可參考 RFC5576 // cname用來惟一標識媒體的數據源 a=ssrc:16864608 cname:YZcxBwerFFm6GH69 // msid後面帶兩個id,第一個是MediaStream的id,第二個是audio track的id(跟後面的mslabel、label對應) a=ssrc:16864608 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 128f4fa0-81dd-4c3a-bbcd-22e71e29d178 a=ssrc:16864608 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:16864608 label:128f4fa0-81dd-4c3a-bbcd-22e71e29d178 // 跟audio相似,不贅述 m=video 9 UDP/TLS/RTP/SAVPF 122 102 125 107 124 120 123 119 c=IN IP4 0.0.0.0 a=rtcp:9 IN IP4 0.0.0.0 a=ice-ufrag:58142170598604946 a=ice-pwd:71696ad0528c4adb02bb40e1 a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19 a=setup:actpass a=mid:1 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=sendrecv a=rtcp-mux a=rtcp-rsize a=rtpmap:122 H264/90000 a=rtcp-fb:122 ccm fir a=rtcp-fb:122 nack a=rtcp-fb:122 nack pli a=rtcp-fb:122 goog-remb a=rtcp-fb:122 transport-cc a=fmtp:122 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f a=rtpmap:102 rtx/90000 a=fmtp:102 apt=122 a=rtpmap:125 H264/90000 a=rtcp-fb:125 ccm fir a=rtcp-fb:125 nack a=rtcp-fb:125 nack pli a=rtcp-fb:125 goog-remb a=rtcp-fb:125 transport-cc a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f a=rtpmap:107 rtx/90000 a=fmtp:107 apt=125 a=rtpmap:124 H264/90000 a=rtcp-fb:124 ccm fir a=rtcp-fb:124 nack a=rtcp-fb:124 nack pli a=rtcp-fb:124 goog-remb a=rtcp-fb:124 transport-cc a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d0032 a=rtpmap:120 rtx/90000 a=fmtp:120 apt=124 a=rtpmap:123 H264/90000 a=rtcp-fb:123 ccm fir a=rtcp-fb:123 nack a=rtcp-fb:123 nack pli a=rtcp-fb:123 goog-remb a=rtcp-fb:123 transport-cc a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032 a=rtpmap:119 rtx/90000 a=fmtp:119 apt=123 a=ssrc-group:FID 33718809 50483271 a=ssrc:33718809 cname:ovaCctnHP9Asci9c a=ssrc:33718809 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:33718809 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:33718809 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:50483271 cname:ovaCctnHP9Asci9c a=ssrc:50483271 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:50483271 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:50483271 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d
SDP協議格式自己很簡單,難點通常在於應用層在不一樣場景下擴展出來的屬性,以及不一樣擴展屬性對應的含義。好比上面舉的例子,擴展屬性、屬性值的說明分散在數十個RFC裏,查找、理解都費了一番功夫。
若有錯漏,敬請指出。
SDP: Session Description Protocol
Annotated Example SDP for WebRTC