音视频与 WebRTC 详解
一套从真实源码出发的 WebRTC 深度教程。我们不讲玩具示例,而是打开 Google 的 libwebrtc(C++)最新 main 分支,一篇一个专题,把 PeerConnection、ICE、DTLS/SRTP、RTP/RTCP、拥塞控制、视频与音频管线、数据通道,直到 rtc_base 基础设施,一层层拆到源码级。预计 100~200 篇。
序 · 一套从源码出发的 WebRTC 教程
一通视频通话看起来理所当然:点开、接通、看见对方。可这背后,是软件工程里最复杂的实时系统之一——采集、编码、封装、加密、穿越 NAT、对抗丢包与抖动、估计带宽、解码、渲染,几十个子系统在几十毫秒的预算里协同工作。而把这一切开源、工业级地实现出来的,正是 Google 的 libwebrtc——浏览器和无数原生应用共用的那套 C++ 库。
这个专栏,就是要打开这套源码,一层一层读进去。
这不是一份「WebRTC 入门」,而是一次「源码级纵深」。 我们基于 libwebrtc 的最新 main 分支源码,一篇一个专题,把每个子系统拆到真实的类、真实的文件、真实的数据流。全程遵循一个原则:凡有结论,必有源码为证——我们会指名道姓地给出文件路径(如 pc/peer_connection.cc)、类名(如 SdpOfferAnswerHandler)、关键函数,让你能对着真实代码逐行验证。
规模:WebRTC 太大了,一两篇讲不清任何一个子系统。这个教程预计 100~200 篇,分为若干「部分」,每篇聚焦一个专题——一个类、一个协议环节、一个算法。它会很长,但每一篇都能独立读。
读者与前置
- 面向谁:有 C++ 基础、想真正搞懂 WebRTC 内部如何运转的工程师——做音视频、做实时通信、做浏览器 / 客户端,或纯粹好奇「这套东西到底怎么实现」的人。
- 需要什么:能读 C++(不必精通模板元编程);了解基本的网络概念(IP、UDP、TCP)。协议细节(ICE、DTLS、RTP……)我们会从零讲起,不预设你懂。
- 不需要什么:你不必能编译 WebRTC(它的构建很重)。我们把源码摊开给你看,对照阅读即可;想动手编译的,第一部分会给出路径。
这套源码有多大
先给个体量感,好让你知道我们要征服的是什么。libwebrtc 有 5000+ 个 C++ 源文件,几个最重的子系统:
| 子系统 | 大致文件数 | 是什么 |
|---|---|---|
modules/audio_processing/ | ~520 | 音频处理(回声消除 AEC3、降噪、增益) |
modules/audio_coding/ | ~325 | 音频编解码与 NetEq |
modules/rtp_rtcp/ | ~310 | RTP / RTCP 实时传输核心 |
modules/video_coding/ | ~240 | 视频抖动缓冲、FEC、打包 |
net/dcsctp/ | ~240 | 数据通道的 SCTP 实现 |
modules/desktop_capture/ | ~230 | 屏幕 / 窗口采集 |
p2p/ | ~130 | ICE 连接建立 |
modules/congestion_controller/ | ~100 | 拥塞控制与带宽估计 |
光是「回声消除」一个模块就有五百多个文件——这就是为什么它值得 100 篇以上。
全景路线图
我们会按这条路线,从「一次通话怎么建立」一路深入到每个子系统的算法内核:
- 第 0 部分 · 导论与全景(本部分) —— WebRTC 是什么、源码地图、一次通话的一生、三大线程模型、代理模式与线程安全、怎么读这套源码。
- 第 1 部分 · PeerConnection 与会话建立 ——
PeerConnectionFactory、PeerConnection这个「上帝对象」、SDP 与 JSEP、SdpOfferAnswerHandler协商状态机、RtpTransceiver/RtpSender/RtpReceiver、DataChannelController、统计收集。 - 第 2 部分 · ICE 与连接建立(
p2p/) —— 候选采集、P2PTransportChannel、PortAllocator、STUN 与 TURN、连通性检查、提名、ICE 重启、网络监测。 - 第 3 部分 · 安全:DTLS 与 SRTP —— DTLS 握手、
DtlsSrtpTransport、SRTP 密钥导出与加解密、证书与指纹、BoringSSL 集成。 - 第 4 部分 · RTP / RTCP —— 包结构与头扩展、
RtpSenderEgress、发送与接收侧、RTCP 反馈、NACK / RTX、FEC(ULPFEC / FlexFEC)、Transport-CC。 - 第 5 部分 · 拥塞控制与带宽估计 —— GCC(
goog_cc)、延迟based 估计(trendline)、丢包based 估计、探测、PacedSender平滑发包、目标码率。 - 第 6 部分 · 视频管线 ——
VideoStreamEncoder、接收侧VideoReceiveStream2、抖动缓冲与帧组装、编解码器抽象(VP8/VP9/AV1/H264/H265)、SVC 与联播、质量 / 帧率自适应、码率分配。 - 第 7 部分 · 音频管线 ——
AudioSendStream/AudioReceiveStream、ACM、NetEq(自适应抖动缓冲)、APM(音频处理:AEC3 回声消除、AGC 增益、NS 降噪、VAD)。 - 第 8 部分 · 数据通道与 SCTP ——
SctpDataChannel、从零实现的 dcSCTP、握手、可靠 / 有序传输、部分可靠、流控与拥塞控制。 - 第 9 部分 · Call 与媒体引擎 ——
Call中枢、RtpTransportControllerSend、BitrateAllocator、媒体引擎(WebRtcVoiceEngine/WebRtcVideoEngine)。 - 第 10 部分 · 基础设施(
rtc_base/) ——Thread与TaskQueue、同步原语、时间与时钟、缓冲区、引用计数、速率统计。 - 第 11 部分 · 观测与调试 ——
RtcEventLog、RTCStatsReport、事件日志可视化、field trials 实验框架、指标直方图。 - 第 12 部分 · 平台集成 —— Android(JNI)与 iOS / macOS(ObjC)SDK、音视频设备模块、桌面采集。
约定
- 源码版本:基于 libwebrtc
main分支的一份新近快照。WebRTC 演进很快,个别类名 / 路径可能随版本微调,但架构与核心算法长期稳定——这正是我们着力的地方。 - 路径写法:我们统一用上游 canonical 路径(如
modules/rtp_rtcp/source/rtp_sender.cc)。一个小技巧:每个头文件的 include guard 就编码了它的完整路径——MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_对应的正是那个路径。怎么读这套源码一章会细说。 - 代码引用:文中的代码片段来自真实源码,可能为聚焦主线而省略次要分支、错误处理、日志(用
...标注),但不虚构——关键逻辑忠于原文。
准备好了吗?我们从最根本的问题开始:WebRTC 到底是什么,这套 C++ 库在整个生态里处于什么位置。 👉 WebRTC 是什么。