sdp 結構簡析


參考:

1. 概述

SDP(Session Description Protocol,會話描述協議) 的具體標准定義在了 rfc4566 中。本篇文章主要以 rfc4566 為基礎,通過 webrtc offer/answer 協商中的 sdp 為例進行記錄,然后會對比與 sip 呼叫中 sdp 的一些異同。

2. 結構

sdp 是一行一行的文本,每一行之間使用 \n 或者 \r\n 來分割,所以如果要解析 sdp,那么代碼需要兼容這兩種分割方式。除開分隔符,其他都是可打印字符。
每一行中,采用 type=value 的結構,即使用 = 號進行分割。其中,type 必須為單個字符,而 value 則較為復雜,可以有多種不同格式,= 號之間不能存在空格。

2.1 總體結構

sdp 多個行之間會一起描述一個結構功能,sdp 是結構化的。簡單來說,主要分為會話級別描述(session level)和媒體級別描述(media level),會話級別描述只有一個,媒體級別描述可以有多個(下面示例出自 rfc4566):

Session description(會話級別描述)
         v=  (protocol version)
         o=  (originator and session identifier)
         s=  (session name)
         c=* (connection information -- not required if included in all media)
         One or more Time descriptions ("t=" and "r=" lines; see below)
         a=* (zero or more session attribute lines)
         Zero or more Media descriptions

Time description
         t=  (time the session is active)

Media description(媒體級別描述), if present
         m=  (media name and transport address)
         c=* (connection information -- optional if included at session level)
         a=* (zero or more media attribute lines)

2.2 會話級別描述(Session description level)

會話描述總是在 sdp 的開頭,是必須存在的結構。以下面的會話描述為例,說明常見的每個字段:

v=0
o=- 1044094566052576507 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp

2.2.1 v(protocol version)

會話協議版本,rfc4566 固定了版本號為 0,即:

v=0

2.2.2 o(originator and session identifier)

會話發起者標識:

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:地址類型,比如 IP4、IV6。
  • unicast-address:域名,或者 IP 地址。

2.2.3 s(session name)

會話名,沒有具體設置可為 -:

s=-

2.2.4 t(timing)

聲明會話的開始時間和結束時間:

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

如果開始和結束時間都為 0,那么意味着這次會話是永久的。

2.2.5 a(attribute)

a 開頭的表示附加屬性,用於擴展 sdp,有如下兩種格式:

a=<attribute>
a=<attribute>:<value>

a 開頭的行不僅會出現在 session level 中,也會出現在 media level 中(后文將展示)。

2.3 媒體級別描述(Media description level)

會話描述結束后,接着是媒體描述。在sdp中,可能有多個媒體描述,每個媒體描述由 m= 行開始。不同於 session level,media level 中的一些不同行,會有明確的先后關系,不能亂序,而 session level 中的大部分行可以任意排列。以下面的媒體描述為例,說明常見的字段:

m=audio 9 UDP/TLS/RTP/SAVPF 111 103
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Fyzi
a=ice-pwd:/NDZTbh8NX+BTFjRyZy7Heqc
a=ice-options:trickle
a=fingerprint:sha-256 60:DF:D2:8E:AC:1B:7C:DB:DA:36:39:57:AA:DD:1A:C2:43:58:36:09:80:56:CA:18:F4:85:6B:9F:B1:8F:78:13
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendonly
a=msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 13eb9491-262e-4982-9aea-1c6af9e8ef22
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=ssrc:724846199 cname:wJobAtYmVV7u5Y3x
a=ssrc:724846199 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 13eb9491-262e-4982-9aea-1c6af9e8ef22
a=ssrc:724846199 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp

2.3.1 m=(Media Descriptions)

媒體描述起始行:

m=<media> <port> <proto> <fmt> ...
  • media:媒體類型。支持包括 video、audio、text、application(bfcp) 等。
  • port:流媒體傳輸端口。具體含義取決於使用的網絡類型(在 c= 中聲明)和使用的協議(proto,在 m= 中聲明)。
  • proto:流媒體傳輸協議。具體含義取決於 c= 中定義的地址類型,比如 c= 是 IP4,那么這里的傳輸協議運行在 IP4 之上。以 UDP/TLS/RTP/SAVPF 為例:
    • UDP:傳輸層協議是UDP。
    • TLS:加密傳輸基於 DTLS 協議。
    • RTP:使用 rtp 協議傳輸媒體。
    • SAVPF:使用 SRTP 協議對 RTP 媒體負載進行加密。如果是 AVPF 或 AVP,表示不對 RTP 中的媒體負載進行加密。AVPF與AVP的區別,見 rfc4585 文檔(webrtc 一般用 AVPF,sip 一般用 AVP)。
  • fmt:媒體格式的描述,可能有多個。根據 proto 的不同,fmt 的含義也不同。比如 proto 為 RTP/AVP 時,fmt 表示 RTP payload 的類型。如果有多個,表示在這次會話中,多種 payload 類型都可能會用到。

2.3.2 c=(Connection Data)

會話連接信息。此字段也可以只出現在 session level 中,或者只在 media level 中,也可以都出現:

c=<nettype> <addrtype> <connection-address>
  • nettype:網絡類型,比如IN,表示 Internet。
  • addrtype:地址類型,比如IP4、IP6。
  • connection-address:如果是廣播,則為廣播地址組;如果是單播,則為單播地址。

2.4 group bundle 與 mid

在 webrtc 中,a=group:BUNDLE 行用於綁定不同的 media level,而每個 media level 都會有一個 mid 字段,用於媒體行標識:

// Session Description
a=group:BUNDLE 0 1
...
// Audio Media Description
a=mid 0
...
// Video Media Description
a=mid 1
...

每個媒體行都可以創建一個自己的網絡連接,用於傳遞音視頻和 rtcp 數據。會話綁定媒體行的意義是,不同媒體行可以復用同一個網絡連接進行數據傳輸。

2.5 ICE(Interactive Connectivity Establishment)

媒體協商完成后,webrtc 雙方要做的第一件事就是建立網絡連接,而 ice 協議(參考 rfc5245)定義了 webrtc 建立網絡連接的方式,反應在 sdp 中,有如下字段:

...
a=ice-ufrag:Fyzi
a=ice-pwd:/NDZTbh8NX+BTFjRyZy7Heqc
a=ice-options:trickle
a=ice-lite
...
  • ice-ufrag 和 ice-pwd 用於 ice 中 stun 消息的認證
  • ice-options:trickle 表明本端支持獨立發送 candidates 和 sdp,參考 https://tools.ietf.org/id/draft-ietf-ice-trickle-16.html
  • ice-lite 表明本端不會做連通性檢查(本端只會回應 stun binding response)

這些 ice 字段可以出現在所有的 media level 中,如果 sdp 指定了 group:bundle,則綁定的 media level 中,ice 字段應該都相同。

2.5.1 candidate(地址候選項)

地址候選項可以出現在 sdp 中,也可以單獨通過 http、websocket 等類似發送 sdp 的方式發送給對端(來自 rfc5245 15.1,更改了排列格式,SP 表示空格):

candidate-attribute="candidate:" foundation SP component-id SP transport SP priority SP connection-address SP port SP "typ" SP cand-type [SP rel-addr] [SP rel-port] *(SP extension-att-name SP extension-att-value)
  • foundation:多個 candidates 之間通過此字段來區分是否是同一種候選地址
  • component-id:1 表示用於傳輸 rtp 的候選地址,2 表示用於傳輸 rtcp 的候選地址,如果啟用了 rtcp-mux,那么都為 1 即可
  • transport:網絡傳輸類型,udp 或 tcp
  • priority:此 candidate 的優先級,用於生成 check-list pair 的時候,誰最先發起連通性檢查
  • connection-address:候選地址,可以是 ipv4、ipv6、域名(如果是域名,接收端需要進行 dns 解析)
  • port:候選端口
  • cand-type:host、srflx、prflx、relay 之一
  • extension-att-name,extension-att-value:擴展屬性

如下是一個 sdp 中的 candidate 示例(只能出現在 media level 中,不能出現在 session level 中,多個不同 media level 中的 candidate 可以相同):

  a=candidate:0 1 udp 2130706431 192.168.0.106 8090 typ host generation 0
  • foundation 為 0
  • component-id 為 1,表明是用於 rtp 傳輸的候選地址,如果 sdp 啟用了 rtcp-mux,則 rtcp 傳輸也復用這個候選地址
  • 網絡傳輸使用 udp
  • 優先級為 2130706431,詳細計算公式參考 rfc5245
  • 候選 ipv4 地址為 192.168.0.106
  • 候選 port 為 8090
  • 候選地址類型為 host,這種地址要么本端擁有公網 ip,要么與對端在同一個局域網中
  • generation 0 是擴展屬性

注意以下是一個 janus 通過信令發送的 trickle candidate 示例:

 {"janus":"trickle","candidate":{"candidate":"candidate:3805835391 1 udp 2122260223 192.168.0.107 53792 typ host generation 0 ufrag icRG network-id 1","sdpMid":"0","sdpMLineIndex":0},"transaction":"jIToQHjOgntu","session_id":52}

其中,必須指明此 candidate 屬於哪個 media stream(這里通過 mid 和 m-line index 進行指定,顯然,即使是 ice trickle 模式,也必須先發送 sdp 然后再發送 local candidate,參考 https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-trickle-ice-02#section-9.2)。

2.6 DTLS

ICE 連接建立完成后,接着就是 DTLS 握手協商出用於 SRTP 媒體加密的密鑰,DTLS 握手在 sdp 中的字段如下:

a=fingerprint:sha-256 60:DF:D2:8E:AC:1B:7C:DB:DA:36:39:57:AA:DD:1A:C2:43:58:36:09:80:56:CA:18:F4:85:6B:9F:B1:8F:78:13
a=setup:actpass

其中,fingerprint 即握手中的指紋信息(用於自簽證書驗證),setup 表明本端在握手中的角色:

  • active:主動發起 DTLS 握手。
  • passive:被動等待接受 DTLS 握手消息。
  • actpass:既可以主動發起,也可以被動接受。當 offer 一方為 actpass 時,answer 一方必須指定為 active 或 passive。

2.7 Stream Direction

此屬性在 a= 中,如 a=sendonly,在不同 media level 中,可以有不同,以表明不同的媒體收發支持:

  • sendonly:本端只支持發送媒體,不接收媒體,因此對端返回的 sdp 可以不攜帶 ssrc 信息。
  • recvonly:本端只支持接收媒體,不發送媒體,因此本端 sdp 可以不攜帶 ssrc 信息。
  • sendrecv:本端支持收發媒體
  • inactive:用在某個 media level 協商失敗的回應中

2.8 Codec Parameters(編解碼格式參數)

編解碼參數用於描述媒體編解碼格式信息(使用此格式進行編解碼),一個 media level 可以支持多個編解碼格式,具體最終使用哪個或哪些取決於媒體協商的結果。
offer 中的編解碼格式表明 offer 端支持發送接收帶這些媒體格式的 rtp 包,answer 中的編解碼格式只能從這些給定的編解碼格式中進行協商。

2.8.1 rtpmap

a=rtpmap 是編解碼格式參數的起始行:

a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]
  • payload type:rtp payload 值,必須是 m line 中支持的某個值
  • encoding name:編解碼格式名稱,如 H264、opus、vpx 等
  • clock rate:時鍾頻率
  • encoding parameters:可選項

2.8.2 fmtp(format specific param)

用於對 rtpmap 指定的編碼格式做進一步描述:

a=fmtp:<format> <format specific parameters>
  • format:等於其上最近一個 rtpmap 的 payload 值,所以 a=fmtp 行必須在 a=rtpmap 行的后面,有順序之分
  • format specific parameters:對 rtpmap 編解碼格式的進一步描述

如對 h264 編解碼格式:

a=rtpmap:102 H264/90000
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
  • level-asymmetry-allowed:指定
  • packetization-mode:
  • profile-level-id:16進制

2.8.3 rtcp-fb(rtcp feedback)

rtpmap 編解碼格式支持的 rtcp 反饋消息類型,如:

a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
  • goog-remb:Receiver Estimated Max Bitrate 接收端碼率反饋,參考 https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
  • transport-cc:傳輸層擁塞控制,參考 https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
  • ccm fir:Full Intra Request,關鍵幀請求,主要用於發送端剛加入會議時,接收端傳遞此消息,讓發送端盡快發送關鍵幀。fir 在 rfc5104(新的定義,一般用這種)和 rfc2032(舊的定義,不加 ccm 標識) 中進行了定義
  • nack:Negative Acknowledgement,nack 實際上分為 RTPFB 和 PSFB,在 rtcp 的 FMT 字段進行區分。這里指 rtp 包丟失重傳,參考 rfc4585
  • nack pli:nack Picture Loss Indication,當丟 rtp 包太多時,接收端發送此消息,讓發送端盡快發送新的關鍵幀過來

2.8.4 rtx

當 rtp 丟包重傳時,可以直接重傳原始包,也可以將待重傳包的 rtp payload type 填入新的負載類型值,用於表明這是一個重傳包。新的負載類型值即 sdp 中的 rtx rtpmap。rtx 依賴於某個非重傳的 rtpmap 編解碼格式,表示此 rtx 專門用來重傳所屬的編解碼格式:

a=rtpmap:123 H264/90000
a=rtcp-fb:123 nack
a=rtcp-fb:123 nack pli
a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f
a=rtpmap:118 rtx/90000
a=fmtp:118 apt=123

如上,重傳 rtpmap 的 encoding name 為 rtx,pt 值為 118,如何與其上的 rtpmap:123 H264 相關聯呢?答案是借助 a=fmtp:118 apt=123,apt= 的值即此 rtx 所屬的非重傳編解碼格式。
注意,rtx 不需要雙向協商,即只要本端的 sdp 中出現 rtx 即表明本端重傳 rtp 時,以 rtx 的方式重傳。
rtx 重傳包也會擁有自己獨立的 ssrc,rtx 的 ssrc 參見下文。

2.9 extmap

rtp 頭部擴展,參考 rfc5285:

a=extmap:<value>["/"<direction>] <URI> <extensionattributes>

如一個 audio level 支持的頭部擴展:

a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id

value 和 url 可以自定定義。如上,offer 中的 extmap 表明 offer 端支持發送接收帶這些擴展頭的 rtp 包,answer 中的 extmap 只能從這些給定的 extmap 進行協商。

2.10 ssrc

ssrc 即 media level 的源同步標識,參考 rfc5576:

a=ssrc:<ssrc-id> <attribute>
a=ssrc:<ssrc-id> <attribute>:<value>

ssrc-id 是一個在 [0, 2^32-1] 之間的隨機值,如某個 audio level 的 ssrc:

a=ssrc:724846199 cname:wJobAtYmVV7u5Y3x
a=ssrc:724846199 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 13eb9491-262e-4982-9aea-1c6af9e8ef22
a=ssrc:724846199 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
a=ssrc:724846199 label:13eb9491-262e-4982-9aea-1c6af9e8ef22

a=ssrc:724846199 出現了多次,但是 attribute 都不同。

2.10.1 ssrc-group

定義一組相關聯的 ssrc:

a=ssrc-group:<semantics> <ssrc-id> ...
  • semantics:可以取值為 FID(Flow Identification)、FEC(Forward Error Correction)
  • ssrc-id:可以有多個,表明是一組相關聯的 ssrc
    在 rtx 的語義中,rtx 重傳包不僅有不同於被重傳包的 pt 值,也有不同的 ssrc 值,rtx ssrc 在 ssrc-group 字段中,如下是 video media level 示例:
a=ssrc-group:FID 3473705511 683075964
a=ssrc:3473705511 cname:wJobAtYmVV7u5Y3x
a=ssrc:3473705511 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:3473705511 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
a=ssrc:3473705511 label:0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:683075964 cname:wJobAtYmVV7u5Y3x
a=ssrc:683075964 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:683075964 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
a=ssrc:683075964 label:0befb6f8-46a8-4890-9955-b53689962daf

其中,semantics 為 FID,ssrc-id 有兩個,第一個是正常 media level 的 ssrc,第二個 ssrc 即 rtx 的重傳 ssrc。

2.11 示例解釋

下面是一個 offer 示例,將逐行解釋,前文沒有描述的字段,在這里進行描述:

// sdp版本號為0
v=0
// 用戶名為空,會話id是 1044094566052576507,會話版本是2(會話重協商 sess-version 應加 1),地址類型為 IP4,地址為 127.0.0.1(可忽略)
o=- 1044094566052576507 2 IN IP4 127.0.0.1
// 會話名為空
s=-
// 實時會話
t=0 0
// mid=0 和 mid=1 的 media track 多路復用同一個網絡連接
a=group:BUNDLE 0 1
// WMS 是 WebRTC Media Stram 的縮寫,這里給 Media Stream 定義了一個唯一的標識符。一個 Media Stream 可以有多個 track(video track、audio track),這些 track 就是通過這個唯一標識符關聯起來的,具體見下面的媒體行(m=)以及它對應的附加屬性(a=ssrc)
a=msid-semantic: WMS g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
// 音頻媒體描述,端口為9(可忽略),采用 UDP 傳輸加密的 RTP 包,支持 RTCP 反饋,111、103 是 audio 可能采用的編碼格式 payload type 值
m=audio 9 UDP/TLS/RTP/SAVPF 111 103
// 音頻發送者的 IP4 地址,WebRTC 采用 ICE,這里的 0.0.0.0 可直接忽略
c=IN IP4 0.0.0.0
// RTCP 采用的端口、IP地址,因為下面的 a=rtcp-mux,這里可忽略
a=rtcp:9 IN IP4 0.0.0.0
// ice 協商認證字段
a=ice-ufrag:Fyzi
a=ice-pwd:/NDZTbh8NX+BTFjRyZy7Heqc
// 本端支持的 ice 類型是 trickle
a=ice-options:trickle
// dtls 握手指紋
a=fingerprint:sha-256 60:DF:D2:8E:AC:1B:7C:DB:DA:36:39:57:AA:DD:1A:C2:43:58:36:09:80:56:CA:18:F4:85:6B:9F:B1:8F:78:13
// dtls 握手角色,支持主動和被動
a=setup:actpass
// 本 audio 的 mid 為 0,對應前面的 a=group:BUNDLE 0 1
a=mid:0
// audio 支持的 rtp 擴展頭
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
// audio 只支持發送 rtp,不支持接收 rtp。但是注意,仍然支持接收 rtcp
a=sendonly
// msid后面帶兩個id,第一個是 Media Stream 的 id,第二個是 audio track 的 id
a=msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 13eb9491-262e-4982-9aea-1c6af9e8ef22
// rtcp 多路復用 rtp 的網絡通道
a=rtcp-mux
// opus 的 pt 值為 111,clock rate 為 48000,2 聲道
a=rtpmap:111 opus/48000/2
// opus 編解碼格式支持 transport-cc rtcp 反饋,注意,transport-cc rtcp 反饋需要 a=extmap:3 擴展頭的支持
a=rtcp-fb:111 transport-cc
// 進一步描述 opus 編解碼格式,支持帶內 fec
a=fmtp:111 minptime=10;useinbandfec=1
// audio 也支持 ISAC 編解碼格式
a=rtpmap:103 ISAC/16000
// audio 的 ssrc,cname用來唯一標識媒體的數據源
a=ssrc:724846199 cname:wJobAtYmVV7u5Y3x
// msid 與前面的 a=msid 字段相同
a=ssrc:724846199 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 13eb9491-262e-4982-9aea-1c6af9e8ef22
// mslabel:audio track id
a=ssrc:724846199 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
// label:webrtc media stream id
a=ssrc:724846199 label:13eb9491-262e-4982-9aea-1c6af9e8ef22
// 從下面開始是 video track 的媒體描述
m=video 9 UDP/TLS/RTP/SAVPF 96 97 102 121
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:Fyzi
a=ice-pwd:/NDZTbh8NX+BTFjRyZy7Heqc
a=ice-options:trickle
a=fingerprint:sha-256 60:DF:D2:8E:AC:1B:7C:DB:DA:36:39:57:AA:DD:1A:C2:43:58:36:09:80:56:CA:18:F4:85:6B:9F:B1:8F:78:13
a=setup:actpass
// 本 video 的 mid 為 1,對應前面的 a=group:BUNDLE 0 1
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendonly
a=msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 0befb6f8-46a8-4890-9955-b53689962daf
a=rtcp-mux
a=rtcp-rsize
// 支持 vp8 編解碼格式
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
// 支持 h264 編解碼格式
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
// pt 值為 102 的 h264 編解碼格式支持 rtp 丟包重傳
a=rtpmap:121 rtx/90000
a=fmtp:121 apt=102
// video 發送媒體正常的 ssrc 和支持 rtx 重傳的 ssrc
a=ssrc-group:FID 3473705511 683075964
a=ssrc:3473705511 cname:wJobAtYmVV7u5Y3x
a=ssrc:3473705511 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:3473705511 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
a=ssrc:3473705511 label:0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:683075964 cname:wJobAtYmVV7u5Y3x
a=ssrc:683075964 msid:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp 0befb6f8-46a8-4890-9955-b53689962daf
a=ssrc:683075964 mslabel:g4n21yfXiVM9K1CrtoSZMNxoNI7kBbY9rHgp
a=ssrc:683075964 label:0befb6f8-46a8-4890-9955-b53689962daf

3. 協商失敗

媒體協商可能失敗,answer 端會檢查每一個 media level,如果某個 media level 協商失敗,answer 中的 sdp 如何表明呢?有兩種方式:

  • m 行中的 port 字段為 0,如 m=video 0 UDP/TLS/RTP/SAVPF 96 97 102 121
  • media direction 字段為 inactive,如 a=inactive

4. PlanB and UnifiedPlan

webrtc 引入了 stream 和 track 的概念,一個 track 即一路音頻或視頻流,比如一個終端,可以發送屏幕共享一路流、攝像頭一路流、麥克風音頻一路流。每一路單獨流是一個 track,集合在一起形成了一個 stream,每一路流通過 ssrc 來進行區分。
兩路音頻流 planb 的 sdp 格式:

...
a=group:BUNDLE audio
a=msid-semantic: WMS stream-id-2 stream-id-1
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
...
a=mid:audio...
a=rtpmap:103 ISAC/16000
...
a=ssrc:10 cname:cname
a=ssrc:10 msid:stream-id-1 track-id-1
a=ssrc:10 mslabel:stream-id-1
a=ssrc:10 label:track-id-1
a=ssrc:11 cname:cname
a=ssrc:11 msid:stream-id-2 track-id-2
a=ssrc:11 mslabel:stream-id-2
a=ssrc:11 label:track-id-2

兩路音頻流的 UnifiedPlan 格式:

...
a=group:BUNDLE 0 1
a=msid-semantic: WMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
...
a=mid:0
...
a=sendrecv
a=msid:- track-id-1
...
a=rtpmap:103 ISAC/16000
...
a=ssrc:10 cname:cname
a=ssrc:10 msid: track-id-1
a=ssrc:10 mslabel:
a=ssrc:10 label:track-id-1
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
...
a=mid:1
...
a=sendrecv
a=msid:- track-id-2
...
a=rtpmap:103 ISAC/16000
...
a=ssrc:11 cname:cname
a=ssrc:11 msid: track-id-2
a=ssrc:11 mslabel:
a=ssrc:11 label:track-id-2

可見,planb 格式中,audio 只有一個 media level,media level 中有多個 track 時不同 track 通過 ssrc 進行區分,不同 track 必須使用同一種編解碼格式。
unified plan 格式中,audio 有兩個 media level,每個 media level 對應一個 track,也對應一個 ssrc 進行區分,不同 track 可以使用不同的編解碼格式。
planb 和 unified plan 格式的差異注意意義在於:不同音視頻流可以支持不同的編解碼格式。
當只有一路音頻流和一路視頻流時,兩則一樣。

5. sip 呼叫中的 sdp

sip 呼叫中的 sdp 與 webrtc 會有一些顯著的區別,下面分別稱述。

5.1 網絡傳輸上的區別

  • sip 呼叫是一套完整的運行在 TCP/UDP 之上的協議,sdp 只是 sip 呼叫中的一部分;webrtc 中的 sdp 需要依賴其它協議(如 http、websocket等)由用戶自定義傳輸。
  • webrtc 引入了 ICE 協議,致力於打通不同網絡之間(如兩個處於不同 NAT 下的設備)的連接;sip 呼叫則需要開發者根據網絡拓撲類型自定義呼叫方式(如經由一個網關),以實現不同網絡類型的互通,sip 協議本身帶來的跨網絡連接能力有限(如自帶 rport 功能)。
  • webrtc 一般不同 tracks 之間會復用一個網絡鏈接;sip 中不同 tracks,每個 track 的 rtp、rtcp 都會有自己的網絡連接。
  • webrtc 通過 candidates 傳遞網絡連接信息;sip 的網絡連接信息直接寫在 sdp 中
// RTC
a=candidate:1 1 udp 2013266431 192.168.2.106 12345 typ host
// SIP
c=IN IP4 192.168.2.106
m=audio 3262 RTP/AVP 107 108 
m=video 3264 RTP/AVP 97 126 

5.2 媒體流的區別

  • webrtc 支持任意路音視頻流;sip 只支持一路音頻流和一路視頻流(通過 BFCP 協議可以擴展多一路屏幕共享視頻流)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM