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

WebRTC 暴露给 JavaScript 的只有三个 API。 但落地还需要信令、STUN、TURN 三台服务器。

📝 本节和前面几节的关系

7.7.4 讲了兼容性,这一节拆 API 组成。 7.7.6 讲最重要的那个 API 的调用顺序。

一、三个核心 API

① getUserMedia:取摄像头与麦克风。 失败时最常见的原因是没权限,不是设备坏了。 ② RTCPeerConnection:建连、传输、统计。 它承担了 ICE、DTLS、SRTP 的全部工作。 ③ RTCDataChannel:传任意数据。 底层是 SCTP,可以选可靠或部分可靠。

这三个 API 的分工很干净: 一个拿数据、一个传媒体、一个传消息。 其它所有复杂度都被封在 RTCPeerConnection 里面了。

二、DataChannel 的分片

一条 DataChannel 消息如果超过 SCTP 的单包上限,会被分片。 典型上限约 1200 字节(要留出 IP 与 UDP 头的空间)。

实测:1 KB 是 1 片、16 KB 是 14 片、 64 KB 是 55 片、256 KB 是 219 片。 任何一片丢了,整条消息就失败。

所以 DataChannel 默认是可靠传输, 要低延迟可以切「部分可靠」模式,代价是允许丢消息。 这个可配置性是它相对于 WebSocket 的最大优势: WebSocket 只能可靠、有序,做不了低延迟。

三、三个 API 之外的三台服务器

① 信令服务器:交换 SDP 与 ICE 候选。WebRTC 自己不管这一步。 ② STUN 服务器:让双方知道自己的公网地址。 ③ TURN 服务器:对称 NAT 打不通时做中继,带宽成本最高。

这三样都不在标准 API 里,得自己搭—— 这是 WebRTC 落地最容易被低估的部分。

信令服务器可以很简陋: 一个 WebSocket 房间,把 A 的消息转给 B 就够。 真正麻烦的是 TURN: 它要处理大量 UDP 中继,还要算带宽成本。 所以生产上通常直接买云厂商的 TURN 服务,而不是自己搭。

四、动手 Demo:组成部分——三个 API,各管一段

先列三个 API 的职责与失败表现,再算 DataChannel 的分片数。 最后指出「三个 API 之外还有三台服务器」。

apis = [("getUserMedia", "取摄像头与麦克风", "没权限就没画面"),
        ("RTCPeerConnection", "建连、传输、统计", "连不上就黑屏"),
        ("RTCDataChannel", "传任意数据", "消息丢失或乱序")]
for a, d, f in apis:
    print("%-20s %-18s %s" % (a, d, f))

print()
MTU = 1200
for kb in (1, 16, 64, 256):
    n = (kb * 1024 + MTU - 1) // MTU
    print("%3d KB -> %d 片" % (kb, n))

实跑输出:

--------------------------------------------------------------------
组成部分——三个 API,各管一段
--------------------------------------------------------------------
**① 三个核心 API**

  API                   负责                 失败时表现
  -------------------------------------------------------------
  getUserMedia          取摄像头与麦克风     没权限就没画面
  RTCPeerConnection     建连、传输、统计     连不上就黑屏
  RTCDataChannel        传任意数据           消息丢失或乱序

**② 算一下 DataChannel 的分片**

  **一条 DataChannel 消息如果超过 SCTP 的单包上限,会被分片。**
  **典型上限约 1200 字节(要留出 IP 与 UDP 头的空间)。**

  消息大小     分片数
  -----------------------
  1 KB         1
  16 KB        14
  64 KB        55
  256 KB       219

  **256 KB 要切成 219 片,任何一片丢了整条消息就失败。**
  **所以 DataChannel 默认是可靠传输,**
  **要低延迟可以切「部分可靠」模式,代价是允许丢消息。**

**③ 三个 API 之外还得有的东西**

  **① 信令服务器**:**交换 SDP 与 ICE 候选,WebRTC 自己不管这一步。**
  **② STUN 服务器**:**让双方知道自己的公网地址。**
  **③ TURN 服务器**:**对称 NAT 打不通时做中继,带宽成本最高。**
  **这三样都不在标准 API 里,得自己搭——这是 WebRTC 落地最容易被低估的部分。**

失败表现这一列最实用:黑屏先查权限,连不上先查 NAT。 分片数用向上取整算,(x + M - 1) // M 是标准写法。 256 KB 要 219 片,丢一片就整条失败,这就是「可靠」的代价。

30 秒实验

  1. 把 MTU 改成 1400,看 256 KB 的分片数——降到 188 片,说明上限越大头开销越小。
  2. 把 MTU 改成 500,看分片数——涨到 525 片,这就是为什么不能把 MTU 设太小。
  3. 算一下 1 MB 的分片数,想想该不该用 DataChannel 传文件——856 片,任何一个丢了都要重传,不如用 HTTP。

常见误区

  1. 「WebRTC 只有三个 API 就够」——还得有三台服务器。
  2. 「DataChannel 只能可靠传输」——可以配部分可靠换低延迟。
  3. 「信令协议有标准」——没有,随便你用什么。
自测三问(点开对答案) 1. 三个核心 API 分别做什么? —— **取设备、传媒体、传数据。** 2. DataChannel 分片的关键数字是多少? —— **单包上限约 1200 字节**,超过就分片,丢一片整条失败。 3. 哪台服务器成本最高? —— **TURN**,因为它是媒体中继,流量真的从它身上过。

相关笔记