一、什么是 WebRTC?
WebRTC(Web Real-Time Communication) 是一项开放的实时通信技术标准,允许浏览器和移动应用之间进行点对点(P2P)的音视频通话和数据传输,无需安装插件或第三方软件。
核心特征
- 开源免费:W3C 和 IETF 标准化,Google 主导开源实现
- 浏览器原生支持:Chrome、Firefox、Safari、Edge 均已内置
- P2P 通信:数据尽可能直连,低延迟
- 端到端加密:所有音视频和数据通道默认 DTLS/SRTP 加密
二、WebRTC 三大核心 API
1. getUserMedia — 媒体捕获
获取摄像头和麦克风的音视频流。
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1280, height: 720 },
audio: true
});
// 将流绑定到 <video> 元素显示
videoElement.srcObject = stream;
2. RTCPeerConnection — 建立连接
管理两端之间的 P2P 连接,处理编解码协商、NAT 穿透、加密等。
const pc = new RTCPeerConnection(configuration);
// 添加本地媒体流
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// 监听远程媒体流
pc.ontrack = (event) => {
remoteVideo.srcObject = event.streams[0];
};
// 监听 ICE 候选
pc.onicecandidate = (event) => {
if (event.candidate) {
// 通过信令服务器交换 candidate
signalingServer.send({ candidate: event.candidate });
}
};
3. RTCDataChannel — 数据传输
在 P2P 连接上传输任意二进制/文本数据,低延迟、有序可靠。
const dc = pc.createDataChannel("chat", {
ordered: true
});
dc.onopen = () => dc.send("Hello WebRTC!");
dc.onmessage = (e) => console.log("收到:", e.data);
三、WebRTC 通信架构
┌──────────┐ 信令(Signaling) ┌──────────┐
│ Peer A │ ◄──────────────────────► │ Peer B │
│ (浏览器) │ │ (浏览器) │
└────┬─────┘ └────┬─────┘
│ │
│ STUN/TURN 服务器 │
│ ◄──── NAT 穿透 ────► │
│ │
└──────── P2P 直连通道 ───────────────┘
(音视频 + 数据)
关键组件说明
| 组件 | 作用 |
|---|---|
| 信令服务器 | 交换 SDP 描述和 ICE 候选(WebRTC 不规定信令协议,常用 WebSocket) |
| STUN 服务器 | 帮助设备发现自己的公网地址(NAT 映射) |
| TURN 服务器 | 当 P2P 直连失败时,作为中继服务器转发数据 |
| ICE | Interactive Connectivity Establishment,综合使用 STUN/TURN 找到可用路径 |
四、连接建立流程(握手全流程)
Peer A Signaling Server Peer B
│ ──── offer (SDP) ──────────► │ │
│ │ ──── offer ──────────► │
│ │ │
│ │ ◄──── answer (SDP) ───── │
│ ◄──── answer ─────────────── │ │
│ │ │
│ ──── ICE candidate ────────► │ ──── ICE candidate ───► │
│ ◄──── ICE candidate ───────── │ ◄──── ICE candidate ───── │
│ │ │
│ ════════ P2P 连接建立 ════════════════════════════════════════════ │
详细步骤
- 创建 Offer:
pc.createOffer()→pc.setLocalDescription() - 通过信令发送 Offer 到对端
- 对端接收并创建 Answer:
pc.setRemoteDescription(offer)→pc.createAnswer()→pc.setLocalDescription() - 通过信令返回 Answer
- 双方交换 ICE 候选(ICE Trickling)
- ICE 连通性检查:尝试所有候选路径,选择最优
- DTLS 握手:建立加密通道
- SRTP/SCTP 传输:音视频和数据开始流动
五、NAT 穿透与 ICE 机制
NAT 类型与穿透策略
| NAT 类型 | 穿透难度 | 方案 |
|---|---|---|
| 完全锥形(Full Cone) | 容易 | STUN 即可 |
| 限制锥形(Restricted Cone) | 中等 | STUN + ICE |
| 端口限制锥形 | 较难 | STUN + ICE |
| 对称型(Symmetric NAT) | 困难 | 需要 TURN 中继 |
ICE 候选类型
- Host Candidate:本机 IP 地址,局域网内有效
- Server Reflexive (srflx):通过 STUN 获取的公网映射地址
- Peer Reflexive (prflx):ICE 检查中发现的地址
- Relay Candidate:TURN 服务器分配的中继地址
ICE 框架按优先级依次尝试,直到找到可用路径。
六、音视频编解码
视频编解码器
| 编解码器 | 特点 |
|---|---|
| VP8 | Google 开源,WebRTC 默认视频编码 |
| VP9/AV1 | 新一代编码,更高压缩率 |
| H.264 | 兼容性最好,硬件支持广泛 |
| H.265/HEVC | 部分浏览器支持,Safari 较好 |
音频编解码器
| 编解码器 | 特点 |
|---|---|
| Opus | WebRTC 默认音频编码,6~510kbps 自适应 |
| G.711/PCM | 兼容性好,带宽占用高 |
| G.722 | 宽带语音 |
关键技术
- 自适应比特率(ABR):根据网络状况动态调整码率
- SVC(可伸缩视频编码):多层编码,适应不同接收端
- Simulcast:同时发送多路不同分辨率流
- 带宽估计:基于 REMB/TWCC 反馈
七、WebRTC 安全机制
| 层面 | 技术 |
|---|---|
| 信令层 | HTTPS / WSS(非 WebRTC 规定,但实践中必须) |
| 传输加密 | DTLS(Datagram TLS)用于数据通道 |
| 媒体加密 | SRTP(Secure RTP)用于音视频流 |
| 身份验证 | DTLS-SRTP 密钥协商 |
| 浏览器安全 | HTTPS 环境才能访问摄像头/麦克风 |
🔒 WebRTC 所有媒体和数据传输默认加密,不存在明文传输选项。
八、典型应用场景
1. 视频会议系统
- Google Meet、Zoom Web、腾讯会议 Web 版
- 多方通话:SFU(选择性转发单元)架构
2. 直播 / 互动直播
- 超低延迟直播(<500ms)
- 观众连麦互动
3. 在线教育
- 1对1 网课、小班课
- 屏幕共享 + 电子白板(DataChannel 同步状态)
4. 远程协作
- 远程桌面控制
- 协同编辑(DataChannel 传输操作指令)
5. IoT / 安防监控
- 摄像头实时画面
- 设备间低延迟数据同步
6. 云游戏
- 游戏画面实时串流
- 操作指令低延迟回传
九、多方通信架构
Mesh(网状)
A ◄──► B
│ │
▼ ▼
C ◄──► D
- 每个参与者与其他所有人直连
- ✅ 简单,无服务器成本
- ❌ 带宽 O(n²),人数受限(通常 ≤4 人)
SFU(选择性转发单元)
A ──┐
B ──┼──► SFU ──► 分发给所有人
C ──┘
- 每人只上传一路流,SFU 转发给其他人
- ✅ 带宽 O(n),可扩展到几十人
- ❌ 需要服务器资源
- 代表:Janus、mediasoup、Jitsi、LiveKit
MCU(多点控制单元)
A ──┐
B ──┼──► MCU ── 合并为一路 ──► 分发
C ──┘
- 服务器混合所有流为一路
- ✅ 客户端带宽低
- ❌ 服务器计算开销大,延迟较高
十、主流开源方案
| 项目 | 类型 | 特点 |
|---|---|---|
| mediasoup | SFU | Node.js 控制面 + C++ 媒体引擎,高性能 |
| Janus | SFU/Gateway | C 语言,插件化架构,功能丰富 |
| Jitsi | SFU | Java,完整解决方案(Meet + Videobridge) |
| LiveKit | SFU | Go 语言,云原生,SDK 丰富 |
| Pion | Library | Go 语言 WebRTC 实现,灵活可嵌入 |
| aiortc | Library | Python WebRTC 实现,适合 AI/IoT 场景 |
| Kurento | MCU/MCU | Java/JS API,支持媒体处理(滤镜、识别等) |
十一、性能优化实践
网络层
- 合理配置 ICE Server(多 STUN/TURN 冗余)
- 启用 TWCC(Transport-wide Congestion Control)进行带宽估计
- 根据网络 RTT、丢包率动态调整码率
媒体层
- 使用 Simulcast 适应多端不同网络
- 配合适当的 VP8/VP9 编码参数
- 开启 Jitter Buffer 减少抖动影响
前端层
- 合理管理
MediaStream生命周期,避免内存泄漏 - 通话中动态切换摄像头/麦克风时正确替换 Track
- 使用
getStats()监控实时通话质量
// 监控通话质量示例
setInterval(async () => {
const stats = await pc.getStats();
stats.forEach(report => {
if (report.type === 'inbound-rtp') {
console.log(`丢包率: ${report.packetsLost / (report.packetsReceived + report.packetsLost) * 100}%`);
console.log(`抖动: ${report.jitter}ms`);
}
});
}, 5000);
十二、常见问题与排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 连接失败 | NAT/防火墙 | 检查 TURN 服务器配置,确保 iceTransportPolicy: 'relay' 可连通 |
| 黑屏/无声 | getUserMedia 权限未获取 | 确认 HTTPS 环境,检查浏览器权限设置 |
| 延迟高 | 网络差 / 服务器远 | 优化 TURN 部署位置,降低编码码率 |
| 回声 | 音频回路 | 启用回声消除 echoCancellation: true |
| 回声/啸叫 | 双端同时开扬声器 | AEC(自动回声消除)+ AGC(自动增益控制) |
| ICE 失败 | 对称 NAT / UDP 被封 | 部署 TURN over TCP / TLS |
调试工具
chrome://webrtc-internals/— Chrome WebRTC 内部状态about:webrtc— Firefox WebRTC 日志pc.getStats()— 运行时统计数据
十三、WebRTC 未来趋势
- AV1 编解码普及:更高压缩率,同等质量下节省 30%+ 带宽
- 端到端加密(E2EE):Insertable Streams API 实现真正的端到端加密
- WebTransport + WebCodecs:更底层的传输和编码控制,补充 WebRTC 灵活性
- AI 增强:超分辨率、降噪、虚拟背景、实时翻译
- ** Scalable Video Coding (SVC)**:更广泛的多层编码支持
- WebRTC over QUIC:基于 QUIC 协议传输,提升可靠性
总结
WebRTC 是现代实时通信的基石技术:
- 🌐 浏览器原生,无需安装插件
- 🔒 默认端到端加密,安全性高
- ⚡ P2P 直连,延迟极低
- 🔧 完善的生态,开源方案丰富
- 📈 持续演进,AV1/SVC/E2EE 等新特性不断加入
无论是视频会议、在线教育、互动直播还是 IoT 场景,WebRTC 都是当前最成熟的实时通信技术方案。