WebRTC:浏览器为什么不用安装软件就能视频通话

TL;DR

WebRTC 把摄像头、麦克风、网络穿透、加密传输和实时自适应组合进浏览器。本文从信令、SDP 与 ICE 讲起,拆解 STUN、TURN、DTLS-SRTP、数据通道和 SFU,并说明实时通信真正难在哪里。

WebRTC 把摄像头、麦克风、网络穿透、加密传输和实时自适应组合进浏览器。本文从信令、SDP 与 ICE 讲起,拆解 STUN、TURN、DTLS-SRTP、数据通道和 SFU,并说明实时通信真正难在哪里。

WebRTC:浏览器为什么不用安装软件就能视频通话

你在浏览器里点开一个视频会议链接,不用安装插件,也不用先把视频上传到某个平台,摄像头和麦克风就能开始工作。WebRTC 就是这件事背后的浏览器能力集合:它提供建立实时音频、视频和数据交换的 API,并把底层连接所需的协议交给浏览器处理。W3C WebRTC 规范

WebRTC 标志

不过,“WebRTC 让两台设备直接连接”只是一个好记的开场白,不是完整架构。真实系统还需要信令服务器帮双方交换连接信息,需要 STUN 帮客户端发现自己的公网映射,必要时还要靠 TURN 中继媒体。理解这几层,才能知道为什么一个看似简单的“加入会议”按钮,背后会有这么多状态。

WebRTC 不是一个协议,而是一组协作部件

可以把一次通话拆成四个问题:

  1. 谁想和谁通话? 这是信令问题,通常由业务服务器通过 WebSocket、HTTP 或其他方式完成。
  2. 双方各自有什么能力? 摄像头、麦克风、编码器、分辨率和数据通道都要协商。
  3. 网络上哪条路径能走通? 这由 ICE 负责尝试候选地址。
  4. 建立后如何加密和传输? 媒体通常走 SRTP,数据通道使用经过 DTLS 保护的传输机制。

信令不属于 WebRTC 规范的核心 API。浏览器不会替你决定“把 Offer 发给谁”,它只生成和消费连接描述。业务系统可以把信令放在自己的服务器上,这也是为什么 WebRTC 仍然需要一个后端,即使音视频最终可能不经过这个后端。

从点下按钮到听见声音,中间发生了什么

第一步:浏览器申请媒体权限

getUserMedia 会触发浏览器的权限模型。用户允许后,页面得到本地音视频轨道;拒绝、设备不存在、设备被其他程序占用,都可能在连接建立前失败。

第二步:创建连接并生成 Offer

页面创建 RTCPeerConnection,把本地音视频轨道加入连接,再调用 createOffer。生成的 SDP 可以理解为一份“我能提供什么、我希望收到什么、我支持哪些编码和传输参数”的描述。

const pc = new RTCPeerConnection({ iceServers })
const stream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true,
})

for (const track of stream.getTracks()) {
  pc.addTrack(track, stream)
}

const offer = await pc.createOffer()
await pc.setLocalDescription(offer)
signalServer.send({ type: "offer", sdp: pc.localDescription })

第三步:对方返回 Answer

对端收到 Offer 后设置为远端描述,再生成 Answer。双方通过信令交换这些描述,浏览器才知道协商的起点。这个过程不是传输媒体本身,而是在为传输建立共同语言。

第四步:ICE 试路

一台设备通常有多个地址:本机局域网地址、路由器映射出来的公网地址,以及 TURN 服务器提供的中继地址。ICE 会收集这些候选地址并进行连通性检查,优先尝试更直接的路径,失败后再回退。

STUN 和 TURN 分别在解决什么

STUN 服务器像一个“公网回声器”:客户端向它发请求,服务器告诉客户端“从公网看,你的地址和端口是这个”。客户端可以把这个候选地址交给对方,尝试通过 NAT 映射建立连接。

TURN 则更像中转站。如果双方的网络策略不允许直接打通,或者某些 NAT 映射无法被对端使用,媒体可以先发到 TURN,再由 TURN 转发给另一端。TURN 能提高成功率,但会增加服务器带宽和延迟成本,所以生产系统通常把它作为必要的回退路径,而不是默认让所有媒体都经过中继。

媒体通道和数据通道不是一回事

音视频强调持续播放和延迟控制,常见策略是丢掉太晚的帧,避免“为了完整而播放过时画面”。数据通道则可以选择可靠有序,或在某些实时状态场景中接受丢包。WebRTC 的数据通道适合聊天、协同控制、游戏状态和文件传输,但不同场景应该选择不同的可靠性与顺序策略。

媒体质量也不是“协商完就固定”。浏览器会根据丢包、往返时间和可用带宽调整码率、分辨率和帧率。多路视频还可能使用 simulcast 或 SVC,让服务器或接收端选择更合适的层。工程上真正要观察的是 getStats() 中的丢包、抖动、RTT、编码时间和解码时间,而不是只看“连接成功”。

WebRTC 的边界

  • 它不替你解决房间、用户身份、录制、转码和消息存储。
  • 点对点不保证一定直连,TURN 中继是很多企业网络里的必要条件。
  • 浏览器权限、自动播放策略和设备切换会影响用户体验。
  • 多人会议如果让所有客户端互相连接,连接数会迅速增长,通常需要 SFU 或 MCU 之类的媒体服务器架构。
  • 端到端加密、录制和服务端转码之间存在真实的系统取舍,不能只用一个“安全”标签概括。

一句话带走

WebRTC 的魔法不是“浏览器突然学会了视频通话”,而是把权限、能力协商、NAT 穿透、加密和实时传输组合成了一套可编程能力。直连是理想路径,信令和 TURN 才是让这条理想路径在真实互联网里活下来的基础设施。

延伸阅读

KEEP READING