webRTC中的SDP的Bundlle可能包含一個或者多個媒體塊(媒體描述, 源碼對應類ContentInfo
),從 m=
開始到下一個 m=
行(或 SDP 結束)之間的所有屬性(包括 a=
)都屬于同一個媒體塊(media section, 源碼里面對應類MediaContentDescription
),下面舉例一個包含音頻、視頻和數據通道的完整 SDP 詳細說明:
完整 SDP 示例
v=0
o=- 621762799816690914 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video data # Bundle組定義
a=msid-semantic: WMS stream_label### 音頻媒體塊 ###
m=audio 49170 UDP/TLS/RTP/SAVPF 111 103 104 # 媒體行
c=IN IP4 192.168.1.100
a=rtcp:49171 IN IP4 192.168.1.100
a=ice-ufrag:8hhy
a=ice-pwd:38dsu82jd9sll
a=fingerprint:sha-256 A1:B2:C3:...
a=setup:actpass
a=mid:audio # 媒體標識符
a=sendrecv
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=ssrc:1234567890 cname:user@example.com### 視頻媒體塊 ###
m=video 49172 UDP/TLS/RTP/SAVPF 96 97 98 # 媒體行
c=IN IP4 192.168.1.100
a=rtcp:49173 IN IP4 192.168.1.100
a=ice-ufrag:8hhy # 與音頻相同的ufrag/pwd
a=ice-pwd:38dsu82jd9sll
a=fingerprint:sha-256 A1:B2:C3:... # 相同指紋
a=setup:actpass
a=mid:video # 媒體標識符
a=sendrecv
a=rtpmap:96 VP8/90000
a=rtpmap:97 H264/90000
a=rtpmap:98 VP9/90000
a=ssrc:2345678901 cname:user@example.com### 數據通道媒體塊 ###
m=application 49174 UDP/DTLS/SCTP webrtc-datachannel # 媒體行
c=IN IP4 192.168.1.100
a=ice-ufrag:8hhy # 相同ufrag/pwd
a=ice-pwd:38dsu82jd9sll
a=fingerprint:sha-256 A1:B2:C3:... # 相同指紋
a=setup:actpass
a=mid:data # 媒體標識符
a=sctp-port:5000
a=max-message-size:262144
結構解析圖解
Bundle Group
音頻 audio
視頻 video
數據通道 data
端口 49170
編解碼: Opus/ISAC
SSRC: 1234567890
端口 49172
編解碼: VP8/H264/VP9
SSRC: 2345678901
端口 49174
SCTP端口: 5000
媒體塊劃分
1. 音頻媒體塊
2025-08-01 2025-08-01 2025-08-02 2025-08-02 2025-08-03 2025-08-03 2025-08-04 2025-08-04 2025-08-05 2025-08-05 2025-08-06 2025-08-06 UDP端口 ICE參數 DTLS指紋 Opus編解碼 ISAC編解碼 SSRC標識 傳輸層 媒體層 音頻媒體塊結構
2. 視頻媒體塊
2025-08-01 2025-08-01 2025-08-02 2025-08-02 2025-08-03 2025-08-03 2025-08-04 2025-08-04 2025-08-05 2025-08-05 2025-08-06 2025-08-06 2025-08-07 2025-08-07 UDP端口 ICE參數 DTLS指紋 VP8編解碼 H264編解碼 VP9編解碼 SSRC標識 傳輸層 媒體層 視頻媒體塊結構
3. 數據通道媒體塊
2025-08-01 2025-08-01 2025-08-01 2025-08-01 2025-08-02 2025-08-02 2025-08-02 2025-08-02 2025-08-03 2025-08-03 2025-08-03 2025-08-03 UDP端口 SCTP端口 最大消息 ICE參數 DTLS指紋 傳輸層 數據層 數據通道媒體塊結構
Bundle 機制詳解
1. 共享元素
30% 30% 20% 20% Bundle共享資源 ICE參數 DTLS指紋 傳輸通道 NAT映射
2. 實際端口分配媒體類型 聲明端口 實際使用端口 原因 音頻 49170 49170 作為Bundle主通道 視頻 49172 49170 復用音頻端口 數據通道 49174 49170 復用音頻端口
3. 源碼中的Bundle處理
void JsepTransportController :: MaybeCreateJsepTransport ( ) { if ( bundle_group_ && bundle_group_-> HasContentName ( content_name) ) { jsep_transport = GetJsepTransportForMid ( bundle_group_-> FirstContentName ( ) ) ; } else { jsep_transport = CreateJsepTransport ( ) ; }
}
關鍵設計要點
1. 媒體塊獨立性
AudioDescription
+codecs : vector<AudioCodec>
+bandwidth : int
+direction : MediaDirection
VideoDescription
+codecs : vector<VideoCodec>
+rtp_extensions : vector<RtpExtension>
DataDescription
+sctp_port : int
+max_message_size : int
TransportDescription
+ice_ufrag : string
+ice_pwd : string
+fingerprint : DtlsFingerprint
2. Bundle 實現機制
PeerConnection TransportController NetworkStack 創建Bundle組(audio,video,data) 為audio創建傳輸通道 將video/data映射到audio的通道 返回ICE候選(僅audio端口) 候選應用于所有Bundle媒體 PeerConnection TransportController NetworkStack
3. 協商過程
共享
復用
復用
Offer生成
Bundle組聲明
音頻描述
視頻描述
數據描述
傳輸參數
實際應用場景
1. 多流會議系統
發布
音頻
視頻
屏幕共享
數據
User
PeerConnection
48kHz Opus
1080p VP9
720p VP8
文件傳輸
2. 性能優化效果指標 獨立傳輸 Bundle模式 提升 連接建立時間 800ms 300ms 62.5% 端口使用數 3 1 66.7% ICE開銷 高 低 - NAT穿透成功率 85% 95% +10%
調試技巧
1. 驗證Bundle有效性
grep -A 10 "m=" offer.sdp | grep -E "a=mid:|a=ice-ufrag:|a=fingerprint:"
a = mid:audio
a = ice-ufrag:8hhy
a = fingerprint:sha-256 A1:B2:C3:.. .
--
a = mid:video
a = ice-ufrag:8hhy
a = fingerprint:sha-256 A1:B2:C3:.. .
--
a = mid:data
a = ice-ufrag:8hhy
a = fingerprint:sha-256 A1:B2:C3:.. .
2. 關鍵日志點
RTC_LOG ( LS_INFO) << "Created bundle group with mids: " << bundle_group. ToString ( ) ;
RTC_LOG ( LS_VERBOSE) << "Reusing transport for mid=" << mid<< " from primary mid=" << primary_mid;
3. 網絡抓包分析
# 顯示Bundle端口的流量
udp.port == 49170 && (rtp || sctp || dtls)