WebRTC:會話描述協議SDP

什麼是SDP

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>

各字段含義以下:編碼

  • username:發起者的用戶名,不容許存在空格,若是應用不支持用戶名,則爲-
  • sess-id:會話id,由應用自行定義,規範的建議是NTP(Network Time Protocol)時間戳。
  • sess-version:會話版本,用途由應用自行定義,只要會話數據發生變化時(好比編碼),sess-version隨着遞增就行。一樣的,規範的建議是NTP時間戳。
  • nettype:網絡類型,好比IN表示Internet
  • addrtype:地址類型,好比IP4IV6
  • unicast-address:域名,或者IP地址。

會話名 s=

必選,有且僅有一個s=字段,且不能爲空。若是實在沒有有意義的會話名,能夠賦一個空格,即s= 加密

s=<session name>

鏈接數據:c=

格式以下:

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

每一個SDP至少須要包含一個會話級別的c=字段,或者在每一個媒體描述後面各包含一個c=字段。(媒體描述後的c=會覆蓋會話級別的c=

  • nettype:網絡類型,好比IN,表示 Internet。
  • addrtype:地址類型,好比IP4IP6
  • connection-address:若是是廣播,則爲廣播地址組;若是是單播,則爲單播地址;

舉例01:

c=IN IP4 224.2.36.42/127

舉例02:

c=IN IP4 host.anywhere.com

媒體描述:m=

SDP可能同時包含多個媒體描述。格式以下:

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

其中:

  • media:媒體類型。包括 video、audio、text、application、message等。
  • port:傳輸媒體流的端口,具體含義取決於使用的網絡類型(在c=中聲明)和使用的協議(proto,在m=中聲明)。
  • proto:傳輸協議,具體含義取決於c=中定義的地址類型,好比c=是IP4,那麼這裏的傳輸協議運行在IP4之上。好比:

    • UDP:傳輸層協議是UDP。
    • RTP/AVP:針對視頻、音頻的RTP協議,跑在UDP之上。
    • RTP/SAVP:針對視頻、音頻的SRTP協議,跑在UDP之上。
  • fmt:媒體格式的描述,可能有多個。根據 proto 的不一樣,fmt 的含義也不一樣。好比 proto 爲 RTP/SAVP 時,fmt 表示 RTP payload 的類型。若是有多個,表示在此次會話中,多種payload類型可能會用到,且第一個爲默認的payload類型。

舉例,下面表示媒體類型是視頻,採用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 又分兩種類型:

  1. 靜態類型:參考 RTP/AVP audio and video payload types
  2. 動態類型:在a=fmtp:裏進行定義。(a=爲附加屬性,見後面小節)

舉例,下面的SDP中:

  1. 對於audio,111 是動態類型,表示opus/48000/2
  2. 對於video,122 是動態類型,表示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)。

  1. 媒體級別:媒體描述(m=)後面能夠跟任意數量的 a= 字段,對媒體描述進行擴展。
  2. 會話級別:在第一個媒體字段(media field)前,添加的 a= 字段是會話級別的。

有以下兩種格式:

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實例

下面例子來自騰訊雲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

相關文章
相關標籤/搜索