WebRTC技术解析

WebRTC技术解析

一个无需插件、开箱即用的 P2P 音视频传输方案

什么是 WebRTC

WebRTC(Web Real-Time Communication)是 Google 开源的一项实时通信技术,直接内置于浏览器,无需安装任何插件或第三方软件,就能实现浏览器之间的音视频通话、数据传输和屏幕共享。

核心指标 :端到端延迟可控制在 200ms 以内 ,相比传统基于服务器的轮询方案延迟降低 90% ,且服务器带宽成本可减少 70% 以上(因为媒体流不经过服务器中转)。

解决了什么问题

传统网页实现视频通话需要:

  • 浏览器插件(Flash、Silverlight)→ 用户需手动安装,已淘汰

  • RTMP + Flash 流媒体服务器 → 延迟高、维护复杂

  • Socket.io + 服务端转发 → 服务器压力大,无法承载大规模并发

WebRTC 的核心突破:

  1. NAT 穿透 :通过 ICE(交互式连接建立)协议自动尝试 STUN/TURN 服务器,成功率可达 95% 以上

  2. 端到端加密:基于 DTLS 和 SRTP,媒体流传输过程全程加密

  3. 自适应码率:根据网络状况动态调整视频分辨率、帧率和码率,弱网下仍能保持通话

  4. 直接 P2P 传输 :媒体流不经过服务器,降低服务端带宽消耗 80% 以上

最简单的使用流程

WebRTC 连接建立需要信令服务器 (可用 Socket.io 实现)来交换连接信息,但实际媒体流是 P2P 的。

1. 获取本地媒体流

javascript 复制代码
// 获取摄像头和麦克风
const localStream = await navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
});
// 将流绑定到 video 元素
document.getElementById('localVideo').srcObject = localStream;

2. 创建 RTCPeerConnection 并添加流

javascript 复制代码
// 配置 STUN 服务器(用于 NAT 穿透)
const configuration = {
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
};
const peerConnection = new RTCPeerConnection(configuration);
// 将本地流的所有 track 添加到连接中
localStream.getTracks().forEach(track => {
  peerConnection.addTrack(track, localStream);
});
// 监听远程流并播放
peerConnection.ontrack = (event) => {
  document.getElementById('remoteVideo').srcObject = event.streams[0];
};

3. 创建 Offer 并交换 SDP

发起方(Caller)

javascript 复制代码
// 创建 offer(包含本地媒体能力描述)
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// 通过信令服务器发送 offer 给对端
signalingSocket.emit('offer', { offer });

接收方(Callee)

javascript 复制代码
// 收到 offer 后设置远程描述,并创建 answer
await peerConnection.setRemoteDescription(offer);
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
// 发送 answer 回对端
signalingSocket.emit('answer', { answer });

发起方收到 answer

javascript 复制代码
await peerConnection.setRemoteDescription(answer);
// 此时连接建立完成,ontrack 会触发

4. ICE 候选交换

连接过程中,浏览器会自动收集 ICE 候选(即可能的网络路径),双方需互相交换:

javascript

javascript 复制代码
// 监听本地 ICE 候选
peerConnection.onicecandidate = (event) => {
  if (event.candidate) {
    signalingSocket.emit('ice-candidate', { candidate: event.candidate });
  }
};
// 收到对端候选时添加
signalingSocket.on('ice-candidate', async ({ candidate }) => {
  await peerConnection.addIceCandidate(candidate);
});

完整的最小 Demo(配合 Socket.io 信令)

服务端(server.js)

javascript 复制代码
const io = require('socket.io')(3000);
io.on('connection', (socket) => {
  socket.on('offer', (data) => socket.broadcast.emit('offer', data));
  socket.on('answer', (data) => socket.broadcast.emit('answer', data));
  socket.on('ice-candidate', (data) => socket.broadcast.emit('ice-candidate', data));
});

客户端核心代码(省略 HTML 元素绑定)

javascript 复制代码
// 统一封装信令处理
const socket = io('http://localhost:3000');
let pc = null;
async function startCall(isInitiator) {
 const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
 document.getElementById('localVideo').srcObject = stream;

const config = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
 pc = new RTCPeerConnection(config);

stream.getTracks().forEach(t => pc.addTrack(t, stream));
 pc.ontrack = e => document.getElementById('remoteVideo').srcObject = e.streams[0];
 pc.onicecandidate = e => e.candidate && socket.emit('ice-candidate', e.candidate);

if (isInitiator) {
 const offer = await pc.createOffer();
 await pc.setLocalDescription(offer);
 socket.emit('offer', { offer });
 }

socket.on('offer', async ({ offer }) => {
 await pc.setRemoteDescription(offer);
 const answer = await pc.createAnswer();
 await pc.setLocalDescription(answer);
 socket.emit('answer', { answer });
 });

socket.on('answer', async ({ answer }) => {
 await pc.setRemoteDescription(answer);
 });

socket.on('ice-candidate', async ({ candidate }) => {
 await pc.addIceCandidate(candidate);
 });
}
// 页面加载后决定是否作为发起方(例如通过 URL 参数)
startCall(window.location.search.includes('initiator=true'));
相关推荐
换个昵称都难12 天前
webrtc peerconnection_server 模块介绍
运维·服务器·webrtc
EasyGBS12 天前
延迟直降90%!国标GB28181视频平台EasyGBS支持WebRTC WHIP推流设备接入,让万物互联更简单
音视频·webrtc
换个昵称都难13 天前
webrtc RtpRtcp模块化测试-MockRtpRtcp
webrtc
如意IT13 天前
指纹浏览器检测之BrowserScan的webrtc指纹检测和反检测
自动化·webrtc·chromium·浏览器开发
换个昵称都难13 天前
webrtc TURN 主要源码介绍
webrtc
换个昵称都难13 天前
webrtc RTC_P2P源码解析
asp.net·webrtc·p2p
换个昵称都难13 天前
webrtc StunServer源码介绍
webrtc
数据知道14 天前
指纹浏览器:DNS 泄漏防范与 WebRTC 本地 IP 屏蔽的底层实现
爬虫·网络协议·tcp/ip·安全·webrtc·数据采集·指纹浏览器
换个昵称都难15 天前
webrtc源码解析概要介绍
webrtc
换个昵称都难15 天前
WebRTC 完整调用流程(前端纯 JS 实现,最简可运行)
webrtc