🎬 第七章 流媒体开源库简介
📄 一句话概括

WebRTC 分三层:应用层给 API、引擎层管音视频、网络层管打洞与加密。 连接数是平方级,所以 P2P 只适合一对一。

📝 本节和前面几节的关系

7.5 与 7.6 都是服务器,这一节转到浏览器里的直播。 7.7.2 与 7.7.3 分别细看视频与音频这两条链路。

一、三层

应用层:getUserMedia、RTCPeerConnection、RTCDataChannel。 浏览器暴露给 JavaScript 的就这三个。 引擎层:音视频引擎、编解码、抖动缓冲、回声消除、自动增益。 这一层把「采集到的原始数据」变成「可传输的编码流」。 网络层:ICE、STUN、TURN、DTLS、SRTP。 这一层解决「怎么穿 NAT」与「怎么加密」。

分层的好处是「换一层不影响其它层」: 换编码器不用动网络层,换 NAT 穿透方案不用动引擎层。 这也是 WebRTC 能持续演进的原因。

二、P2P 与 SFU 的连接数

纯 P2P 是「两两相连」,连接数是 N×(N-1)/2。 SFU 是「每个人只连服务器」,连接数是 N。

实测对比很直观: 2 人时 P2P 只要 1 条、SFU 要 2 条; 8 人时 P2P 28 条、SFU 8 条; 32 人时 P2P 496 条、SFU 32 条——差 15.5 倍。

而且 P2P 的每条连接都要自己编码一路: 32 人时每台机器要编 31 路、发 31 路。 所以 4 人以上基本就别考虑纯 P2P 了,直接上 SFU。

P2P 唯一还占优的场景是「一对一」: 两个人时只有 1 条连接,服务器完全不参与媒体转发,成本最低。 所以视频客服、远程协助这类场景仍然首选 P2P。

三、打洞为什么需要三台服务器

① 信令服务器:交换 SDP 与 ICE 候选。WebRTC 自己不管这一步。 ② STUN 服务器:告诉客户端「你的公网地址是什么」。 ③ TURN 服务器:对称 NAT 打不通时做中继。

这三样都不在标准 API 里,得自己搭—— 这是 WebRTC 落地最容易被低估的部分。 很多人以为「调个 API 就能通」,结果卡在 NAT 上几天。

其中 TURN 的带宽成本最高,因为它是「媒体中继」: 流量真的从它身上过,不是只帮忙打招呼。 所以生产上要尽量让 P2P 或 STUN 打通,TURN 只做兜底。

四、动手 Demo:WebRTC 架构——三层,连接数是平方级

先列三层职责,再算 P2P 与 SFU 的连接数随人数怎么变。 算完就知道「4 人以上别用纯 P2P」。

print("人数  P2P 连接  SFU 连接  P2P/SFU")
for n in (2, 4, 8, 16, 32):
    p2p = n * (n - 1) // 2
    print("%4d  %8d  %9d  %7.1f" % (n, p2p, n, p2p / n))

print()
n = 32
print("%d 人时纯 P2P 每人要编 %d 路、发 %d 路" % (n, n - 1, n - 1))
print("%d 人时 SFU 每人只编 1 路、发 1 路" % n)

实跑输出:

--------------------------------------------------------------------
WebRTC 架构——三层,连接数是平方级
--------------------------------------------------------------------
**① 三层**

  层         内容
  --------------------------------------------------------------
  应用层     getUserMedia/RTCPeerConnection/RTCDataChannel
  引擎层     音视频引擎、编解码、抖动缓冲、回声消除
  网络层     ICE、STUN、TURN、DTLS、SRTP

**② P2P 与 SFU 的连接数**

  **纯 P2P 是「两两相连」,连接数是 N×(N-1)/2;**
  **SFU 是「每个人只连服务器」,连接数是 N。**

  人数     P2P 连接数     SFU 连接数     倍数
  -----------------------------------------------
  2        1              2              0.5
  4        6              4              1.5
  8        28             8              3.5
  16       120            16             7.5
  32       496            32             15.5

  **32 人时 P2P 要 496 条连接,SFU 只要 32 条——差 15.5 倍。**
  **而且 P2P 的每条连接都要自己编码一路,**
  **所以 4 人以上基本就别考虑纯 P2P 了,直接上 SFU。**

  **P2P 唯一还占优的场景是「一对一」:**
  **两个人时 P2P 只有 1 条连接,服务器完全不参与媒体转发,成本最低。**

2 人时 P2P 只要 1 条,这是它唯一比 SFU 省的场景。 P2P/SFU 的比值就是 (N-1)/2,人数翻倍比值也翻倍。 「每人编 N-1 路」才是 P2P 真正的杀手,编码比连接更耗 CPU。

30 秒实验

  1. 把人数加到 64,看 P2P 连接数——2016 条,这时连连接表都建不起来。
  2. 加一行 3 人的数据,看比值——1.0,说明 3 人是 P2P 与 SFU 的临界点。
  3. 把「编 N-1 路」改成「编 1 路后转发」,想想这是不是 MCU——不是,MCU 是服务器端混流,等于把解码也包了。

常见误区

  1. 「WebRTC 一定走 P2P」——多人场景都走 SFU。
  2. 「调 API 就能连通」——还得有信令、STUN、TURN。
  3. 「TURN 只是帮忙打招呼」——它是媒体中继,流量真的过它。
自测三问(点开对答案) 1. WebRTC 的三层是什么? —— **应用层、引擎层、网络层**;只有应用层暴露给 JavaScript。 2. 为什么 4 人以上不适合 P2P? —— **连接数与编码路数都是平方级增长**,每人要编 N-1 路。 3. 三台辅助服务器分别做什么? —— **信令交换 SDP、STUN 报公网地址、TURN 做中继兜底。**

相关笔记