我在WebRTC上花费了六年时间,现在深入讲解它

我花了将近六年时间在WebRTC之上构建东西,我仍然认为它是最被低估的网络基础设施之一。每当你进行Google Meet通话、在Discord中共享屏幕或从浏览器参加远程医疗预约时——WebRTC都在承担繁重的工作。但大多数我交谈过的开发者都把它当作黑盒子对待。他们抓起一个库,连接一些事件处理程序,然后祈祷一切顺利。

这种方法在它不工作的时候就失效了。而当它失效时——当通话在公司防火墙后断开、视频质量在移动设备上下降、当你无法弄清楚为什么有两秒延迟时——你真的需要理解底层发生的事情。所以让我们来深入探讨这个问题。

目录

How WebRTC Works in 2026: A Developer's Deep Dive

WebRTC到底是什么?

WebRTC(Web实时通信)是一套开源协议、API和标准,允许浏览器和移动应用程序实时交换音频、视频和任意数据。Google最初在2011年发布了该项目,W3C在2021年将其标准化,到2026年它已嵌入到基本上每个现代浏览器——Chrome、Firefox、Safari、Edge及其移动版本。

WebRTC背后的关键见解是点对点通信。不是将你的视频通话路由通过中央服务器(这会增加延迟并花费金钱),WebRTC尝试在两个设备之间建立直接连接。你的笔记本电脑直接与同事的笔记本电脑通话。服务器的角色是最小的——它只是帮助两个对等方找到彼此。

当然,"尝试"在这句话中做了很多工作。NAT、防火墙和公司网络的现实意味着直接连接并不总是可能的。WebRTC有一个完整的子系统专门用于解决这个问题,我们稍后会讨论。

但首先,构建块。

三个核心API

WebRTC公开了三个主要的JavaScript API。在编写任何代码之前,理解每个API的作用至关重要。

getUserMedia(MediaDevices API)

这是访问摄像头和麦克风的方式。它返回包含音频和/或视频轨道的MediaStream对象。

const stream = await navigator.mediaDevices.getUserMedia({
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 },
    frameRate: { ideal: 30 }
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true
  }
});

注意那些音频约束。WebRTC在浏览器级别处理回声消除和噪声抑制——对于基本用例,你不需要自带音频处理管道。在2026年,浏览器原生噪声抑制已经变得非常好,尽管许多应用仍在上面附加AI动力的模型以获得更好的结果。

你也可以使用getDisplayMedia()进行屏幕共享,它遵循相同的模式,但提示用户选择屏幕、窗口或标签。

RTCPeerConnection

这是主力。RTCPeerConnection代表你的本地设备和远程对等方之间的连接。它处理:

  • 编解码器协商(两边都能理解的格式)
  • ICE候选收集(找出网络路径)
  • DTLS握手(加密)
  • SRTP媒体传输(实际音频/视频数据)
  • 带宽估计和自适应
const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    {
      urls: 'turn:your-turn-server.com:443',
      username: 'user',
      credential: 'pass'
    }
  ]
});

// 向连接添加本地轨道
stream.getTracks().forEach(track => pc.addTrack(track, stream));

// 处理来自远程对等方的传入轨道
pc.ontrack = (event) => {
  remoteVideo.srcObject = event.streams[0];
};

单个RTCPeerConnection可以同时传输多个音频和视频轨道。你不需要为音频和视频分别创建连接。

RTCDataChannel

这个经常被忽视,但它非常有用。RTCDataChannel允许你在对等方之间发送任意数据——文本消息、文件块、游戏状态、传感器数据,任何你需要的东西。

const dataChannel = pc.createDataChannel('chat', {
  ordered: true,
  maxRetransmits: 3
});

dataChannel.onopen = () => {
  dataChannel.send(JSON.stringify({ type: 'message', text: 'Hello!' }));
};

dataChannel.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

数据通道在DTLS上使用SCTP(流控制传输协议),你可以将其配置为有序或无序、可靠或不可靠。对于聊天功能,你需要有序和可靠。对于实时游戏状态,你可能需要无序和不可靠,以优先考虑新鲜度而不是完整性。

信令:WebRTC不处理的部分

这是当大多数开发者第一次遇到WebRTC时困惑的地方:规范故意没有定义对等方如何找到彼此。 WebRTC处理两个对等方相互了解后的一切,但初始发现——称为信令——完全由你决定。

信令涉及交换两种类型的信息:

  1. 会话描述(SDP):这些描述了每个对等方支持的媒体格式、编解码器和能力。
  2. ICE候选:这些是连接可能使用的潜在网络路径。

交换遵循一个offer/answer模型:

// 对等方A创建一个offer
const offer = await pcA.createOffer();
await pcA.setLocalDescription(offer);
// 通过你的信令服务器将offer发送给对等方B

// 对等方B接收offer并创建一个answer
await pcB.setRemoteDescription(offer);
const answer = await pcB.createAnswer();
await pcB.setLocalDescription(answer);
// 将answer发送回对等方A

// 对等方A接收answer
await pcA.setRemoteDescription(answer);

你可以使用WebSockets、服务器发送事件、HTTP轮询、Firebase实时数据库——字面上任何可以在两个客户端之间传递消息的方式来实现你的信令服务器。我见过从Socket.io到普通REST API轮询的各种生产系统。

SDP格式本身是……好吧,说实话,它很丑陋。这是一个看起来像这样的几十年前的文本格式:

v=0
o=- 4611731400430051336 2 IN IP4 127.0.0.1
s=-
t=0 0
m=audio 49170 RTP/SAVPF 111 103 104
a=rtpmap:111 opus/48000/2

你很少需要手动解析SDP,但理解它携带编解码器偏好、加密参数和ICE凭证有助于调试连接问题时极其重要。

How WebRTC Works in 2026: A Developer's Deep Dive - architecture

连接舞蹈:ICE、STUN和TURN

这是WebRTC真正聪明的地方——同时也是真正复杂的地方。问题:互联网上大多数设备都位于NAT(网络地址转换)后面。你的笔记本电脑没有公网IP地址。你的手机也没有。那么两个位于不同NAT后面的设备如何直接相互通话?

WebRTC使用一个称为ICE(交互式连接建立)的框架来解决这个问题。

STUN:发现你的公网地址

STUN(NAT会话穿越实用程序)服务器很轻量级。你的浏览器向它发送一个请求,STUN服务器用你的公网IP地址和端口来响应——从外部看你的地址。把它想象成当你在建筑内部时问街上的某人"我的地址是什么?"。

STUN服务器便宜得运行,Google提供免费的(如stun.l.google.com:19302)。他们不中继任何媒体——他们只告诉你你的公网地址是什么。

TURN:中继后备方案

有时直接点对点连接根本不可能。对称NAT、公司防火墙和某些移动运营商配置会阻止直接连接。当发生这种情况时,你需要一个TURN(使用NAT周围中继的穿越)服务器。

TURN服务器实际上在对等方之间中继所有媒体流量。这意味着:

  • 更高的延迟(流量通过中继而不是直接)
  • 更高的带宽成本(你要为所有那些视频流量付费)
  • 但当没有其他办法时它可以工作

在生产环境中,大约10-20%的连接需要TURN中继,具体取决于你的用户群。企业用户在公司防火墙后面经常遇到这个数字——有时40-60%。如果你想在生产环境中获得可靠的WebRTC,你必须运行TURN服务器。 我不能太强调这一点。我见过初创公司在没有TURN的情况下推出,然后想知道为什么他们四分之一的用户无法连接。

ICE候选收集过程

当你创建一个RTCPeerConnection时,ICE开始收集候选——潜在的网络路由。它收集三种类型:

候选类型 延迟 成本
Host 本地网络接口 最低(仅LAN) 免费
服务器自反(srflx) 通过STUN发现 最小(STUN很便宜)
中继 在TURN服务器上分配 更高 显著(带宽成本)

ICE然后按优先顺序测试这些候选,首先尝试最快的选项。如果主机候选有效(两个对等方在同一LAN上),很好。如果不是,它尝试STUN发现的地址。如果那些失败,它回退到TURN中继。

这一切都自动发生,但你可以观看:

pc.onicecandidate = (event) => {
  if (event.candidate) {
    console.log('New ICE candidate:', event.candidate.type);
    // 通过信令将此候选发送给远程对等方
  }
};

pc.oniceconnectionstatechange = () => {
  console.log('ICE state:', pc.iceConnectionState);
  // 状态:new -> checking -> connected -> completed
  // 或:new -> checking -> failed(哎呀)
};

媒体如何实际流动

一旦ICE建立了一条路径,媒体就通过RTP(实时传输协议)流动,特别是SRTP(安全RTP),因为WebRTC强制加密。

这是简化的流程:

  1. 摄像头捕获一帧
  2. 编码器使用协商的编解码器压缩它(VP8、VP9、H.264或AV1)
  3. 压缩的帧被分成RTP数据包
  4. 每个数据包使用SRTP加密
  5. 数据包通过UDP(通常)发送到远程对等方
  6. 远程对等方解密、重组和解码帧
  7. 帧在<video>元素中呈现

这对视频每秒发生30次。对于音频(通常是Opus编解码器),每秒接近50个数据包。

WebRTC使用UDP而不是TCP进行媒体传输。TCP通过重传丢失的数据包来保证交付,这听起来不错,直到你意识到从500ms前重传的视频帧不仅无用——它会主动损害,因为它延迟了更新的帧。UDP让WebRTC优先考虑及时性而不是完整性,这正是你想要的实时媒体。

RTCP:反馈循环

除了RTP,WebRTC使用RTCP(RTP控制协议)在对等方之间交换统计信息。每一方报告:

  • 数据包丢失率
  • 抖动(数据包到达时间的方差)
  • 往返时间
  • 可用带宽估计

这个反馈驱动自适应比特率系统,我们接下来会讨论。

编解码器和2026年自适应比特率

WebRTC支持多个编解码器,过去几年的形势发生了有意义的变化。

视频编解码器

编解码器 浏览器支持(2026) 压缩效率 CPU使用 备注
VP8 通用 基准 遗留,但仍是强制实现的编解码器
VP9 通用 ~比VP8好30% 中等 大多数用例的良好平衡
H.264 通用 类似VP8 低(硬件加速) 历史上对Safari互操作性的要求
AV1 Chrome、Firefox、Safari 18+ ~比VP9好30% 高(改进中) 未来,但移动设备上CPU成本仍然重要

AV1采用在2026年加速了。较新设备中的硬件编码支持(Apple M4、最近的高通骁龙芯片)解决了最大的抱怨——CPU使用。对于新项目,我会默认为VP9,当两个对等方都支持时将AV1作为首选选项。

音频编解码器

Opus是王者。它一直是WebRTC的强制音频编解码器,有充分的理由——它处理从窄带语音到全带宽音乐的一切,适应变化的网络条件,并具有出色的错误隐藏。你很少需要考虑音频编解码器。

自适应比特率

这是WebRTC最好的功能之一,它自动发生。发送方通过RTCP反馈持续监控网络条件,并实时调整编码比特率。

当带宽下降时(比如你拿着手机进入电梯),WebRTC将:

  1. 降低视频分辨率
  2. 降低帧速率
  3. 增加压缩(降低质量)

当条件改善时,它向上扩展。Google的拥塞控制算法(GCC)处理这个问题,到2026年它已经被改进,可以在几秒内对网络变化做出反应。你不需要自己实现任何这些——它内置在浏览器的WebRTC栈中。

安全模型:默认加密

WebRTC被设计为强制加密。没有办法禁用它。每个WebRTC连接都使用:

  • DTLS(数据报传输层安全):处理密钥交换。把它想象成UDP的TLS。
  • SRTP(安全实时传输协议):使用从DTLS握手派生的密钥加密实际媒体数据包。

对于数据通道,加密是DTLS over SCTP。

这意味着即使有人截获了数据包(比如你的ISP或同一Wi-Fi网络上的某人),他们也无法解码音频或视频内容。加密是对等方之间的端到端加密——有一个重要的警告。

如果你使用TURN中继服务器,TURN服务器可以看到加密的数据包但无法解密它们。加密在对等方处终止,而不是在中继处。但是,如果你对群组通话使用SFU(选择性转发单元)——大多数生产系统都这样做——SFU传统上需要解密和重新加密媒体。这是可插入流(现在在2026年所有主要浏览器中都可用)变得重要的地方,允许通过SFU进行端到端加密,让你添加一个SFU无法剥离的额外加密层。

WebRTC vs. WebTransport vs. 传统VoIP

我经常被问到这个问题,所以让我们把它说清楚。

功能 WebRTC WebTransport 传统VoIP(SIP)
传输 UDP(主要) QUIC(HTTP/3) UDP/TCP
点对点 否(客户端-服务器) 是(理论上)
浏览器原生 否(需要软电话/插件)
媒体处理 内置 自己动手 内置
加密 强制(DTLS/SRTP) 强制(TLS 1.3) 可选(SRTP如果配置)
数据通道 是(SCTP) 是(QUIC流)
NAT穿越 ICE/STUN/TURN 不需要(基于服务器) STUN/TURN或SBC
延迟 小于一秒 小于一秒 小于一秒
最适合 P2P通话、会议 单向流、游戏 企业电话

WebTransport建立在QUIC/HTTP/3之上,在2026年已经在特定用例中获得了吸引力——特别是单向直播流,你不需要完整的点对点机制。它不是替换WebRTC;它是补充性的。如果你正在构建双向视频通话,WebRTC仍然是正确的选择。如果你正在构建一个广播平台,其中一个源流向数千人,WebTransport(或建立在它之上的Media over QUIC)值得评估。基于SIP的传统VoIP也不会消失,特别是在现有PBX基础设施的企业中。许多2026年的生产系统运行WebRTC到SIP网关,将基于浏览器的客户端与传统电话系统连接。

2026年的变化

2026年的WebRTC与2023年的WebRTC没有根本上的不同,但几个发展很重要:

AI集成已成为主流

实时AI功能现在直接在WebRTC流上运行:

  • 超越浏览器提供的本机背景噪声抑制(Krisp等工具或Google Meet中的内置模型)
  • 通话期间的实时转录和翻译
  • 参与WebRTC通话的AI语音代理,作为对等方,处理客户服务或会议摘要
  • 音频流上的情感分析,用于呼叫中心应用

WebRTC提供的低延迟传输正是这些AI模型所需要的。你无法在有两秒延迟的流上运行实时转录。

AV1硬件编码是真实的

我在编解码器部分提到过这一点,但值得重复。在较新芯片上的AV1硬件编码器支持使其对实时使用变得实际。你获得VP9级CPU使用量,压缩性能提高30%。对于带宽受限的场景(移动、发展中市场),这是一个大问题。

WebCodecs API成熟度

WebCodecs API让你访问浏览器的内置编码器/解码器,而不需要通过完整的WebRTC栈。当你需要低级控制时这很有用——自定义视频处理管道、在流传输时编码以供录制,或将帧馈送到ML模型中。它与WebRTC的可插入流配对良好,用于自定义处理。

改进的浏览器奇偶性

Safari在历史上一直是WebRTC的问题儿童。在2026年,Safari 18+已经缩小了大多数差距——simulcast正常工作、可插入流得到支持、AV1解码可用。你仍然需要跨浏览器测试,但编写Safari特定解决方案的日子基本上已经过去了。

使用WebRTC构建:实际考虑

如果你正在构建一个使用WebRTC的产品,这是我会考虑的:

不要自己构建SFU(可能)

对于1:1通话,直接点对点很好。对于3-4个以上参与者的群组通话,你需要一个选择性转发单元。从头开始构建一个是一项严肃的事业。考虑开源选项如mediasoupJanusPion(基于Go),或托管服务如TwilioDaily.coLiveKitAgora

预算TURN服务器

使用coturn(开源)或托管TURN服务。在端口443/TCP上运行TURN作为后备——某些企业防火墙阻止除HTTP/HTTPS端口外的所有内容。为适度部署预算$200-500/月;视频中继带宽加起来很快。

在真实网络上测试

WebRTC在localhost上效果很好。它在拥塞的Wi-Fi、移动网络和公司代理后面以有趣的方式分解。Chrome的chrome://webrtc-internals是调试的最佳助手——它显示ICE候选收集、编解码器协商、带宽估计和数据包丢失的实时情况。

考虑你的前端架构

如果你正在构建包含WebRTC功能的网络应用,前端框架很重要。我们已经在Next.js应用程序中构建了实时协作功能,其中WebRTC数据通道为实时光标和共享状态提供动力。对于包含偶尔实时功能的内容丰富的网站,Astro的岛屿架构允许你仅在需要时加载WebRTC代码,保持初始包精简。

如果你需要一个与无头CMS集成的自定义WebRTC解决方案——比如,对于远程医疗平台或直播商务网站——那是从一开始就得到架构正确可以节省数个月痛苦的项目。如果你想讨论你的具体设置,欢迎联系我们

常见问题

WebRTC完全不需要服务器可以工作吗? 基本不行。你总是需要一个信令服务器来帮助对等方交换连接信息(SDP offer/answer和ICE候选)。你还至少需要一个STUN服务器进行NAT穿越,现实中需要一个TURN服务器以获得可靠性。但实际媒体可以在不触及你的服务器的情况下点对点流动。

为什么WebRTC连接有时在企业防火墙后失败? 企业防火墙经常阻止UDP流量并限制出站连接仅限于端口80和443。由于WebRTC主要在动态端口上使用UDP,这可能会阻止直接连接,甚至阻止STUN。解决方案是在端口443上用TCP运行TURN服务器,它看起来像防火墙的常规HTTPS流量。这就是TURN基础设施对企业部署不可协商的原因。

WebRTC如何处理差质量或波动的网络条件? WebRTC使用自适应比特率编码。它通过RTCP反馈持续监控数据包丢失、抖动和可用带宽,并实时调整编码质量。在坏连接上,你会看到更低的分辨率和帧速率,而不是冻结的视频。Google的拥塞控制算法(GCC)自动管理这个——你不需要自己实现它。

WebRTC可以扩展到数百或数千个观众吗? 不能用纯点对点——每个参与者都需要与其他每个参与者的直接连接。对于大型群组(超过~4个人),你需要一个选择性转发单元(SFU),它接收每个参与者的流并将其转发给其他人。对于向数千人广播,你会将WebRTC摄入与CDN配对或使用处理扇出的基于WebRTC的流平台。

WebRTC被加密了吗?我的ISP可以看到我的视频通话吗? 是的,所有WebRTC媒体都使用DTLS进行密钥交换和SRTP进行媒体传输来加密。这种加密是强制的——你字面上无法禁用它。你的ISP可以看到你正在进行WebRTC连接以及有多少数据在流动,但他们无法解码实际的音频或视频内容。

WebRTC和WebSockets对实时功能的区别是什么? WebSocket是基于TCP的,设计用于可靠、有序的消息传递——非常适合聊天、通知和信令。WebRTC对媒体传输使用UDP,优先考虑低延迟而不是保证传递,并支持点对点连接。对你的信令服务器和基于文本的实时功能使用WebSocket;当你需要音频、视频或低延迟数据通道时使用WebRTC。

2026年的流媒体项目应该使用WebRTC还是WebTransport? 这取决于通信的方向。对于双向交互式流(视频通话、远程医疗、具有观众交互的直播商务),WebRTC是明确的选择。对于一对多广播流,其中亚秒级延迟很重要但互动性有限,WebTransport(和新兴的Media over QUIC标准)值得评估。许多平台同时使用两者——WebRTC用于摄入和互动,WebTransport或HLS/DASH用于大规模分发。

我需要什么硬件/带宽来进行WebRTC视频通话? 对于720p视频通话,预期每个参与者大约1.5-2 Mbps的上传和下载。1080p推升至2.5-4 Mbps。最近5年的任何现代设备(笔记本电脑、手机、平板电脑)都有足够的CPU来运行WebRTC。瓶颈几乎总是网络质量——特别是上行带宽和网络稳定性——而不是处理能力。