WebRTC без эзотерики

Автор: Николай СапуновОбновлено: август 202624 мин чтения
Содержание статьи +

TL;DR

WebRTC, или Web Real-Time Communication, – это открытый стандарт, позволяющий браузеру или мобильному приложению передавать аудио, видео и произвольные данные другому браузеру или приложению с задержкой, достаточной для живого разговора без перебивок. На WebRTC построены Google Meet, голосовые каналы Discord, видеозвонки WhatsApp, звонки в Facebook Messenger, практически все современные сервисы телемедицины, а также всё больше платформ для live-торговли и онлайн-обучения. За простым JavaScript-интерфейсом – одним объектом RTCPeerConnection – скрывается стек из девяти IETF RFC, рекомендаций W3C и медиа-слоя, который проходит через NAT, шифрует каждый пакет и адаптируется к доступной полосе пропускания. В этой статье объясняется, что такое WebRTC, зачем нужен каждый элемент его стека, почему минимальная задержка составляет 100–300 мс (в отличие от 5–30 секунд у HLS) и что должна учитывать продуктовая команда перед запуском WebRTC на больших масштабах.

Почему это важно

Если вы разрабатываете продукт, в котором два или более человека одновременно видят и слышат друг друга в реальном времени – видеовстречи, консультации врачей, live-аукционы с голосовыми комментариями зрителей, фитнес-занятия с тренером, контролирующим технику выполнения – WebRTC почти наверняка станет правильным выбором транспортного протокола. Вам обязательно нужно достаточно хорошо понимать его, чтобы оценить риски, заложить в бюджет и обсудить с инженерами.

Технология была утверждена в качестве рекомендации W3C в январе 2021 года, а в том же месяце IETF опубликовала набор из девяти протоколов (RFC 8825–8835). Исходная JavaScript-спецификация была уточнена второй серией RFC в период с 2022 по 2024 год. К 2026 году каждый современный браузер будет поставляться с поддержкой WebRTC по умолчанию, а серверная open-source-экосистема – mediasoup, Janus, LiveKit, Jitsi Videobridge, Pion – станет настолько зрелой, что компетентная команда сможет запустить конференц-продукт за недели, а не за годы.

Подвох в том, что простая картина «два браузера общаются напрямую» перестаёт работать, как только участников становится больше трёх или используется публичная сеть. Цена непонимания того, что WebRTC умеет, а чего – нет, выражается в постоянных ребуферах у зрителей, сорванных медицинских консультациях и необходимости переписывать код.

Цель этой статьи – сделать картину правильной, не делая её пугающей.

Что такое WebRTC на самом деле

Самое краткое и точное определение: WebRTC – это набор стандартов, превращающих браузер в медиа-эндпоинт, способный передавать и принимать аудио, видео и данные в реальном времени через публичный интернет с встроенным шифрованием, обходом NAT и адаптацией к пропускной способности. Эти стандарты распределены между двумя организациями: W3C отвечает за JavaScript API, с которым работает фронтенд-разработчик, а IETF – за сетевые протоколы, по которым передаются данные после выхода из браузера. Основной документ W3C – WebRTC: Real-Time Communication in Browsers – формально стал рекомендацией 26 января 2021 года и был обновлён в марте 2023 года с учётом внесённых изменений, уже внедрённых в продакшен (W3C, WebRTC: Real-Time Communication in Browsers, 2023). Документы IETF представлены девятью RFC, опубликованными единым пакетом в январе 2021 года, а затем дополненными протоколом JSEP в виде RFC 9429, вышедшего в апреле 2023 года и сделавшего устаревшим RFC 8829 (IETF, RFC 9429, JavaScript Session Establishment Protocol, 2023).

Практический пересказ, прежде чем мы погрузимся в стек: WebRTC – это набор технологий, необходимых для того, чтобы вызов getUserMedia() на веб-странице создал объект MediaStream, передал этот поток объекту RTCPeerConnection, а противоположная сторона соединения – другой браузер, мобильное приложение или сервер – получила кадры в течение нескольких сотен миллисекунд и отобразила их так, будто две точки соединены прямым кабелем. Всё, что стандартизирует WebRTC, существует для того, чтобы этот пересказ оставался верным при наличии NAT, файрволов, потерь пакетов, джиттера, асимметричной полосы пропускания и при условии, что байты никогда не должны передаваться в открытом виде.

Рисунок 1. Стек WebRTC одним взглядом. JavaScript API и объект RTCPeerConnection – наверху; протоколы IETF переносят байты, как только они покидают браузер.

Откуда взялся WebRTC за один абзац

WebRTC появился в Google в 2010 году в результате приобретения двух компаний: On2 Technologies, предоставившей видеокодек VP8, и Global IP Solutions, передавшей аудиодвижок и надёжный real-time-стек, ранее использовавшийся в десктопных приложениях для звонков. В мае 2011 года Google открыла исходный код и предложила технологию как интернет-стандарт. IETF создала рабочую группу rtcweb, а W3C – WebRTC Working Group; обе организации десятилетиями координировали работу, и стандарты были окончательно утверждены одновременно в январе 2021 года (IETF Blog, WebRTC Standardized, 26 января 2021). Десять лет разработки имеют большое значение, поскольку объясняют архитектуру: WebRTC с самого начала создавался для открытого веба – поэтому безопасность встроена по умолчанию, а не является опциональной, все браузеры реализуют его единообразно, и ни один вендор не контролирует технологию. Это единственный браузерный стандарт для real-time-передачи медиа, который успешно пережил переход к среде без плагинов, уничтожив Flash, Silverlight и Java-апплеты.

Пять вещей, которые делает WebRTC

Если очистить WebRTC от выполняемой работы, остаётся пять задач. Остальная часть статьи подробно рассматривает каждую из них; в этом разделе они лишь перечислены, чтобы у читателя была общая картина.

Первая задача – захват медиа: получить аудио и видео с микрофона и камеры и преобразовать их в JavaScript-объект, с которым можно работать на странице. Для этого в браузере используется API navigator.mediaDevices.getUserMedia(), описанное в дочерней спецификации W3C Media Capture and Streams (W3C, Media Capture and Streams, рекомендация с апреля 2025 года). На выходе получается объект MediaStream, содержащий один или несколько объектов MediaStreamTrack, каждый из которых представляет собой отдельную аудио- или видеодорожку.

Вторая задача – согласование сессии: эндпоинты должны договориться о кодеках, частотах дискретизации аудио, разрешениях видео, необходимости передачи видео помимо аудио и способе сопоставления сетевых адресов. Договорённость фиксируется в виде двух документов протокола описания сессии (Session Description Protocol) – offer и answer – правила формирования и использования которых описаны в JavaScript Session Establishment Protocol, RFC 9429 (IETF, RFC 9429, JSEP, апрель 2023). SDP генерирует браузер автоматически; приложение никогда не создаёт его вручную. Задача приложения – передавать SDP-объекты от одного участника к другому. Эта передача называется сигналингом, и WebRTC намеренно не стандартизирует её.

Третья задача – обход NAT и сетевых границ: найти путь через все NAT, файрволы и корпоративные прокси между конечными точками. Стандарт – Interactive Connectivity Establishment (RFC 8445), а также помощники STUN (RFC 8489) и TURN (RFC 8656). ICE собирает все возможные адреса, по которым конечная точка может быть доступна – локальный IP, публичный IP, обнаруженный через STUN-сервер, и relayed-IP через TURN-сервер, – а затем параллельно проверяет все комбинации адресов двух сторон, пока не найдёт рабочую пару (IETF, RFC 8445, Interactive Connectivity Establishment, июль 2018).

Четвёртая задача – шифрование. WebRTC требует, чтобы каждый байт передаваемых данных был зашифрован: режима передачи в открытом виде не предусмотрено. Для согласования симметричных ключей используется протокол Handshake на основе Datagram Transport Layer Security (DTLS), описанного в RFC 9147 – UDP-совместимой версии TLS. Далее медиаданные передаются по протоколу Secure Real-Time Transport Protocol (SRTP), RFC 3711, с ключами, обменёнными через расширение DTLS-ключей для SRTP, определённое в RFC 5764. Отпечатки сертификатов, подтверждающие принадлежность DTLS-сертификатов конкретным конечным точкам, передаются внутри SDP, что позволяет использовать канал сигнализации в качестве основы доверия для медиа-канала (IETF, RFC 5764, DTLS Extension to Establish Keys for SRTP, май 2010).

Пятая задача – сам медиа-транспорт: как только зашифрованный UDP-канал установлен, аудио- и видеоданные передаются по протоколу Real-Time Transport Protocol (RFC 3550), а получатель информирует отправителя о состоянии сети с помощью RTP Control Protocol (RFC 3550, раздел 6). Цикл RTP/RTCP обеспечивает адаптацию полосы пропускания, восстановление потерянных пакетов и буферизацию джиттера в WebRTC. Что касается data-каналов – если они используются – они работают на основе Stream Control Transmission Protocol (RFC 4960), инкапсулированного в DTLS. Это сознательный выбор, позволяющий приложению получать надёжные упорядоченные потоки байтов без эффекта head-of-line blocking, который привёл бы к задержкам при использовании TCP.

Это всё, что делает WebRTC, – объяснено простым языком, где это возможно. Остальная часть статьи подробно разбирает каждую задачу.

JavaScript-поверхность, с которой работает разработчик

Центральный объект спецификации W3C – RTCPeerConnection. Рабочий пример занимает всего несколько строк и стоит того, чтобы его прочитать, даже если вы не используете JavaScript, поскольку он наглядно демонстрирует, насколько тонкий API доступен разработчику по сравнению с находящимся под ним протоколным стеком:

// 1. Получить локальный микрофон и камеру.
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });

// 2. Создать peer connection со STUN-сервером для обнаружения NAT.
const pc = new RTCPeerConnection({
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});

// 3. Прицепить каждую локальную дорожку к peer connection.
stream.getTracks().forEach(track => pc.addTrack(track, stream));

// 4. Когда приходит удалённая дорожка — отрисовать её.
pc.ontrack = (event) => {
  document.getElementById("remoteVideo").srcObject = event.streams[0];
};

// 5. Создать SDP-offer и отправить его через сигналинг-канал приложения.
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
mySignallingChannel.send({ type: "offer", sdp: offer.sdp });

Читатель, не знакомый с API WebRTC, часто спрашивает: где вызов шифрования, где вызов адаптации полосы пропускания, где вызов обхода NAT? Честный ответ: ни одного из этих вызовов как отдельного API не существует – они скрыты внутри конструктора RTCPeerConnection и процесса согласования, запускающегося при вызовах setLocalDescription и setRemoteDescription. Приложению остаётся лишь две задачи: захватить медиапоток и передать SDP-офер и SDP-ансер между пирами. Всё остальное – работа браузера (Mozilla MDN, RTCPeerConnection, 2026). Это было сделано осознанно, и именно поэтому стандартизация WebRTC заняла десять лет.

Танец SDP offer/answer

Согласование между двумя пирами всегда происходит по одной и той же схеме: инициатор (offerer) формирует описание того, что он готов отправлять и принимать, а ответчик (answerer) отвечает своим описанием – тем, с чем он согласен. Затем обе стороны применяют оба описания к своей локальной state-машине. Правила описаны в RFC 9429 (JSEP). Документы представляют собой блобы протокола описания сессии (Session Description Protocol), изначально определённого для телефонии в RFC 8866 (IETF, RFC 8866, Session Description Protocol, январь 2021).

SDP-offer для одного аудио- и видеозвонка занимает около 40 строк. Поля, важные для понимания WebRTC: строки m= объявляют медиа-секцию – по одной на каждую аудио- или видеодорожку, а также одну для data-канала; строки a=rtpmap: перечисляют все кодеки, которые offerer готов принять, в порядке предпочтения; строка a=fingerprint: содержит SHA-256-отпечаток DTLS-сертификата, который offerer предъявит при handshake шифрования; строки a=ice-ufrag и a=ice-pwd содержат учётные данные, которыми ICE будет аутентифицировать пакеты проверки соединения; строки a=candidate: перечисляют все пары IP-адреса и порта, собранные offerer’ом как потенциальные локальные адреса. Answerer читает всё это, выбирает один кодек на каждую медиа-секцию, определяет, какие пары IP-адреса и портов он будет использовать, подписывает свой DTLS-отпечаток в ответе и отправляет SDP обратно.

Арифметика согласования стоит того, чтобы показать её один раз, потому что это источник одного из вечных сюрпризов WebRTC – SDP оказывается большим. Типичный offer с аудио (Opus), видео (VP8, VP9, H.264, AV1), data-каналом и стандартным набором WebRTC header extensions выглядит примерно так:

1 session-level блок            +  6 строк
+ 3 медиа-секции               × 12 строк (m=, c=, a=rtcp, a=ice-ufrag, a=ice-pwd, a=fingerprint, a=setup, a=mid, a=sendrecv, a=rtcp-mux, a=rtpmap × N, a=fmtp × N)
+ 4 кодека на видеосекцию      ×  3 строки (rtpmap, rtcp-fb, fmtp)
+ 12 ICE-кандидатов            × 12 строк (по одной на a=candidate)
= примерно 240 строк, 8–10 КБ текста

Восемь килобайт – это немного для канала в 100 Мбит/с, но это не бесплатно: такая нагрузка ложится на сигнализационный канал ещё до начала звонка. Продакшены, использующие trickle ICE (что стало более распространённым паттерном в 2026 году), отправляют первоначальный SDP объёмом меньше – обычно 4 КБ – и дотрикливают строки candidate позже, по мере их сбора браузером.

Сигналинг: то, что WebRTC не стандартизировал

У WebRTC нет встроенного сигналинг-протокола. Стандарт прямо об этом говорит: авторы JSEP намеренно оставили сигналинг за пределами спецификации, чтобы приложение могло выбрать подходящий транспорт в зависимости от существующей инфраструктуры (RFC 9429, §1.1, апрель 2023). На практике сигналинг-канал почти всегда реализуется как WebSocket-соединение между каждым пиром и небольшим сервером, принадлежащим приложению; этот сервер отвечает за маршрутизацию offer’ов нужному answerer’у, answer’ов – обратно нужному offerer’у, а также за передачу trickled-кандидатов ICE в обоих направлениях. Сигналинг-сервер без дополнительных функций можно написать за несколько сотен строк кода на любом языке программирования.

Неочевидное следствие: каждая команда, разрабатывающая WebRTC-продукт, создаёт свой сигналинг-сервер. Некоторые остаются минимальными и проходят весь жизненный цикл продукта без изменений; другие постепенно наращивают функциональность – управление комнатами, статусом участников, записью, экранной передачей и чатом – и тогда сигналинг-сервер превращается в нервную систему приложения. Open-source-фреймворки вроде LiveKit и mediasoup предоставляют референсные реализации сигналинга; Janus и Jitsi Videobridge используют собственные; закрытые вендоры интегрируют его внутрь SDK. Канонического ответа не существует, потому что нет единой спецификации.

Где здесь Фора Софт

Фора Софт поставляет WebRTC-решения с 2011 года – с момента, когда Google открыла исходный код. За более чем 80 проектов в сфере конференц-связи, телемедицины, e-learning, live-торговли и AR/VR-коллабораций команда разрабатывала сигналинг-серверы с нуля и интегрировала такие медиа-роутеры, как mediasoup, Janus, Jitsi, LiveKit и Pion. Паттерны, повторяющиеся в каждом проекте – выбор топологии SFU, расчёт пропускной способности TURN, проектирование моста WebRTC → HLS для записи, защита сигналинг-сервера от room-bombing’а – те же самые, что рассматриваются в блоке 8 раздела Learn. Эта статья – введение; остальные материалы блока углубляются в каждую из этих тем.

ICE, STUN и TURN: как байты находят друг друга

Самая сложная задача в WebRTC – соединить два устройства через публичный интернет, потому что у большинства из них нет публично маршрутизируемого IP-адреса. Ноутбук в кофейне находится за NAT этой кофейни, тот – за carrier-grade NAT провайдера, а тот, в свою очередь, – за каким-нибудь файрволом провайдера; телефон в сотовой сети – за NAT оператора и, возможно, ещё и за оверлеем приватных IP. Собственная ОС устройства знает только свой приватный адрес – обычно 192.168.x.x или 10.x.x.x – и не имеет ни малейшего представления о том, как выглядит публичный.

Interactive Connectivity Establishment, RFC 8445, решает эту задачу, собирая параллельно все адреса, по которым эндпоинт может быть доступен. Всего три типа адресов. Host-кандидат – это локальный IP-адрес, предоставляемый операционной системой. Server-рефлексивный кандидат – публичный IP-адрес, определённый путём отправки STUN-запроса на публичный STUN-сервер и анализа исходного адреса в ответе с точки зрения сервера: таким образом становится виден публичный адрес, отображённый через NAT (IETF, RFC 8489, Session Traversal Utilities for NAT (STUN), февраль 2020). Релейный кандидат – публичный IP-адрес TURN-сервера, с которым эндпоинт прошёл аутентификацию и попросил пересылать пакеты от своего имени: резервный вариант, когда прямой путь недоступен (IETF, RFC 8656, Traversal Using Relays around NAT (TURN), февраль 2020).

Когда оба пира собрали кандидатов и обменялись ими через сигналинг, ICE формирует все возможные пары (кандидат-A, кандидат-B) и отправляет STUN-пакеты для проверки соединения по каждой из них, пока хотя бы одна пара не пройдёт проверку в обе стороны. Побеждает первая успешная пара. В продакшене чаще всего побеждает пара server-reflexive-to-server-reflexive (оба пира за NAT, который разрешает входящие пакеты после исходящего соединения) или relayed-to-relayed (оба пира за строгим NAT, где единственный рабочий путь – через TURN-сервер посередине). Доля звонков, которым требуется TURN, зависит от сетевой среды: публично-интернетные конференц-платформы фиксируют 8–15% сессий с использованием релейного соединения, а корпоративные платформы со строгими файрволами – 25–40% (Cloudflare, State of WebRTC report, 2025).

Рисунок 2. Три пути, которые рассматривает ICE. STUN сообщает каждому пиру его публичный адрес; TURN ретранслирует медиа, когда прямого соединения нет.

Экономику TURN продуктовые команды часто недооценивают. TURN-сервер – это чистая ретрансляция по полосе пропускания: каждый байт медиаданных проходит через него дважды (входящий от отправителя и исходящий к получателю), и оплата идёт за объём трафика. Один видеозвонок в разрешении 720p со скоростью 1,5 Мбит/с в каждом направлении потребляет 3 Мбит/с на одного участника и 6 Мбит/с на весь звонок; умножьте это на долю сессий, использующих TURN, и на пиковое количество одновременных звонков – и вы получите главную статью расходов публичного конференц-продукта. Калькулятор B5 внизу страницы поможет вам смоделировать свою цифру.

DTLS-SRTP: почему в WebRTC нет режима без шифрования

WebRTC требует шифрования на каждом соединении – всегда. Это закреплено как в спецификации W3C, так и в архитектуре безопасности IETF (RFC 8827): ни один браузер не позволяет отключить эту функцию. Процесс установления соединения работает следующим образом: каждый пир генерирует самоподписанный DTLS-сертификат, вычисляет его отпечаток SHA-256 и включает этот отпечаток в свой SDP. SDP передаётся через сигнальный канал – который должен быть защищён TLS, если приложение должно быть устойчиво к атакам типа «человек посередине» – и принимающая сторона заранее знает, какой отпечаток должен совпадать с сертификатом другой стороны. Когда DTLS-рукопожатие проходит по UDP-каналу, найденному с помощью ICE, каждая сторона проверяет сертификат другой стороны по отпечатку из SDP; при несовпадении соединение немедленно завершается (IETF, RFC 8827, WebRTC Security Architecture, январь 2021).

Когда DTLS генерирует мастер-секрет, ключи для SRTP вычисляются с помощью расширения DTLS-SRTP (RFC 5764). С этого момента каждый RTP-пакет с аудио или видео шифруется с использованием AES (обычно AES-128-GCM в современных развертываниях) и проходит аутентификацию. Сетевой наблюдатель, перехватывающий трафик, видит только SRTP-заголовки и поток зашифрованных данных.

Неочевидное следствие: WebRTC – единственный широко распространённый протокол для передачи медиа в реальном времени, который с момента появления шифруется по умолчанию. В легаси-системах SIP/RTP оператор сам решает, использовать ли шифрование; в WebRTC такой выбор отсутствует. Это делает его рациональным выбором для телемедицины, голосовых сервисов в финансовой сфере и любых продуктов, где регулятор задаёт вопрос: «Кто-нибудь мог увидеть голос пациента в открытом виде на сетевом пути?» – и ответ должен быть однозначным: «Нет».

RTP, RTCP и как WebRTC анализирует сеть

Когда зашифрованный UDP-канал открыт, аудио и видео передаются внутри протокола Real-Time Transport Protocol, описанного в RFC 3550. RTP – это «рабочая лошадка» интернет-голосовой и видеосвязи уже тридцать лет; WebRTC добавляет обратную связь от получателя, замыкающую систему управления. Получатель непрерывно отправляет RTCP receiver reports – с информацией о проценте потерь пакетов, джиттере (разбросе интервалов между прибытием пакетов) и round-trip delay – обратно отправителю. Алгоритм оценки пропускной способности на стороне отправителя анализирует эти данные и соответственно подстраивает битрейт кодека, слой simulcast или слой SVC.

Эталонный алгоритм Google, используемый в Chrome и большинстве клиентов на базе Chromium, – Google Congestion Control (GCC). Он применяет фильтр Калмана для оценки доступной полосы пропускания на основе RTCP-отчётов и динамически снижает битрейт кодека при ухудшении оценки, восстанавливая его при стабилизации сети (Carlucci et al., Congestion Control for Web Real-Time Communication, IEEE/ACM Transactions on Networking, 2017). Более новое расширение transport-cc позволяет получателю передавать временные метки поступления каждого пакета, обеспечивая отправителю более информативный сигнал по сравнению со стандартным RTCP receiver report; transport-cc сегодня является значением по умолчанию во всех крупных реализациях (W3C WebRTC spec, §5.6, 2023).

Та же петля обратной связи используется для восстановления потерянных пакетов. Получатель может запросить NACK (отрицательное подтверждение) на конкретный потерянный пакет, и отправитель повторит его передачу из небольшого буфера истории, если сделает это до того, как джиттер-буфер получателя воспроизведёт этот пакет. В случае слишком поздних потерь получатель может запросить picture-loss indication (PLI) или full-intra-request (FIR), заставляя отправителя отправить ключевой кадр для ресинхронизации декодера. Поддержка forward error correction предусмотрена, но по умолчанию почти не используется – RTT типичной конференции достаточно мал, чтобы повторная передача обычно оказывалась выгоднее по использованию полосы пропускания.

Рабочий бюджет задержки: почему WebRTC попадает в 100–300 мс

Задержка в WebRTC измеряется «от стекла до стекла» – это реальное время с момента, когда фотон попадает на сенсор камеры с одной стороны, до момента, когда соответствующий пиксель появляется на экране с другой. Опубликованная средняя задержка WebRTC в чистой сети составляет около 100 мс; верхняя граница допустимой задержки для естественного разговора – около 300 мс; при задержке выше 500 мс перебивки начинают нарушать естественный обмен репликами. Эти цифры взяты из десятилетий исследований в телефонной связи и применимы к WebRTC без изменений.

Куда уходят эти 100–300 мс? Рабочий бюджет для чистой сети выглядит следующим образом:

ИсточникТипично (мс)Заметки
Захват камеры и задержка кодера20–40Один-два кадра на 30 fps; больше при lookahead кодера
Локальный джиттер и буфер пакетизации10–20Сетевой стек ОС немного буферизует перед отправкой
Передача по сети в одну сторону20–80Континент – 20 мс coast-to-coast, 80 мс трансатлантика
Джиттер-буфер получателя30–80Размер для 95-го перцентиля inter-packet variance
Конвейер декода и рендера10–30Один кадр на 30 fps – это 33 мс
Итого90–250В пределах опубликованной полосы WebRTC 100–300 мс

Сравните с HLS, который буферизует сегменты продолжительностью 4–10 секунд до начала воспроизведения и обеспечивает задержку «от экрана до экрана» 5–30 секунд в стандартной конфигурации; с LL-HLS, достигающим показателя 2–5 секунд; или с Media over QUIC – новинкой 2026 года, ориентированной на задержку 500 мс при масштабировании через CDN. Разрыв в два порядка между WebRTC и HLS – единственная ключевая цифра, которую должна усвоить продуктовая команда: если кейсу требуется задержка менее одной секунды, WebRTC – правильный выбор транспорта; если нет – HTTP-протокол, как правило, дешевле в эксплуатации.

Рисунок 3. Бюджет задержки WebRTC, glass-to-glass. Основные составляющие – джиттер-буфер приёмника и сетевая передача.

Картинка «два браузера» ломается на трёх

WebRTC называют peer-to-peer, потому что API предоставляет один объект RTCPeerConnection, взаимодействующий с одной другой точкой. Проблема в том, что «одна другая точка» – это предел. Если вы хотите включить в звонок трёх человек, каждому участнику придётся поддерживать соединение с каждым из остальных: три участника – три соединения в браузере, четыре – шесть, десять – сорок пять. Пропускная способность растёт так же: каждый участник передаёт своё видео N раз – по одному для каждого другого участника, и это быстро превышает возможности upstream-канала домашнего интернета уже при четырёх-пяти участниках. Такая топология, при которой каждый соединён с каждым, называется mesh, и это стандартное поведение, если вы пишете наивное WebRTC-приложение.

Продакшен-конференцинг решает эту задачу с помощью промежуточного сервера. Существует два паттерна:

Selective Forwarding Unit (SFU) принимает WebRTC-соединение от каждого участника, расшифровывает данные только до уровня RTP-заголовков и пересылает зашифрованную полезную нагрузку всем остальным участникам. SFU не выполняет транскодирование, не смешивает потоки – он лишь маршрутизирует их. Из-за того, что каждый участник отправляет своё видео в SFU только один раз, нагрузка на канал передачи данных от пира падает с O(N) до O(1). mediasoup, Janus, LiveKit, Jitsi Videobridge и Pion – это SFU (LiveKit, SFU vs MCU vs Mesh, 2024).

Multipoint Conferencing Unit (MCU) завершает каждое соединение, декодирует все входящие потоки, объединяет их в единый выходной видеопоток и заново кодирует этот составной поток для каждого участника. Загрузка с одного пира – один поток, выгрузка на один пир – один поток, но нагрузка на CPU сервера очень высока, поскольку он выполняет кодирование видео в реальном времени для каждого участника.

К 2026 году SFU победил во всех категориях, где устройство участников способно обрабатывать несколько входящих видеопотоков (web, mobile, smart TV): меньшая нагрузка на CPU и меньшая задержка при маршрутизации, а не микшировании, перевешивают чуть большую сложность на стороне клиента. MCU остаются востребованными только там, где принимающее устройство не может работать с несколькими потоками (некоторые устаревшие телефонные мосты, некоторые ограниченные embedded-клиенты). Подробное сравнение – в статье 8.4 (SFU vs MCU vs Mesh); сравнение пяти крупных open-source SFU – в статье 8.5.

Частая ловушка: считать WebRTC HTTP-протоколом

Самая частая ошибка команд, впервые внедряющих WebRTC, – рассматривать его как HTTP. Они полагают, что CDN поможет с масштабированием (не поможет – CDN кэширует, а WebRTC-потоки уникальны для каждой сессии); что балансировщик перед сигналинг-сервером решит все проблемы (не решит – медиа-плоскость WebRTC работает по совершенно другому транспорту, и сигналинг-сервер здесь не при чём); что медиа будет работать поверх корпоративного VPN (обычно нет, потому что NAT за VPN не знает о WebRTC). Честная формулировка для product-менеджера: WebRTC – это peer-to-peer-протокол для передачи медиа, использующий HTTP исключительно для сигналинга и только так, как решит приложение. Масштабирование, стоимость и сценарии отказоустойчивости полностью отличаются от всего, что есть в HTTP-мире. Архитектуру нужно проектировать с учётом этого – остальная часть Block 8 проведёт вас через процесс.

Состояние WebRTC в 2026 году

WebRTC стал стабильным стандартом с января 2021 года, но экосистема вокруг него продолжает развиваться. Три изменения особенно важны для любой команды, создающей продукт сегодня.

Первое – улучшилась ситуация с кодеками. AV1 со scalable video coding (AV1 SVC) появился в Chrome 90, Firefox получил аппаратный декодер в 2024 году, а Safari 18 добавил базовую поддержку в конце 2024 года. При достаточной пропускной способности сети AV1 SVC обеспечивает такое же воспринимаемое качество, как VP9, но при примерно на 30% более низком битрейте. Благодаря слоистой структуре SVC серверы SFU могут отбрасывать слои для медленных получателей без перекодирования (Bitmovin, AV1 in WebRTC, 2024). H.264 остаётся универсальным резервным кодеком; Opus – универсальным аудиокодеком.

Второе – WebTransport достиг статус baseline во всех крупных браузерах в марте 2026 года, когда Safari 26.4 добавил его (webrtc.ventures, WebTransport Is Now Baseline, апрель 2026). WebTransport – не замена WebRTC для двустороннего общения, а дополнение для передачи односторонних данных и лежит в основе нескольких экспериментов WHIP-over-WebTransport. О нём будет больше говорить в 2026–2027 годах.

Третье – история интеграции ИИ-агентов созрела. Фреймворк LiveKit Agents стартовал в 2024 году, к 2025 году достиг масштабов продакшена и позволил разработчикам интегрировать модели OpenAI Realtime API, Google Gemini Live или любые аналогичные голосовые модели в WebRTC-комнаты как полноценных участников. К первому кварталу 2026 года LiveKit Agents набрал 700 ежемесячных поисковых запросов как head term в кластере – категории не существовало в 2024 году. Это самый крупный новый кейс и тема статьи 8.10. Если в дорожной карте фигурирует voice-first ИИ-агент любого типа, WebRTC сегодня – предполагаемый транспорт.

Чего в WebRTC нет

Стоит отметить, что WebRTC намеренно не поддерживает некоторые функции, поскольку именно эти пробелы определяют архитектурные решения команды:

Нет сигналинга – его реализуете вы сами. Нет SFU – выбираете: покупаете, запускаете open-source или разрабатываете с нуля. Нет записи – организуете мост в HLS- или MP4-рекордер, обычно через бота-участника в комнате. Нет TURN-сервера – запускаете coturn или арендуете у Twilio, Cloudflare или CDN. Нет модели комнаты и presence – всё это обеспечивает сигналинг-сервер. Нет rate-лимитов и анти-абьюз-контролей – снова, это задача сигналинг-сервера. Нет способа транслировать один поток миллиону зрителей. WebRTC масштабируется до тысяч в каскаде SFU; для миллионов – мостите в HLS, DASH или Media over QUIC.

Список выглядит пугающе, но на деле open-source-экосистема закрывает каждую дыру, а паттерны хорошо задокументированы. Смысл их перечисления – задать ожидания: как только масштаб выходит за пределы «два человека разговаривают», работа сводится к заполнению пробелов, а не к самому WebRTC.

Ключевые тезисы

  • WebRTC – открытый стандарт W3C и IETF для встроенной в браузер передачи аудио, видео и данных в реальном времени, шифрованной по умолчанию и адаптирующейся под доступную полосу пропускания.
  • API браузера предоставляет один объект – RTCPeerConnection, – за которым скрываются девять RFC.
  • Сигналинг намеренно не стандартизирован; каждая команда разрабатывает собственный сервер, обычно на базе WebSocket.
  • ICE в сочетании с STUN и TURN находят путь через сеть; в продакшене 8–40% сессий требуют использования TURN-ретранслятора – это основная статья расходов.
  • Цель по задержке – 100–300 мс от экрана до экрана, что на два порядка ниже, чем у HLS, и делает WebRTC подходящим транспортом для интерактивного общения.
  • Архитектура peer-to-peer не работает при трёх и более участниках; в продакшен-конференцинге используется SFU (mediasoup, LiveKit, Janus, Jitsi, Pion) для маршрутизации потоков.

Что почитать дальше

Дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.