惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
L
LangChain Blog
Jina AI
Jina AI
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
T
Threat Research - Cisco Blogs
量子位
G
GRAHAM CLULEY
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
C
Cisco Blogs
Scott Helme
Scott Helme
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
V
V2EX
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
P
Proofpoint News Feed
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
PCI Perspectives
PCI Perspectives
博客园_首页
L
LINUX DO - 最新话题
IT之家
IT之家
有赞技术团队
有赞技术团队
博客园 - Franky
Hacker News: Ask HN
Hacker News: Ask HN
Last Week in AI
Last Week in AI
The Cloudflare Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
美团技术团队
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Security Archives - TechRepublic
Security Archives - TechRepublic
L
LINUX DO - 热门话题
AWS News Blog
AWS News Blog
S
Security Affairs
T
Tailwind CSS Blog

一个工匠

AI 发展临界点 - 快上车 流式响应(Chat):HTTP 响应体字节流的读取与解析 iPhone 截屏高效翻译 Flash Open Terminal iPhone 侧载安装 Xcode Symbolic Debug AI 指北 投资风险收益评估 Mac 快速修改系统快捷键 Git Record passkey How to pay apple frameworks Mac - Command Line Tools DNS 的 CNAME 是如何工作的 SSE 指南 1.1.1.1、WARP 和 MASQUE 移动端换端方案与场景还原 设备发现 分辨率 - 像素密度 - HiDPI Mac 字体 ESP32 trump - 川普 币圈 - 虚拟货币 【旅游】富士山 【旅游】sakura(樱花) 【旅游】千岛湖 我的 2023 【Swift】中文词语纠错 计算机字符编码与内存编码 - Unicode、UTF8、String 从汇编角度理解 “函数调用栈” 和 “有栈协程” 在 Xcode 中更好的使用 Swift 通过 Swift Package 制作二进制库 Arc 浏览器 - 意外的惊喜 【Swift 三方源码 1】SwiftShell 高效的命令行工具 Swift 脚本开发环境搭建 rime - 小鹤双拼 【旅游】沿海旅游 (威海、青岛) 好记性远远不如烂笔头 高级语言小记 又一年高考 Vision 未来已来 致敬耗子哥 Socket 与 ICMP 对互联网隐私的一些想法 网络代理是如何工作的 (致敬 Surge) 又十年 - 至三十而立 双拼 - 少有的高回报效率技能 Vim 技巧 我的 2022 三年疫情五味杂陈 - 下 老梗 - 浏览器按回车后发生了什么 三年疫情五味杂陈 生活推荐清单 Shell 和进程 有计划的努力 内卷 不确定性 数学可以保障逻辑自洽 这些年我的软件清单 决定做一些改变 函数调用栈之彻底理解 锁 - 共享数据安全指↑ 江苏女有感 碎碎念 - 2022 碎碎念 - 2021 打算记录一些碎碎念 多重性格就是逆天改命 从 Core Foundation 看更大世界 TCP 数据传输过程分析 iOS main 文件中的 @autoreleasepool 的真实用途 多线程的难点在哪里 Objective-C 和 Runtime 早起打卡计划 ing 打比方 IM 和 Socket 的关系及 Heart 的必要性 如果我的人生突然只剩下 8 小时... 胡说八道之雪粉 Array 和 LinkedList 的深刻认知 Swift struct (值类型) 与 class (引用类型) 区别及三种传参机制深刻关系和使用 逃离信用卡和花呗 Swift_let_var_struct_class 网聚人的力量 - 网易 绿皮火车 喝酒十之八九会误事 HKong 胡说八道之云服务 互联网网络传输协议理解坑点 CPU 的制作 我心里一直有一个念想 网络基础协议 为什么 32 位操作系统只能用 4G 内存空间 努力和天赋 洗牙 RAC-Api-Summer iOS 内存原理 Block 闭包简查记录 《白夜行》 谈谈事件驱动 老博新开 祭首
WebRTC 的一些解释
海驴 · 2024-11-09 · via 一个工匠

2 人参会,两个【客户端】直接打通,最舒适

4 人参会,每个【客户端】打开多个通道,上下行剧增,硬件消耗剧增

8 人参会,【服务端】作为中转通道,相比 4 人场景,下行剧增,上行剧减,硬件消耗增加

50 人参会,【服务端】作为终极合流通道。相比 8 人场景,客户端回退到 2 人消耗,并把所有消耗转移到【服务端】

Tips:当【服务端】作为 webrtc 的一个通道后,玩法就非常多样了。比如【说话人大屏】、【服务端滤镜】等

码率 = 分辨率 × 比特深度 × 帧率 × 压缩比
比特深度:描述一个 px 所需要的 bit。通常 RGB 为 3 色彩通道,每个色彩需要 8 个 bit,即 24 bit。
压缩比:H.264 / H.265 压缩效率极高,根据视频画面的【前后帧之间的 px 差异】,极大降低视频流尺寸。

示例:(场景设定:分辨率:1080p,色彩通道:3,帧率:30,编码:H.264)
码率 = 1920 × 1080 × 24 × 30 x 1 / 100 = 14.93 Mbps = 14930Kbps = 1866.25KBps = 1.87 MBps
即:每秒需要 1.87 M 的流量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
示例//=============会话描述====================
v=0
o=- 7017624586836067756 2 IN IP4 127.0.0.1
s=-
t=0 0
...

//================媒体描述=================
//================音频媒体=================
/*
* 音频使用端口1024收发数据
* UDP/TLS/RTP/SAVPF 表示使用 dtls/srtp 协议对数据加密传输
* 111、103 ... 表示本会话音频数据的 Payload Type
*/
m=audio 1024 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126

//==============网络描述==================
//指明接收或者发送音频使用的IP地址,由于WebRTC使用ICE传输,这个被忽略。
c=IN IP4 0.0.0.0
//用来设置rtcp地址和端口,WebRTC不使用
a=rtcp:9 IN IP4 0.0.0.0
...

//==============音频安全描述================
//ICE协商过程中的安全验证信息
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...

//==============音频流媒体描述================
a=rtpmap:111 opus/48000/2
//minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性
a=fmtp:111 minptime=10;useinbandfec=1
...
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
...

//=================视频媒体=================
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
...
//=================网络描述=================
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
...
//=================视频安全描述=================
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...

//================视频流描述===============
a=mid:video
...
a=rtpmap:100 VP8/90000
//================服务质量描述===============
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack //支持丢包重传,参考rfc4585
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb //支持使用rtcp包来控制发送方的码流
a=rtcp-fb:100 transport-cc
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
v=0
o=- 5595748951276187774 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic: WMS FAMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:2D6J
a=ice-pwd:jWsbseLplx44YJwXRravag7Y
a=ice-options:trickle renomination
a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
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=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:FAMS FAMSa0
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:3316953618 cname:cXfVAjx41LASIlBT
a=ssrc:3316953618 msid:FAMS FAMSa0
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:2D6J
a=ice-pwd:jWsbseLplx44YJwXRravag7Y
a=ice-options:trickle renomination
a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
a=setup:actpass
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:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 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:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendonly
a=msid:FAMS FAMSv1
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 H264/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=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c34
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 H264/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e034
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 red/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 ulpfec/90000
a=ssrc-group:FID 439044504 650966991
a=ssrc:439044504 cname:cXfVAjx41LASIlBT
a=ssrc:439044504 msid:FAMS FAMSv1
a=ssrc:650966991 cname:cXfVAjx41LASIlBT
a=ssrc:650966991 msid:FAMS FAMSv1
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:2D6J
a=ice-pwd:jWsbseLplx44YJwXRravag7Y
a=ice-options:trickle renomination
a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
a=setup:actpass
a=mid:2
a=sctp-port:5000
a=max-message-size:262144
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
//==会话描述==

v=0
- **协议版本**:SDP 协议版本号,这里是版本0。

o=- 5595748951276187774 2 IN IP4 127.0.0.1
- **会话起源**:
- 用户名:`-`(匿名)
- 会话ID:`5595748951276187774`
- 会话版本:`2`
- 网络类型:`IN`(互联网)
- 地址类型:`IP4`
- 地址:`127.0.0.1`(本地回环地址)

s=-
- **会话名称**:`-`(未指定)

t=0 0
- **会话活动时间**:从`0`到`0`,表示会话无限期有效。

a=group:BUNDLE 0 1 2
- **媒体流分组**:使用`BUNDLE`机制将媒体流`0`、`1`和`2`绑定在一起,共享一个传输通道。

a=extmap-allow-mixed
- **扩展映射混合允许**:允许同时使用一字节和两字节的RTP头扩展(参考RFC 8285)。

a=msid-semantic: WMS FAMS
- **媒体流标识语义**:`WMS`表示WebRTC媒体流,`FAMS`是媒体流的标识符。


//==音频媒体描述==

m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
- **媒体描述**:
- 媒体类型:`audio`(音频)
- 端口:`9`(通常为`9`表示使用UDP/TLS/RTP协议并通过ICE协商实际端口)
- 传输协议:`UDP/TLS/RTP/SAVPF`(安全的RTP协议,带反馈机制)
- 有效负载类型(编码):`111`、`63`、`9`、`102`、`0`、`8`、`13`、`110`、`126`

c=IN IP4 0.0.0.0
- **连接信息**:
- 网络类型:`IN`(互联网)
- 地址类型:`IP4`
- 地址:`0.0.0.0`(占位符,表示实际地址通过ICE协商)

a=rtcp:9 IN IP4 0.0.0.0
- **RTCP连接信息**:
- 端口:`9`
- 网络类型:`IN`
- 地址类型:`IP4`
- 地址:`0.0.0.0`

a=ice-ufrag:2D6J
- **ICE用户名碎片**:`2D6J`,用于ICE候选者的身份认证。

a=ice-pwd:jWsbseLplx44YJwXRravag7Y
- **ICE密码**:`jWsbseLplx44YJwXRravag7Y`,用于ICE身份验证。

a=ice-options:trickle renomination
- **ICE选项**:
- `trickle`:支持逐步收集和发送ICE候选者(Trickle ICE)。
- `renomination`:支持重新提名最佳候选者。

a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
- **DTLS指纹**:
- 哈希算法:`sha-256`
- 指纹值:用于验证DTLS握手的安全性。

a=setup:actpass
- **DTLS连接角色**:`actpass`表示主动-被动,双方可协商谁主动发起DTLS握手。

a=mid:0
- **媒体标识符**:`0`,用于在BUNDLE中标识此媒体流。

a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
- **RTP头扩展**:
- ID:`1`
- URI:`ssrc-audio-level`,用于传输音频电平信息。

a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
- **RTP头扩展**:
- ID:`2`
- URI:`abs-send-time`,用于同步媒体流的发送时间。

a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
- **RTP头扩展**:
- ID:`3`
- URI:`transport-wide-cc`,用于传输层的拥塞控制。

a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
- **RTP头扩展**:
- ID:`4`
- URI:`mid`,用于标识媒体流的MID。

a=sendrecv
- **发送接收方向**:支持同时发送和接收媒体流。

a=msid:FAMS FAMSa0
- **媒体流标识**:
- 流ID:`FAMS`
- 轨道ID:`FAMSa0`

a=rtcp-mux
- **RTCP复用**:音频的RTCP流与RTP流复用在同一个端口。

a=rtpmap:111 opus/48000/2
- **RTP映射**:
- 编码:`opus`
- 采样率:`48000`Hz
- 声道数:`2`

a=rtcp-fb:111 transport-cc
- **RTCP反馈机制**:
- 针对编码`111`(opus),支持`transport-cc`(传输层拥塞控制)。

a=fmtp:111 minptime=10;useinbandfec=1
- **格式参数**:
- 针对编码`111`(opus)
- `minptime=10`:最小包时间为10毫秒
- `useinbandfec=1`:启用带内前向纠错(FEC),提高音频质量

a=rtpmap:63 red/48000/2
- **RTP映射**:
- 编码:`red`(冗余编码)
- 采样率:`48000`Hz
- 声道数:`2`

a=fmtp:63 111/111
- **格式参数**:
- 针对编码`63`(red)
- `111/111`:表示冗余编码中使用的主、次编码类型都是`111`(opus)

a=rtpmap:9 G722/8000
- **RTP映射**:
- 编码:`G722`
- 采样率:`8000`Hz

a=rtpmap:102 ILBC/8000
- **RTP映射**:
- 编码:`iLBC`
- 采样率:`8000`Hz

a=rtpmap:0 PCMU/8000
- **RTP映射**:
- 编码:`PCMU`(G.711 μ-law)
- 采样率:`8000`Hz

a=rtpmap:8 PCMA/8000
- **RTP映射**:
- 编码:`PCMA`(G.711 A-law)
- 采样率:`8000`Hz

a=rtpmap:13 CN/8000
- **RTP映射**:
- 编码:`CN`(舒适噪声)
- 采样率:`8000`Hz

a=rtpmap:110 telephone-event/48000
- **RTP映射**:
- 编码:`telephone-event`(DTMF信号)
- 采样率:`48000`Hz

a=rtpmap:126 telephone-event/8000
- **RTP映射**:
- 编码:`telephone-event`(DTMF信号)
- 采样率:`8000`Hz

a=ssrc:3316953618 cname:cXfVAjx41LASIlBT
- **同步源(SSRC)标识**:
- SSRC:`3316953618`
- CNAME:`cXfVAjx41LASIlBT`,用于跨媒体流同步

a=ssrc:3316953618 msid:FAMS FAMSa0
- **媒体流标识**:
- 流ID:`FAMS`
- 轨道ID:`FAMSa0`

//==视频媒体描述==

m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127
- **媒体描述**:
- 媒体类型:`video`(视频)
- 端口:`9`(通过ICE协商实际端口)
- 传输协议:`UDP/TLS/RTP/SAVPF`(安全的RTP协议,带反馈机制)
- 有效负载类型(编码):`96`、`97`、`98`、`99`、`100`、`101`、`127`

c=IN IP4 0.0.0.0
- **连接信息**:与音频部分相同

a=rtcp:9 IN IP4 0.0.0.0
- **RTCP连接信息**:与音频部分相同

a=ice-ufrag:2D6J
- **ICE用户名碎片**:`2D6J`,与音频部分相同

a=ice-pwd:jWsbseLplx44YJwXRravag7Y
- **ICE密码**:`jWsbseLplx44YJwXRravag7Y`,与音频部分相同

a=ice-options:trickle renomination
- **ICE选项**:支持Trickle ICE和重新提名机制

a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
- **DTLS指纹**:用于DTLS握手的安全验证

a=setup:actpass
- **DTLS连接角色**:双方均可主动或被动,待协商

a=mid:1
- **媒体标识符**:`1`,用于BUNDLE中的媒体流标识

a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
- **RTP头扩展**:
- ID:`14`
- URI:`toffset`,传输时间偏移

a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
- **RTP头扩展**:ID `2`,绝对发送时间

a=extmap:13 urn:3gpp:video-orientation
- **RTP头扩展**:
- ID:`13`
- URI:`video-orientation`,视频方向信息

a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
- **RTP头扩展**:ID `3`,传输层拥塞控制

a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
- **RTP头扩展**:
- ID:`5`
- URI:`playout-delay`,播放延迟建议

a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
- **RTP头扩展**:
- ID:`6`
- URI:`video-content-type`,视频内容类型

a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
- **RTP头扩展**:
- ID:`7`
- URI:`video-timing`,视频定时信息

a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
- **RTP头扩展**:
- ID:`8`
- URI:`color-space`,视频色彩空间信息

a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
- **RTP头扩展**:ID `4`,媒体标识(MID)

a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
- **RTP头扩展**:
- ID:`10`
- URI:`rtp-stream-id`,RTP流标识

a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
- **RTP头扩展**:
- ID:`11`
- URI:`repaired-rtp-stream-id`,修复的RTP流标识

a=sendonly
- **发送方向**:只发送,不接收

a=msid:FAMS FAMSv1
- **媒体流标识**:
- 流ID:`FAMS`
- 轨道ID:`FAMSv1`

a=rtcp-mux
- **RTCP复用**:将RTCP与RTP复用同一端口

a=rtcp-rsize
- **RTCP缩减大小**:使用较小的RTCP报文(RFC 5506)

a=rtpmap:96 H264/90000
- **RTP映射**:
- 编码:`H264`
- 采样率:`90000`Hz

a=rtcp-fb:96 goog-remb
- **RTCP反馈**:
- 针对编码`96`,支持`goog-remb`带宽估计

a=rtcp-fb:96 transport-cc
- **RTCP反馈**:
- 支持传输层拥塞控制

a=rtcp-fb:96 ccm fir
- **RTCP反馈**:
- 支持`ccm fir`(全帧请求)

a=rtcp-fb:96 nack
- **RTCP反馈**:
- 支持`nack`(否定确认)用于丢包重传

a=rtcp-fb:96 nack pli
- **RTCP反馈**:
- 支持`pli`(图片丢失指示),请求关键帧

a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c34
- **格式参数**:
- 允许非对称级别:`level-asymmetry-allowed=1`
- 分包模式:`packetization-mode=1`(非交错模式)
- 配置文件级别:`profile-level-id=640c34`(High Profile,Level 3.4)

a=rtpmap:97 rtx/90000
- **RTP映射**:
- 编码:`rtx`(重传)
- 采样率:`90000`Hz

a=fmtp:97 apt=96
- **格式参数**:
- 关联有效负载类型:`apt=96`(对应H264编码)

a=rtpmap:98 H264/90000
- **RTP映射**:
- 编码:`H264`
- 采样率:`90000`Hz

a=rtcp-fb:98 goog-remb
- **RTCP反馈**:同编码`96`

a=rtcp-fb:98 transport-cc
- **RTCP反馈**:同编码`96`

a=rtcp-fb:98 ccm fir
- **RTCP反馈**:同编码`96`

a=rtcp-fb:98 nack
- **RTCP反馈**:同编码`96`

a=rtcp-fb:98 nack pli
- **RTCP反馈**:同编码`96`

a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e034
- **格式参数**:
- 配置文件级别:`profile-level-id=42e034`(Baseline Profile,Level 3.4)

a=rtpmap:99 rtx/90000
- **RTP映射**:
- 编码:`rtx`
- 采样率:`90000`Hz

a=fmtp:99 apt=98
- **格式参数**:
- 关联有效负载类型:`apt=98`(对应H264编码)

a=rtpmap:100 red/90000
- **RTP映射**:
- 编码:`red`(冗余编码)
- 采样率:`90000`Hz

a=rtpmap:101 rtx/90000
- **RTP映射**:
- 编码:`rtx`
- 采样率:`90000`Hz

a=fmtp:101 apt=100
- **格式参数**:
- 关联有效负载类型:`apt=100`(对应red编码)

a=rtpmap:127 ulpfec/90000
- **RTP映射**:
- 编码:`ulpfec`(前向纠错)
- 采样率:`90000`Hz

a=ssrc-group:FID 439044504 650966991
- **SSRC组**:
- 组语义:`FID`(流标识)
- SSRC列表:`439044504`(主流),`650966991`(重传流)

a=ssrc:439044504 cname:cXfVAjx41LASIlBT
- **同步源(SSRC)标识**:
- SSRC:`439044504`
- CNAME:`cXfVAjx41LASIlBT`

a=ssrc:439044504 msid:FAMS FAMSv1
- **媒体流标识**:
- 流ID:`FAMS`
- 轨道ID:`FAMSv1`

a=ssrc:650966991 cname:cXfVAjx41LASIlBT
- **同步源(SSRC)标识**:
- SSRC:`650966991`
- CNAME:`cXfVAjx41LASIlBT`

a=ssrc:650966991 msid:FAMS FAMSv1
- **媒体流标识**:
- 流ID:`FAMS`
- 轨道ID:`FAMSv1`

//==数据通道描述==

m=application 9 UDP/DTLS/SCTP webrtc-datachannel
- **媒体描述**:
- 媒体类型:`application`(应用数据)
- 端口:`9`(通过ICE协商)
- 传输协议:`UDP/DTLS/SCTP`(基于DTLS的SCTP传输)
- 格式:`webrtc-datachannel`,表示WebRTC数据通道

c=IN IP4 0.0.0.0
- **连接信息**:与前面一致

a=ice-ufrag:2D6J
- **ICE用户名碎片**:`2D6J`,与前面一致

a=ice-pwd:jWsbseLplx44YJwXRravag7Y
- **ICE密码**:`jWsbseLplx44YJwXRravag7Y`,与前面一致

a=ice-options:trickle renomination
- **ICE选项**:支持Trickle ICE和重新提名

a=fingerprint:sha-256 F4:57:8B:7E:6C:A1:0F:08:95:72:67:68:3C:18:67:40:39:D9:D5:0A:A4:6E:C0:3E:67:BA:E0:02:B5:FF:EF:40
- **DTLS指纹**:用于安全验证

a=setup:actpass
- **DTLS连接角色**:双方均可主动或被动

a=mid:2
- **媒体标识符**:`2`,用于BUNDLE中的媒体流标识

a=sctp-port:5000
- **SCTP端口**:`5000`,用于SCTP协议的传输

a=max-message-size:262144
- **最大消息大小**:`262144`字节,数据通道单次消息的最大尺寸

candidate: 一个可能的网络连接点的候选项。网络节点负责最终的音视频流传输的数据通道,很重要
sdpMid / sdpMLineIndex: 用来标记 SDP 中的媒体流索引。即每一个 candidate 候选,都属于某一个媒体流通道,如 音频流、视频流等。

1
2
3
4
5
6
7
8
9
{
"candidate": "candidate:4109260943 1 udp 8331263 x.x.x.x 36634 typ relay raddr x.x.x.x rport 63859 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
}

优先级排序:
1. 候选类型:host > srflx > relay
2. 网络成本 network-cost:wifi > 蜂窝

下面示例,是使用 Cloudflare TURN 服务采集到的一个网络发现节点:
candidate:4109260943 1 udp 8331263 x.x.x.x 36634 typ relay raddr x.x.x.x rport 63859 generation 0 ufrag 2D6J network-id 1 network-cost 10

tips:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
[
{
"candidate": "candidate:2524315334 1 udp 2122260223 10.0.3.39 59309 typ host generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:2489915706 1 udp 2122194687 169.254.125.209 51656 typ host generation 0 ufrag 2D6J network-id 2 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1463068104 1 udp 2121998079 192.0.0.1 54311 typ host generation 0 ufrag 2D6J network-id 7 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:878085806 1 udp 2122131711 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 50281 typ host generation 0 ufrag 2D6J network-id 8 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:3258950406 1 udp 2122066175 240b:c010:823:5c21:40a5:9a43:ff0c:906 58647 typ host generation 0 ufrag 2D6J network-id 9 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:306562041 1 udp 2121935103 240b:c010:823:5c21:18b6:b94e:abe4:cec2 53502 typ host generation 0 ufrag 2D6J network-id 3 network-cost 50",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:306562041 1 udp 2121869567 240b:c010:823:5c21:18b6:b94e:abe4:cec2 54246 typ host generation 0 ufrag 2D6J network-id 4 network-cost 50",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:2524315334 1 udp 2122260223 10.0.3.39 49555 typ host generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:2489915706 1 udp 2122194687 169.254.125.209 50166 typ host generation 0 ufrag 2D6J network-id 2 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:1463068104 1 udp 2121998079 192.0.0.1 53998 typ host generation 0 ufrag 2D6J network-id 7 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:878085806 1 udp 2122131711 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 52161 typ host generation 0 ufrag 2D6J network-id 8 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:3258950406 1 udp 2122066175 240b:c010:823:5c21:40a5:9a43:ff0c:906 60559 typ host generation 0 ufrag 2D6J network-id 9 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:306562041 1 udp 2121935103 240b:c010:823:5c21:18b6:b94e:abe4:cec2 50196 typ host generation 0 ufrag 2D6J network-id 3 network-cost 50",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63867 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:3975092077 1 tcp 1517889791 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63868 typ host tcptype passive generation 0 ufrag 2D6J network-id 4 network-cost 50",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1759455826 1 tcp 1518280447 10.0.3.39 63862 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1791217070 1 tcp 1518214911 169.254.125.209 63863 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:2845733212 1 tcp 1518018303 192.0.0.1 63864 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63865 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63866 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1759455826 1 tcp 1518280447 10.0.3.39 63869 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:1791217070 1 tcp 1518214911 169.254.125.209 63870 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:2845733212 1 tcp 1518018303 192.0.0.1 63871 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63872 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63873 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63874 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:1759455826 1 tcp 1518280447 10.0.3.39 63876 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:1791217070 1 tcp 1518214911 169.254.125.209 63877 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:2845733212 1 tcp 1518018303 192.0.0.1 63878 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63879 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63880 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63881 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:3975092077 1 tcp 1517889791 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63882 typ host tcptype passive generation 0 ufrag 2D6J network-id 4 network-cost 50",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:1410854543 1 udp 25108735 x.x.x.x 53914 typ relay raddr x.x.x.x rport 63839 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:1101771793 1 udp 41886207 x.x.x.x 53010 typ relay raddr x.x.x.x rport 49555 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:1101771793 1 udp 41886207 x.x.x.x 52333 typ relay raddr x.x.x.x rport 59309 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:1541054091 1 udp 25108735 x.x.x.x 52668 typ relay raddr x.x.x.x rport 63829 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
},
{
"candidate": "candidate:3011387645 1 udp 25108735 x.x.x.x 44090 typ relay raddr x.x.x.x rport 63857 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:351976030 1 udp 8331263 x.x.x.x 46887 typ relay raddr x.x.x.x rport 63834 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 1,
"sdpMid": "1"
},
{
"candidate": "candidate:4109260943 1 udp 8331263 x.x.x.x 36634 typ relay raddr x.x.x.x rport 63859 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 2,
"sdpMid": "2"
},
{
"candidate": "candidate:2106314174 1 udp 8331263 x.x.x.x 23955 typ relay raddr x.x.x.x rport 63831 generation 0 ufrag 2D6J network-id 1 network-cost 10",
"sdpMLineIndex": 0,
"sdpMid": "0"
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
candidate:2524315334 1 udp 2122260223 10.0.3.39 59309 typ host generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:2489915706 1 udp 2122194687 169.254.125.209 51656 typ host generation 0 ufrag 2D6J network-id 2 network-cost 10
candidate:1463068104 1 udp 2121998079 192.0.0.1 54311 typ host generation 0 ufrag 2D6J network-id 7 network-cost 900
candidate:878085806 1 udp 2122131711 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 50281 typ host generation 0 ufrag 2D6J network-id 8 network-cost 900
candidate:3258950406 1 udp 2122066175 240b:c010:823:5c21:40a5:9a43:ff0c:906 58647 typ host generation 0 ufrag 2D6J network-id 9 network-cost 900
candidate:306562041 1 udp 2121935103 240b:c010:823:5c21:18b6:b94e:abe4:cec2 53502 typ host generation 0 ufrag 2D6J network-id 3 network-cost 50
candidate:306562041 1 udp 2121869567 240b:c010:823:5c21:18b6:b94e:abe4:cec2 54246 typ host generation 0 ufrag 2D6J network-id 4 network-cost 50
candidate:2524315334 1 udp 2122260223 10.0.3.39 49555 typ host generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:2489915706 1 udp 2122194687 169.254.125.209 50166 typ host generation 0 ufrag 2D6J network-id 2 network-cost 10
candidate:1463068104 1 udp 2121998079 192.0.0.1 53998 typ host generation 0 ufrag 2D6J network-id 7 network-cost 900
candidate:878085806 1 udp 2122131711 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 52161 typ host generation 0 ufrag 2D6J network-id 8 network-cost 900
candidate:3258950406 1 udp 2122066175 240b:c010:823:5c21:40a5:9a43:ff0c:906 60559 typ host generation 0 ufrag 2D6J network-id 9 network-cost 900
candidate:306562041 1 udp 2121935103 240b:c010:823:5c21:18b6:b94e:abe4:cec2 50196 typ host generation 0 ufrag 2D6J network-id 3 network-cost 50
candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63867 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50
candidate:3975092077 1 tcp 1517889791 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63868 typ host tcptype passive generation 0 ufrag 2D6J network-id 4 network-cost 50
candidate:1759455826 1 tcp 1518280447 10.0.3.39 63862 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1791217070 1 tcp 1518214911 169.254.125.209 63863 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10
candidate:2845733212 1 tcp 1518018303 192.0.0.1 63864 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900
candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63865 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900
candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63866 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900
candidate:1759455826 1 tcp 1518280447 10.0.3.39 63869 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1791217070 1 tcp 1518214911 169.254.125.209 63870 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10
candidate:2845733212 1 tcp 1518018303 192.0.0.1 63871 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900
candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63872 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900
candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63873 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900
candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63874 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50
candidate:1759455826 1 tcp 1518280447 10.0.3.39 63876 typ host tcptype passive generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1791217070 1 tcp 1518214911 169.254.125.209 63877 typ host tcptype passive generation 0 ufrag 2D6J network-id 2 network-cost 10
candidate:2845733212 1 tcp 1518018303 192.0.0.1 63878 typ host tcptype passive generation 0 ufrag 2D6J network-id 7 network-cost 900
candidate:3405533754 1 tcp 1518151935 240b:c010:401:2c70:518d:9e8c:aa43:2dc4 63879 typ host tcptype passive generation 0 ufrag 2D6J network-id 8 network-cost 900
candidate:1016428434 1 tcp 1518086399 240b:c010:823:5c21:40a5:9a43:ff0c:906 63880 typ host tcptype passive generation 0 ufrag 2D6J network-id 9 network-cost 900
candidate:3975092077 1 tcp 1517955327 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63881 typ host tcptype passive generation 0 ufrag 2D6J network-id 3 network-cost 50
candidate:3975092077 1 tcp 1517889791 240b:c010:823:5c21:18b6:b94e:abe4:cec2 63882 typ host tcptype passive generation 0 ufrag 2D6J network-id 4 network-cost 50
candidate:1410854543 1 udp 25108735 x.x.x.x 53914 typ relay raddr x.x.x.x rport 63839 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1101771793 1 udp 41886207 x.x.x.x 53010 typ relay raddr x.x.x.x rport 49555 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1101771793 1 udp 41886207 x.x.x.x 52333 typ relay raddr x.x.x.x rport 59309 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:1541054091 1 udp 25108735 x.x.x.x 52668 typ relay raddr x.x.x.x rport 63829 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:3011387645 1 udp 25108735 x.x.x.x 44090 typ relay raddr x.x.x.x rport 63857 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:351976030 1 udp 8331263 x.x.x.x 46887 typ relay raddr x.x.x.x rport 63834 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:4109260943 1 udp 8331263 x.x.x.x 36634 typ relay raddr x.x.x.x rport 63859 generation 0 ufrag 2D6J network-id 1 network-cost 10
candidate:2106314174 1 udp 8331263 x.x.x.x 23955 typ relay raddr x.x.x.x rport 63831 generation 0 ufrag 2D6J network-id 1 network-cost 10,

在 ipv6 越多的场景下,上面提到的 ipv4 NAT 问题可以有效解决。但 STUN 网络发现依旧不可缺少。local、多 ipv6、防火墙等场景依旧需要网络择优。
ipv6 场景下,不需要打洞就能直连,最具有性价比。以下场景可以专门做【协商回退】处理:

1
2
3
4
5
6
7
8
pc.onicecandidate = event => {
if (event.candidate) {
if (event.candidate.address.indexOf(':') !== -1) {
// IPv6候选者,可能优先处理
handleIPv6Candidate(event.candidate);
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pc.oniceconnectionstatechange = () => {
switch(this.pc.iceConnectionState) {
case 'checking':
// 设置连接超时
connectionTimer = setTimeout(() => {
this.handleConnectionTimeout();
}, this.connectionTimeout);
break;
}
};

async handleConnectionTimeout() {
console.log('连接超时,尝试回退策略');
if (this.preferredProtocol === 'IPv6') {
console.log('切换到IPv4');
this.preferredProtocol = 'IPv4';
await this.restartConnection();
} else {
console.log('尝试TURN服务器');
await this.switchToTURN();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Example:
https://webrtcpush.tlivewebrtcpush.com/webrtc/v2/whip

// WHIP 服务
const server = http.createServer((req, res) => {
// 处理 WHIP 客户端请求
switch (req.method) {
case "POST":
// 生成 SDP Answer
const sdpAnswer = generateSdpAnswer(sdpOffer);
res.statusCode = 201;
res.setHeader("Location", `/whip/sessions/${randomUUID()}`);// 用于 delete
res.end(sdpAnswer);
case "PATCH":
// 处理 ICE 候选
let iceCandidate = req.text();
handleIceCandidate(iceCandidate);
case "DELETE":
// 处理会话删除
deleteSession(req.sessionId);
case "OPTIONS":
// 处理能力协商
res.setHeader("Allow", "POST, PATCH, DELETE, OPTIONS");
res.setHeader("Accept", "application/sdp");
}
res.end();
});

function generateSdpAnswer(sdpOffer) {
return `v=0 o=- 123456789 123456789 IN IP4 0.0.0.0 s=- t=0 0 m=video 9 UDP/TLS/RTP/SAVPF 96 c=IN IP4 0.0.0.0 a=rtpmap:96 VP8/90000 a=setup:active a=mid:0 `;
}

function handleIceCandidate(iceCandidate) {
console.log("Received ICE candidate:", iceCandidate);
}

function deleteSession(sessionId) {
console.log("Deleting session:", sessionId);
}

WebRTC 中 3A (AEC、AGC、ANC) 音频算法最顶级处理音频的算法,可以直接拿来用。
对于网络方向,网络带宽的评估、平滑处理、网络协议的实现在 WebRTC 中是应有尽有。