WebRTC 多媒体 SDP 示例与解析

webRTC中的SDP的Bundlle可能包含一个或者多个媒体块(媒体描述, 源码对应类ContentInfo),从 m= 开始到下一个 m= 行(或 SDP 结束)之间的所有属性(包括 a=)都属于同一个媒体块(media section, 源码里面对应类MediaContentDescription),下面举例一个包含音频、视频和数据通道的完整 SDP 详细说明:

完整 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处理

cpp 复制代码
// pc/jsep_transport_controller.cc
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有效性

bash 复制代码
# 检查Bundle组内媒体是否兼容
grep -A 10 "m=" offer.sdp | grep -E "a=mid:|a=ice-ufrag:|a=fingerprint:"

# 预期输出应显示相同的ufrag和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. 关键日志点

cpp 复制代码
// 检查Bundle组创建
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. 网络抓包分析

wireshark-filter 复制代码
# 显示Bundle端口的流量
udp.port == 49170 && (rtp || sctp || dtls)
相关推荐
草根大哥2 天前
08-横向扩容与突发高并发:加机器到底买到了什么
运维·webrtc·srt·横向扩容·whip·自建cdn
草根大哥2 天前
07-P2P 直连与节点池调度
webrtc·p2p·srt·whip·whep·自建cdn
草根大哥2 天前
06-可观测性:端到端延迟、稳定性与画质
webrtc·srt·whip·自建cdn·ppcdn
大文说跨境2 天前
用 Python 自动化检测浏览器环境指纹:WebRTC 泄露、Canvas 哈希与时区一致性校验
python·自动化·webrtc
EasyDSS3 天前
基于WebRTC的视频会议系统:私有化视频会议平台EasyDSS视频会议到底能干什么
音视频·webrtc·easydss
福大大架构师每日一题6 天前
RustDesk 1.5.0发布:WebRTC、HDR 色调映射、剪贴板同步与百余项修复全面汇总
webrtc
福大大架构师每日一题11 天前
webrtc-rs/webrtc v0.21.0发布:API 可扩展、异步集成、确定性时间、ICE 重启与 SCTP 全面修复
webrtc
智联视频超融合平台11 天前
WebRTC + AI:实时音视频中嵌入神经网络推理的架构设计
人工智能·webrtc·实时音视频
P1Browser12 天前
换了 IP 还是被关联:WebRTC 泄露本地 IP 的三种触发路径
网络协议·tcp/ip·webrtc
福大大架构师每日一题13 天前
pion/webrtc v4.2.22 最新发布:TCP mux 写缓冲区调整至 4 MB,补齐缺失媒体方向处理
tcp/ip·webrtc·媒体