WebRTC
WebRTC (Web Real-Time Communication) — набор стандартов и API для P2P передачи медиа (аудио/видео) и произвольных данных в браузере без плагинов. Основа Google Meet, Discord, Zoom Web Client, Facebook Messenger, WhatsApp Web, всех «звонков в браузере». Разрабатывается W3C и IETF, стабильно с 2017.
Три главных API
- getUserMedia — доступ к микрофону и камере. Возвращает
MediaStream. - RTCPeerConnection — управление соединением с пиром, ICE, DTLS, SRTP, кодирование медиа.
- RTCDataChannel — произвольные данные (SCTP over DTLS over UDP).
Компоненты стека
┌────────────────────────────────────┐
│ Медиа (VP8/VP9/AV1/H.264/H.265, │
│ Opus, PCMU, PCMA) │
├────────────────────────────────────┤
│ SRTP / SRTCP │ ← шифрованное RTP
├────────────────────────────────────┤
│ DTLS-SRTP │ ← handshake для медиа-ключей
├────────────────────────────────────┤
│ SCTP (для DataChannel) │
├────────────────────────────────────┤
│ DTLS │
├────────────────────────────────────┤
│ ICE / STUN / TURN │ ← ICE, STUN, TURN
├────────────────────────────────────┤
│ UDP (или TCP как fallback) │
└────────────────────────────────────┘
Signaling
WebRTC не задаёт способ обмена начальными параметрами (offer/answer + ICE-кандидаты). Signaling делаешь сам — обычно через WebSocket или SSE к своему серверу.
Классический offer/answer:
- Alice создаёт
RTCPeerConnection, добавляет свойMediaStream. - Alice:
createOffer()→ SDP. Через сигналинг шлёт Bob. - Bob:
setRemoteDescription(offer), добавляет свой поток,createAnswer()→ SDP. Шлёт Alice. - Alice:
setRemoteDescription(answer). - Оба собирают ICE-кандидаты и обмениваются ими через сигналинг (trickle).
- ICE находит рабочий путь → DTLS-handshake → медиа течёт.
Простой пример
const pc = new RTCPeerConnection({
iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
});
// Медиа
const stream = await navigator.mediaDevices.getUserMedia({video:true, audio:true});
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// Приём удалённого
pc.ontrack = (ev) => {
document.getElementById('remote').srcObject = ev.streams[0];
};
// ICE-кандидаты
pc.onicecandidate = (ev) => {
if (ev.candidate) signaling.send({candidate: ev.candidate});
};
// Offer/answer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({sdp: offer});
Data Channels
const dc = pc.createDataChannel('game', {ordered: false, maxRetransmits: 0});
dc.onopen = () => dc.send('hi');
dc.onmessage = (ev) => console.log(ev.data);
dc.binaryType = 'arraybuffer';
Параметры:
ordered: false+maxRetransmits: 0— UDP-like, для игр.ordered: true+ без maxRetransmits — TCP-like, для файлов.
Топологии
| Топология | Использование | Cost |
|---|---|---|
| Peer-to-Peer | 1:1 звонок | Нагрузка на клиента, минимум сервера |
| Mesh | Маленькие групповые (3-5 человек). Каждый шлёт всем | N² upload у каждого клиента |
| SFU (Selective Forwarding Unit) | 10-50 участников. Сервер получает потоки и раздаёт | Умеренная серверная нагрузка |
| MCU (Multipoint Control Unit) | Сотни участников, транскодинг | Дорого — CPU-heavy |
Media SFU
Популярные SFU:
- Janus (Meetecho, C) — модульный, много плагинов.
- Jitsi Videobridge (Java) — за ним Jitsi Meet.
- mediasoup (Node.js + C++) — для скейла, используется в Discord.
- Livekit (Go) — cloud-first, коммерческий.
- ion-sfu (Pion, Go) — простой, самый лёгкий.
Кодеки
| Тип | Кодеки |
|---|---|
| Аудио | Opus (default), G.711 (PCMU/PCMA), G.722, iSAC (deprecated) |
| Видео | VP8, VP9, H.264, AV1 (с 2021), H.265 (в Safari 12.1+) |
Opus — де-факто стандарт для VoIP. 8-510 kbps, адаптивный, латентность 5-60 мс.
Простыми словами про SRTP
Медиа шифруется SRTP (Secure RTP). Ключи для SRTP извлекаются из DTLS-handshake — механизм называется DTLS-SRTP. Отпечаток сертификата DTLS передаётся в SDP через a=fingerprint:sha-256 ... — стороны проверяют что подключились именно к тем.
Приватность
- IP leak. STUN/ICE раскрывает локальные IP (даже за VPN). Настройки браузера ограничивают.
- Fingerprinting. Аудио/видео-устройства имеют характеристики (canvas-fingerprinting аналогично).
- WebRTC over VPN. Форсировать TURN-only (
iceTransportPolicy: 'relay') чтобы весь трафик через сервер.
Не-браузерные реализации
- libwebrtc — Google, эталонная. Используется в Chrome, Electron.
- Pion — pure Go. Легко эмбедится в сервера.
- aiortc — Python (async).
- webrtc-rs — Rust.
- OpenWebRTC — deprecated.
WebRTC-NV (Next Version)
Активная разработка новых API поверх WebRTC-транспортов:
- WebCodecs — прямой доступ к кодекам, минуя PeerConnection.
- WebTransport — WebTransport как чистый транспорт.
- Insertable Streams — вклиниваться в кодированный поток (E2EE).