WebRTC是浏览器原生支持的点对点音视频通信技术,核心由Mediastream、RTCPeerConnection和RTCDataChannel三部分组成,需信令服务与STUN/TURN服务器协同实现连接。

WebRTC 是浏览器原生支持的实时音视频通信技术,不用装插件、不依赖中间服务器转发媒体流,两个浏览器之间能直接“面对面”传视频和音频。构建视频聊天应用的核心,就是用它建立点对点连接、交换媒体流、处理网络变化。
WebRTC 的三个关键组件
它不是单个 API,而是由三部分协同工作:
- MediaStream(获取音视频):用
navigator.mediaDevices.getUserMedia()拿到本地摄像头和麦克风流,显示在页面上靠<video></video>标签。 - RTCPeerConnection(建立连接):真正传输音视频的管道。它自动处理编解码、带宽适配、NAT 穿透(通过 STUN/TURN 服务器),你只需配置、创建 Offer/Answer、交换信令。
- RTCDataChannel(传任意数据):可选,适合发送文字消息、文件片段或控制指令,走的是同一条 p2p 连接,低延迟。
必须准备的基础设施:信令 + STUN/TURN
WebRTC 自己不负责“怎么找到对方”,这得靠你实现的信令服务(比如 websocket 或 http)。双方要交换三类信息:
- session Description(SDP):描述自己支持什么编码、分辨率、端口等,即 Offer 和 Answer;
- ICE Candidate:网络地址候选(如本机 IP、公网 IP、中继地址),用于连通性检测;
- 用户身份标识(比如房间号或用户 ID):让服务端知道谁该和谁配对。
STUN 服务器帮你发现公网地址(90% 场景够用);遇到严格防火墙或对称 NAT,就得加 TURN 服务器中转媒体流——推荐用免费的 Twilio STUN/TURN 或自建 Coturn。
立即学习“Java免费学习笔记(深入)”;
最小可行视频聊天流程(两人间)
假设 A 主动发起,B 加入同一房间:
- A 调用
getUserMedia获取本地流 → 添加到RTCPeerConnection→ 调用createOffer→setLocalDescription→ 发 Offer 给 B; - B 收到 Offer →
setRemoteDescription→ 调用createAnswer→setLocalDescription→ 发 Answer 给 A; - A 收到 Answer →
setRemoteDescription; - 双方监听
icecandidate事件,把每个 Candidate 通过信令发给对方; - 监听
addstream(旧版)或track(新版)事件,把对方的远程流绑定到自己的<video></video>元素上。
实际开发中容易踩的坑
新手常卡在这几个地方:
- https 必须开启:
getUserMedia在非 HTTPS(或 localhost 以外的 http)下会被浏览器禁用; - 忽略 ICE 状态:连接失败时多看看
iceConnectionState是 “failed” 还是 “disconnected”,配合日志查 Candidate 是否正常交换; - 没处理
track动态添加:新版 chrome/firefox 不再触发addstream,要用pc.ontrack = e => { video.srcObject = e.streams[0]; }; - 忘记关闭资源:离开页面前调用
pc.close()、stream.getTracks().foreach(t => t.stop()),否则摄像头灯常亮。
基本上就这些。不复杂但容易忽略细节。跑通两人直连后,再扩展多人(用 SFU 架构)、录制、美颜、屏幕共享,都是顺延出来的能力。