# WebRTC 是什么 · 一个标准，一套协议，一份实现

> WebRTC 有两副面孔——W3C 定义的浏览器 API，和 IETF 定义的一整套实时通信协议。而把它们工业级地实现出来的，是 Google 的 libwebrtc（C++）。这一章讲清这三者的关系、WebRTC 解决什么问题，以及它的协议栈全貌。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-10-01
- 原文：https://daiw.org/manual/webrtc/what-is-webrtc
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# WebRTC 是什么 · 一个标准，一套协议，一份实现

在读一行源码之前，先站高一点看清楚：**WebRTC 到底是什么？** 答案有点出人意料——它不是一个东西，而是**三个层面**的合体：一个 **API 标准**、一套**网络协议**、以及一份**参考实现**。这个教程读的，正是那份实现。

## 两副面孔：标准与协议

「WebRTC」这个词，同时指两样东西：

- **一个 W3C 标准**：定义了浏览器里的 JavaScript API——`RTCPeerConnection`、`getUserMedia`、`RTCDataChannel` 等。这是 Web 开发者直接打交道的那一层，由 [W3C 的 webrtc-pc 规范](https://w3c.github.io/webrtc-pc/)定义。
- **一套 IETF 协议**：定义了两个端点之间**真正怎么通信**——怎么穿越 NAT（ICE / STUN / TURN）、怎么加密（DTLS / SRTP）、怎么传媒体（RTP / RTCP）、怎么传数据（SCTP）。这些是一堆 RFC，由 IETF 的 rtcweb / avtcore 等工作组定义。

浏览器里那个简洁的 `pc.createOffer()`，底下牵动的是这**一整套协议栈**。而把这套协议栈**从头到尾实现出来**的，就是我们要读的库。

## 第三副面孔：libwebrtc，那份实现

<Callout type="info">
  **本教程的主角，是 Google 开源的 C++ 库 libwebrtc——WebRTC 事实上的参考实现。** Chrome 用它、Edge 用它、大量原生 App（移动端、桌面端）也直接集成它；各种 SFU / 媒体服务器也常借用它的部件。它是**BSD 许可的开源项目**，托管在 `webrtc.googlesource.com`。

  这个库**同时实现了两副面孔**：上层暴露一套 C++ API（`api/` 目录，[几乎逐一对应](https://daiw.org/manual/webrtc/source-map) W3C 的 JavaScript API），下层实现了全部 IETF 协议。项目自己的架构文档 `g3doc/index.md` 里就写道：面向用户的 `PeerConnectionInterface`「closely modeled after the Javascript API documented in the WebRTC specification」（严格仿照 WebRTC 规范里的 JavaScript API）。所以你在浏览器里写的 `new RTCPeerConnection()`，在这套 C++ 源码里，对应的就是 `webrtc::PeerConnectionInterface`——本教程[第 1 部分](https://daiw.org/manual/webrtc/source-map)的主角。
</Callout>

## WebRTC 解决什么问题

一句话：**让两个端点之间，实时、低延迟、点对点地传输音视频与数据。** 每个词都有分量：

- **实时 / 低延迟**：目标是**几十到一两百毫秒**的端到端延迟——能支撑双向对话。这是它和 HLS / DASH 这类**流媒体**的根本区别：后者为了流畅牺牲延迟，动辄好几秒到几十秒，适合单向直播 / 点播，撑不起「你一句我一句」的通话。
- **点对点（P2P）**：媒体尽量**直连**两个端点，不绕服务器，省带宽、降延迟。当直连不通（对称 NAT、防火墙）时，才退回用 TURN 中继。
- **对抗真实网络**：互联网是**尽力而为**的——会丢包、会抖动、带宽会变。WebRTC 必须实时**估计带宽、平滑发包、前向纠错、重传、隐藏丢包、缓冲抖动**，才能在烂网络里维持通话。这些「对抗」正是它格外硬核、也值得细读的部分。
- **默认加密**：WebRTC **强制加密**——没有不加密的选项。媒体走 SRTP，数据走 DTLS/SCTP，密钥经 DTLS 握手协商。安全不是可选项，是地基。

## 协议栈全貌

把这些协议叠起来，就是 WebRTC 的协议栈。理解这张图，你就有了整个教程的骨架：

```mermaid
flowchart TD
    APP["应用 / API 层<br/>RTCPeerConnection · 轨道 · 数据通道"]
    subgraph MEDIA["媒体与数据"]
        RTP["RTP / RTCP<br/>音视频实时传输 + 反馈"]
        SCTP["SCTP<br/>数据通道(可靠/有序可调)"]
    end
    SRTP["SRTP / DTLS-SRTP<br/>媒体加密"]
    DTLS["DTLS<br/>握手协商密钥"]
    ICE["ICE / STUN / TURN<br/>穿越 NAT,建立连通性"]
    UDP["UDP(优先) / TCP(兜底)"]
    APP --> MEDIA
    RTP --> SRTP
    SCTP --> DTLS
    SRTP --> DTLS
    DTLS --> ICE
    ICE --> UDP
```

自底向上读一遍：

| 层 | 协议 | 干什么 | 本教程 |
| --- | --- | --- | --- |
| 传输 | UDP（优先）/ TCP | 承载一切，UDP 因低延迟被首选 | 贯穿 |
| 连通性 | **ICE / STUN / TURN** | 在两个可能藏在 NAT 后的端点间**找到一条能通的路** | [第 2 部分](https://daiw.org/manual/webrtc/source-map) |
| 安全握手 | **DTLS** | 在这条路上握手，**协商出密钥** | 第 3 部分 |
| 媒体加密 | **SRTP** | 用协商的密钥**加密每个媒体包** | 第 3 部分 |
| 媒体传输 | **RTP / RTCP** | 传音视频包 + 传反馈（丢包 / 带宽 / 时间戳） | 第 4 部分 |
| 数据传输 | **SCTP**(over DTLS) | 传任意数据，可靠性 / 有序性可调 | 第 8 部分 |

WebRTC 的每一次通话，都是**自底向上把这个栈搭起来**的过程：先用 ICE 打通路、再用 DTLS 握手拿密钥、然后 SRTP 加密的 RTP 媒体才能开跑。[下一站的「一次通话的一生」](https://daiw.org/manual/webrtc/call-lifecycle)会把这个搭建过程完整走一遍。

## 小结与下一章

「WebRTC」是**三位一体**：W3C 的**浏览器 API 标准**、IETF 的**一套实时通信协议**（ICE/STUN/TURN、DTLS、SRTP、RTP/RTCP、SCTP）、以及把二者工业级实现出来的 Google **libwebrtc（C++）**——本教程的主角。它解决的是「**实时、低延迟、点对点、默认加密**」地传输音视频与数据，这让它和高延迟的流媒体划清了界限。它的协议栈**自底向上**：UDP → ICE → DTLS → SRTP/RTP → 媒体。

明白了 WebRTC 是什么，下一步是把这套 5000+ 文件的源码**摊开看清结构**：哪个目录管什么、它们怎么分层依赖。👉 [源码地图](https://daiw.org/manual/webrtc/source-map)。

## 参考资料

- [1] W3C.「WebRTC 1.0: Real-Time Communication Between Browsers.」https://w3c.github.io/webrtc-pc/
- [2] libwebrtc 源码.`g3doc/index.md`（项目自带架构文档，`api/` 与 W3C API 的对应关系）。
- [3] IETF RFC 8825「Overview: Real-Time Protocols for Browser-Based Applications」—— WebRTC 协议栈总览。
