WHEP: HTTP-сигнализация для egress WebRTC

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

Последняя проверка: 2026-05-21 по IETF Internet-Draft draft-ietf-wish-whep-03 WebRTC-HTTP Egress Protocol (WHEP) (S. Garcia Murillo, C. Chen, D. Jenkins – опубликован 18 августа 2025 года, истёк 19 февраля 2026 года; статус-цель «Proposed Standard»; статус в рабочей группе – «Revised I-D Needed»); архиву рабочей группы IETF WISH и календарю milestone; документации Cloudflare Stream по WebRTC и changelog по май 2026; changelog платформ Dolby Millicast и OptiView; документации OvenMediaEngine по май 2026; и парному документу WHIP – IETF RFC 9725 от марта 2025 года.

TL;DR

WHEP, WebRTC-HTTP Egress Protocol, – это playback-зеркало WHIP: один HTTP POST со стороны зрителя возвращает SDP answer и запускает поток WebRTC-медиа. Рабочая группа IETF WISH черновики WHEP пишет с 2022 года, но по состоянию на май 2026 года документ всё ещё – draft-ietf-wish-whep-03, истёкший Internet-Draft с последней правкой от августа 2025 года, а не RFC. Этот разрыв статуса с уже опубликованным WHIP RFC – определяющий факт 2026 года и причина, почему каждое внедрение в продакшене сегодня технически целится в подвижную мишень. WHEP – правильный выбор delivery, когда задержка должна оставаться под секундой и вы контролируете обе стороны: и энкодер (через WHIP), и плеер; для всех остальных сценариев HLS, LL-HLS и LL-DASH остаются более безопасными умолчаниями.

Зачем эта статья

Двадцать лет у индустрии стриминга был один стандарт ingest (RTMP) и один стандарт playback (HLS), и эта асимметрия – пушим одним семейством протоколов, тянем другим – просто принималась как данность. Публикация WHIP как RFC 9725 в 2025 году начала закрывать сторону contribution. WHEP, симметрично, существует, чтобы закрыть сторону playback: дать браузеру, смарт-ТВ или мобильному приложению один стандартизованный способ запросить WebRTC-поток у любого совместимого сервера. Обещание – то же, что у WHIP, только на принимающем конце: переносимость. Плеер, который вы пишете сегодня, должен работать против любого WHEP-сервера завтра.

Но WHEP – это ещё и история о том, насколько медленно стандарты на самом деле движутся. По состоянию на май 2026 года вы можете запустить WHEP в продакшене уже сегодня – Cloudflare Stream, Dolby Millicast, OvenMediaEngine, MediaMTX, Janus, LiveKit, Ant Media и ещё несколько вендоров его поддерживают, – но при этом черновик IETF истёк, не успев стать RFC, рабочая группа в статусе «Revised I-D Needed», а самый свежий текст датируется августом 2025 года. Эта статья – канонический справочник по текущему состоянию WHEP для инженеров, продактов и архитекторов, рассматривающих его для delivery-стека 2026 года: что именно говорит черновик, чем он отличается от WHIP, как на практике выглядят расширения выбора слоёв и событий, какие платформы его поддерживают, какой у него реальный пол задержки и что значит нерешённый стандартный риск для процедур закупки.

Что такое WHEP – на одной странице

WHEP, WebRTC-HTTP Egress Protocol, – это тонкий HTTP-слой, позволяющий зрителю установить, поддерживать и закрыть WebRTC-плейбэк-сессию у медиа-сервера. Протокол делает ровно одну вещь: даёт зрителю стандартизованный способ принять одну WebRTC-медиа-сессию – один bundle-объединённый поток аудио + видео, идущий от сервера к зрителю, – и корректно её закрыть. Всё остальное – медиа-транспорт, кодеки, шифрование, контроль перегрузки – это обычный WebRTC по существующим спецификациям W3C и IETF. По форме протокол повторяет WHIP, но направление обратное.

Два URL – это WHEP endpoint URL (куда зритель делает POST, чтобы начать плейбэк-сессию) и WHEP session URL (возвращается в заголовке Location ответа 201 и используется для всего последующего). Глаголы: POST (начать сессию), DELETE (закрыть), PATCH (в двух разных ролях – либо обновить ICE, либо передать SDP answer зрителя в ответ на server counter-offer), OPTIONS (preflight CORS и обнаружение возможностей), GET (возвращает пустой 2XX, полезен только для health-check). Это и весь протокол – остальное в драфте – точные определения того, что должен содержать каждый запрос и ответ.

Механически: зритель генерирует SDP offer для одного WebRTC PeerConnection (один bundle-объединённый медиа-поток аудио + видео, направление recv-only, шифрование DTLS-SRTP оговорено), сериализует offer в текст и отправляет его в теле HTTP POST с заголовком Content-Type: application/sdp на WHEP endpoint URL. У сервера два возможных пути ответа: если он может принять offer как есть, он возвращает 201 Created с SDP answer в теле и session URL в заголовке Location; если принять offer не получается (например, зритель попросил кодек, которого сервер не кодирует), он возвращает 406 Not Acceptable с собственным SDP counter-offer в теле, и зритель должен ответить SDP answer'ом, отправленным в теле PATCH к session-ресурсу. Эта двух-путная переговорная схема – главное механическое отличие от WHIP и причина, по которой большинство продакшен-внедрений WHEP вообще не реализуют counter-offer-путь – они хардкодят предположение по кодеку и полагаются на счастливый путь 201 Created.

После завершения обмена offer/answer происходит обмен ICE-кандидатами (серверные кандидаты приходят полностью в первом ответе, а зритель потом докидывает свои через trickle), завершается DTLS-хэндшейк, и SRTP-медиа начинает течь от сервера к зрителю. Зритель закрывает сессию HTTP DELETE'ом на session URL; если зритель просто исчез, сервер замечает потерю через стандартные ICE-connectivity-check таймеры WebRTC и сам разбирает сессию.

Транспорт на проводе – то, чем пользуется WebRTC: UDP с ICE-кандидатами типов host / server-reflexive / relayed, DTLS для шифрования, SRTP для медиа, – а значит WHEP наследует от WebRTC обход NAT (STUN/TURN, подробно в нашей статье) и контроль перегрузки WebRTC. Слой сигнализации – HTTP/1.1 или HTTP/2; драфт версию не предписывает.

Рис. 1. Полная WHEP-плейбэк-сессия от начала до конца. Счастливый путь – один POST, возвращающий 201; counter-offer-путь добавляет 406 и последующий PATCH. Медиа едет на стандартном WebRTC под капотом, от сервера к зрителю.

Краткая история WHEP

WHEP начал жизнь в 2021 году как индивидуальный Internet-Draft (draft-murillo-whep-00), написанный тем же Серхио Гарсия Мурильо из Millicast, что был соавтором WHIP. Мотивация была прямая: если WHIP стандартизирует contribution в WebRTC, то соответствующий playback-путь нуждается в том же подходе, иначе вендоры стандартизуют простую сторону, а сложную оставят фрагментированной. Рабочая группа IETF WISH адаптировала работу в 2022 году как draft-ietf-wish-whep-00, поставив целью подачу документа в IESG для публикации к декабрю 2024 года.

Этот milestone уехал вправо. Рабочая группа выпустила четыре версии – -00 через -03, – причём последняя (draft-ietf-wish-whep-03) опубликована 18 августа 2025 года и истекла без обновления 19 февраля 2026 года. Текущий статус в IETF datatracker – «Expired» на уровне IESG и «Revised I-D Needed – Issue raised by WG» на уровне рабочей группы, что на простом языке означает: у документа открыты вопросы, которые рабочая группа должна закрыть прежде, чем его можно будет повторно подавать. Статус-цель для RFC остаётся «Proposed Standard». Авторы сейчас – S. Garcia Murillo (Millicast), C. Chen (ByteDance) и D. Jenkins (Everycast Labs Ltd) как редактор.

Эта ситуация неудобна по двум причинам. Во-первых, сам драфт содержит стандартную для IETF фразу: «It is inappropriate to use Internet-Drafts as reference material or to cite them other than as 'work in progress.'» Текст по конвенции IETF не является стабильной ссылкой. Во-вторых, каждый вендор, отгружающий WHEP сегодня, целится в неустойчивую мишень – а часть из них до сих пор отслеживает более ранний индивидуальный драфт (draft-murillo-whep-01), потому что под него написаны их клиентские библиотеки плеера. Документация Cloudflare, например, прямо указывает, что её реализация трекает draft-murillo-whep-01, а не драфт рабочей группы.

Полезный контраст: WHIP – это 16 драфтов и три с половиной года работы рабочей группы; WHEP – три драфта и три года, без публикуемой эталонной реализации со стороны IETF (как dash.js якорит DASH для DASH-IF). Движение по standards-track-у медленное в любом протоколе, но конкретный блокер WHEP – это не технические разногласия, а необходимость зафиксировать более сложную семантику в стабильном тексте: согласование кодеков, управление ресурсами на стороне зрителя, вопрос с расширением events-stream. Протокол работает в продакшене потому что каждый имплементатор сделал локальные выборы там, где спецификация оставила открытое поле.

HTTP-глаголы – что делает каждый

Поверхность протокола маленькая. Дальше – пробежка по проводной механике в том порядке, в котором её встречает зритель.

POST – начать сессию (§4.2)

Зритель генерирует SDP offer для одного WebRTC PeerConnection и шлёт его в теле HTTP POST на WHEP endpoint URL. Запрос обязан нести Content-Type: application/sdp. У SDP offer есть ограничения – направление recvonly (или sendrecv для зрителя, отправляющего обратный аудио-канал, редкий случай); направления inactive и sendonly в offer'ах зрителя запрещены; сессия должна объединять все медиа в один транспорт (§4.5.1, политика max-bundle); и разрешён ровно один MediaStream (§4.5.2). В этих рамках всё, что легально в WebRTC, легально в WHEP offer.

У сервера три возможных ответа. Самый частый – 201 Created (§4.2.1): сервер принял offer как есть, генерирует SDP answer с направлением sendonly, собирает свои ICE-кандидаты ещё до ответа и возвращает answer в теле с двумя заголовками: Location (указатель на session URL) и ETag (начальный entity-tag, идентифицирующий ICE-сессию; обязателен, если поддерживаются ICE restart).

Второй ответ – 406 Not Acceptable (§4.2.2): сервер не смог принять offer зрителя, но готов договариваться и возвращает в теле собственный SDP counter-offer. В ответе тот же Location с указанием на ресурс сессии и параметр valid-until в Content-Type, сообщающий, сколько counter-offer актуален (по умолчанию 30 секунд). Зритель должен ответить SDP answer'ом (направление recvonly), отправленным в теле PATCH на session URL с Content-Type: application/sdp; сервер подтверждает 204 No Content. Этот двухшаговый counter-offer уникален для WHEP – у WHIP его нет, потому что offer всегда определяет энкодер, а сервер его принимает.

Третий ответ – ошибка: 4XX для битого SDP или отсутствующей авторизации; 409 Conflict с заголовком Retry-After, когда у потока ещё нет живого паблишера (§4.2.8 – важный случай «зритель пришёл раньше броадкастера»); или 503 Service Unavailable, когда сервер не может выделить ресурсы (§4.6).

DELETE – закрыть сессию (§4.3)

Когда зритель закончил, он шлёт HTTP DELETE на WHEP session URL. Сервер закрывает ICE и DTLS, освобождает медиа-ресурсы и возвращает 200 OK. DELETE – единственный чистый способ закрыть сессию; если зритель пропал без DELETE, сервер опирается на свои ICE-connectivity-check таймеры WebRTC и consent freshness (RFC 7675), которые типично замечают потерю за несколько секунд и сами закрывают состояние.

PATCH – две разные задачи (§4.2.2 и §4.4)

PATCH в WHEP несёт два совершенно разных тела в зависимости от задачи. Первая задача, уже упомянутая выше, – передать SDP answer зрителя, когда сервер вернул counter-offer; запрос несёт Content-Type: application/sdp, сервер отвечает 204 No Content.

Вторая задача – и более частая – обновить ICE-состояние во время активной сессии (§4.4). Тело – Content-Type: application/trickle-ice-sdpfrag (формат SDP-фрагмента для trickle ICE из RFC 8840), и запрос обязан нести заголовок If-Match. Два подварианта. PATCH с trickle-ICE (только новые кандидаты, без restart) несёт If-Match: "<текущий-etag>", сервер отвечает 204 No Content, нового ETag нет. PATCH с ICE restart несёт буквальный If-Match: * (wildcard), сервер отвечает 200 OK, телом application/trickle-ice-sdpfrag с новыми ufrag/pwd плюс новый набор серверных кандидатов, и новым заголовком ETag, идентифицирующим новую ICE-сессию.

Коды ответа кодируют интерпретацию сервера: 204 No Content (trickle прошёл), 200 OK с новым ETag (restart прошёл), 412 Precondition Failed (If-Match ETag не совпал – состояние сессии ушло вперёд), 428 Precondition Required (запрос не нёс If-Match вообще), 422 Unprocessable Content (сервер поддерживает один из вариантов trickle / restart, но не оба, §4.4.1). Механика ETag та же, что в WHIP – она позволяет клиенту понять, актуальна ли его модель сессии.

OPTIONS и GET – preflight и health (§4.1, §4.3)

OPTIONS используется для двух целей. Первая – CORS preflight: браузер перед POST'ом на WHEP endpoint сделает OPTIONS, и WHEP endpoint обязан обработать preflight с корректными заголовками Access-Control-Allow-Origin. Вторая – анонсирование возможностей: ответ 200 OK на OPTIONS SHOULD содержать Accept-Post: application/sdp. GET по endpoint или session URL возвращает 2XX без тела – полезен только для проверок живости.

Выбор слоя, события и расширения – открытые края

Здесь драфт тоньше всего, и здесь больше всего расходятся продакшен-внедрения.

Две функции, нужные многим WHEP-плеерам по делу, – выбор, какой simulcast- или SVC-слой принимать, и приём server-push событий вида «паблишер только что остановился» или «зрителей сейчас 8427», – в драфте нормативно не специфицированы. В драфте есть extension-фреймворк (§4.9 и §6), который говорит «расширения анонсируют себя через заголовок Link в ответе 201 Created с атрибутом rel, содержащим IANA-зарегистрированный URN с префиксом urn:ietf:params:whep:ext:», и приводит один пример гипотетического Server-Sent Events-расширения – но он представлен как иллюстрация, не нормативно, и документ прямо указывает «this document does not specify such an extension». Более ранние индивидуальные драфты (draft-murillo-whep-*) несли JSON-API выбора слоёв и поток событий SSE, но эти куски были удалены до принятия рабочей группой, оставив поле вендорам.

На практике каждый вендор решил обе проблемы по-своему. Cloudflare выставляет выбор слоёв через отдельный per-session HTTP-endpoint, принимающий JSON-тело с полями {mediaId, rid, spatialLayerId, temporalLayerId} – форма, которая жила в более старых драфтах. Dolby Millicast использует SSE-канал, обнаруживаемый через заголовок Link, для событий вида viewercount, active, inactive, layers. OvenMediaEngine реализует выбор слоёв через query-параметры WHEP session URL. Ни одно из этих расширений не совместимо на проводе между вендорами. Плеер, умеющий говорить с layer-selection endpoint Cloudflare, не будет знать, как разговаривать с Millicast.

Для закупок эта фрагментация важнее, чем сам текст драфта. Провод достаточно совместим, чтобы зритель OvenMediaEngine воспроизвёл поток Millicast; управляемый плейбэк – переключить на нижний simulcast-слой, услышать конец потока – несовместим. Расширения у вендоров обычно документированы хорошо, но это вендор-специфичная поверхность, под которую нужно интегрироваться на каждую платформу.

Аутентификация – Bearer-токены и почему ими нужно пользоваться

Драфт говорит (§4.8), что «все WHEP-endpoint'ы, сессии и клиенты MUST support HTTP Authentication», и (§4.8.1), что «bearer token authentication ... MUST be supported by all WHEP entities». Любой совместимый WHEP-сервер понимает заголовок Authorization: Bearer <token>, и любой совместимый клиент умеет его слать. Если клиент не сконфигурирован с токеном, спецификация дополнительно требует, чтобы заголовок MUST NOT отправлялся ни в одном запросе – закрывая лазейку, через которую дефолтное или устаревшее значение могло бы утечь.

В отличие от WHIP, где bearer-токен почти всегда привязан к стабильной идентичности паблишера (аккаунт броадкастера), у WHEP-токенов в продакшене богаче жизненные циклы. Некоторые вендоры выпускают короткоживущие per-viewer JWT'ы, скоупированные на одну сессию и подписанные платформенным auth-сервисом; другие выпускают stream-level токены, которые может предъявить любой авторизованный зритель; некоторые поддерживают «открытые» потоки, не требующие токена вовсе (заголовок Authorization тогда просто отсутствует). Для платного контента токен – гейт. Относитесь к нему как к любому API credential'у: короткий TTL, скоуп на один поток где возможно, хранение в secrets manager'е.

Криптографическая защита на проводе двухслойная: HTTPS защищает сигнализацию (SDP offer, SDP answer, bearer-токен, обмен кандидатами), а DTLS-SRTP защищает медиа (стандартный DTLS-хэндшейк WebRTC порождает SRTP master keys, которые шифруют каждый медиа-пакет end-to-end). Оба слоя обязательны; §5 (Security Considerations) драфта говорит HTTPS SHALL be used. Plaintext-режима нет.

Какой реальный пол задержки

WHEP наследует latency-бюджет WebRTC. Реалистичная цифра для полного пайплайна WHIP → WHEP на чистой сети в 2026 году – между 200 и 800 миллисекундами glass-to-glass, в зависимости от географии и конфигурации.

Арифметика вслух. Берём типичный поток 30 fps, где один кадр приходит каждые 33 мс. Прибавим конвейер энкодера (30–100 мс для аппаратного H.264), DTLS-SRTP пакетизацию, network RTT на ingest (5–100 мс в одном регионе), маршрутизацию медиа в сервере (10–50 мс внутри SFU), network RTT на egress (5–100 мс в одном регионе) и jitter buffer на стороне WHEP (типично 100–300 мс в WebRTC, настраиваемо). На same-region проводном пути получается около 300–500 мс; на трансатлантическом – удваивается.

Сравнение end-to-end с альтернативами:

КонфигурацияGlass-to-glassЗаметки
WHIP → WHEP, same-region проводной200–500 мсСамый низкий contribution + delivery путь 2026.
WHIP → WHEP, трансатлантический проводной400–800 мсКаждый океанский RTT добавляет около 100 мс.
RTMPS → сервер → WHEP800–1500 мсRTMPS-нога contribution доминирует; WHEP-нога быстрая.
RTMPS → сервер → LL-HLS3–6 сLL-HLS-упаковщик доминирует.
WHIP → сервер → LL-HLS3–6 сContribution быстрый; всё равно LL-HLS-упаковщик доминирует.
RTMPS → сервер → HLS8–20 сКлассическая базовая линия broadcast-on-internet.

Второе важное измерение: WHEP, как и любая WebRTC-доставка, требует относительно чистого playback-пути. Контроль перегрузки и jitter buffer WebRTC терпят несколько процентов потерь, но 5%-ные потери на враждебной мобильной сети или перегруженной домашней Wi-Fi – это место, где WebRTC деградирует заметно. HLS-плеер деградирует, переключаясь на меньший битрейт; WHEP-плеер деградирует, замирая. Интуиция индустрии 2026 года – использовать LL-HLS для «низкая задержка на массе и шумных сетях»; использовать WHEP для «sub-секундная задержка на чистых сетях для умеренного количества зрителей» – этот компромисс хорошо описывает.

Конкретный пример – плейбэк Cloudflare Stream через WHEP

Проследим одну конкретную конфигурацию. Воспроизводим поток 1080p30 H.264 на 6 Mbps с WHEP endpoint Cloudflare Stream в браузере Chrome на проводном Ethernet, против потока, который сейчас в этот же Cloudflare-аккаунт пушит OBS-энкодер через WHIP.

Клиентский код прост. Браузер создаёт RTCPeerConnection, добавляет два RTCRtpTransceiver в режиме recvonly (один на видео, один на аудио), вызывает createOffer() и затем fetch(WHEP_URL, { method: 'POST', headers: { 'Content-Type': 'application/sdp', 'Authorization': 'Bearer ' + token }, body: offer.sdp }). WHEP endpoint Cloudflare валидирует offer, собирает свой полный набор ICE-кандидатов (host-кандидаты в каждом регионе Cloudflare PoP плюс TURN-relay), генерирует SDP answer с медиа-секциями sendonly и полным списком кандидатов и возвращает 201 Created с Location: /webrtc/sessions/<viewer-session-id> и ETag: "view-abc123...".

Браузер принимает answer, вызывает pc.setRemoteDescription(answer), запускается ICE, connectivity check успешно сходится на host-кандидат Cloudflare в том же регионе (RTT около 15 мс). DTLS-хэндшейк завершается за два round-trip'а (~30 мс). Генерируются SRTP-ключи, и медиа начинает течь с сервера на зрителя. Срабатывает событие RTCPeerConnection.ontrack на видео- и аудиотрек; приложение присоединяет их к <video> через videoElement.srcObject = stream; начинается воспроизведение. End-to-end задержка glass-to-glass, измеренная по миллисекундным часам на исходной камере и в WHEP-вкладке браузера: примерно 380 мс.

В течение сессии браузер собирает один дополнительный server-reflexive ICE-кандидат (определение публичного IP завершается после первого POST'а) и отправляет PATCH с Content-Type: application/trickle-ice-sdpfrag, If-Match: "view-abc123..." и кандидатом в теле. Cloudflare отвечает 204 No Content (успешный trickle, без нового ETag). Сессия идёт 90 минут без перерывов; когда пользователь закрывает вкладку, браузер шлёт DELETE /webrtc/sessions/<viewer-session-id> с bearer-токеном, Cloudflare отвечает 200 OK, SRTP-поток останавливается, ресурсы освобождаются.

Сравним с тем же контентом через HLS. Тот же OBS-энкодер, тот же Cloudflare-аккаунт, но зритель тянет HLS-манифест вместо открытия WHEP-сессии: glass-to-glass задержка примерно 12 секунд. Сравним с LL-HLS на том же контенте: примерно 4 секунды. ~380 мс у WHEP – это на полтора порядка ниже, чем у HLS, и в десять раз ниже, чем у LL-HLS. Это единственная цифра, которая имеет значение для выбора use case.

Рис. 2. Та же исходная камера, тот же сервис Cloudflare Stream, три delivery-стека. WHEP даёт около 380 мс glass-to-glass на чистом проводном пути; LL-HLS – около 4 с; HLS – около 12 с. Разница в задержке – единственная причина, почему WHEP существует.

Какие платформы реально поддерживают WHEP в 2026 году

Таблица ниже суммирует поддержку WHEP playback на платформах, которые встречаются в клиентских проектах в 2026 году. Данные актуальны на май 2026; перед принятием архитектурных решений сверьтесь с вендорской документацией.

ПлатформаWHEP playbackTrickle ICEВыбор слояПоток событийЗаметки
Cloudflare StreamДа (GA)ДаВендорный JSON APIНетТрекает draft-murillo-whep-01; sub-секундная доставка неограниченному числу зрителей через edge Cloudflare.
Dolby MillicastДа (GA)ДаВендорный JSON APIДа (SSE через Link header)Первый коммерческий дом протокола; самое зрелое расширение events-stream в индустрии.
AWS IVS Real-TimeДа (GA)ДаНетНетWebRTC playback через IVS Web Broadcast SDK; WHEP на уровне API.
OvenMediaEngineДа (GA)ДаAPI через query-параметрыНетOpen-source; очень частый self-hosted выбор для пайплайнов WHIP→WHEP.
MediaMTXДа (GA)ДаНетНетOpen-source медиа-сервер с широким покрытием протоколов.
JanusДа (плагин)ДаЧерез плагинНетSelf-hosted SFU; WHEP-плагин от сообщества с 2023 года.
mediasoupДа (community)ДаЧерез приложениеНетSelf-hosted SFU; community WHEP-шлюзы существуют.
LiveKitДа (GA)ДаЧерез SDKЧерез SDKCloud и self-hosted; WHEP поддерживается параллельно с нативным LiveKit SDK.
Ant Media ServerДа (GA)ДаВендорный APIДаWHEP добавлен в v2.10; managed и self-hosted.
THEO TechnologiesДа (GA)ДаНетНетИнтегрирован с HESP для гибридных стеков.
Wowza Streaming EngineДаДаНетНетSelf-hosted; WHEP добавлен в 2024 году.
Mux LiveДа (GA)ДаНетНетТрёх-протокольный delivery endpoint.
Vimeo LivestreamДаДаНетНетТрёх-протокольный delivery endpoint.
YouTubeНетТолько HLS / DASH.
TwitchНетТолько HLS.
Facebook LiveНетТолько HLS / DASH.

Раскол зеркалит карту поддержки WHIP: developer-platform и B2B-видеопродукты отгружают WHEP параллельно с HLS и DASH, а потребительские social-платформы – HLS-first и публично WHEP в дорожной карте не показывают. Причина та же с обеих сторон – потребительский social работает на масштабах, где per-viewer экономика WebRTC неконкурентна, и HLS-over-CDN по-прежнему дешевле на порядок на таких объёмах.

Типовые ошибки – что ломает WHEP в продакшене

Короткий список отказов, которые встречаются чаще всего при подъёме нового WHEP delivery-линка. Большинство – конфигурационные несостыковки, а не баги протокола.

Подводный камень 1: ICE-сбой из-за неконфигурированного TURN. WebRTC нуждается в TURN-сервере, когда зритель за симметричным NAT, не позволяющим прямую peer-to-peer связь. В каждом продакшен-внедрении WHEP должен быть TURN (свой или хостовый – anycast TURN Cloudflare, TURN Twilio, кластер Coturn). Самый частый отказ – зритель сообщает «ICE failed», потому что в SDP answer не вернулось ни одного TURN-кандидата. Решение – либо настроить WHEP-сервер на анонс TURN URL (драфт это разрешает через заголовок Link с rel="ice-server"), либо использовать TURN платформы.

Подводный камень 2: counter-offer не реализован в плеере. Путь 406 Not Acceptable с counter-offer редок в продакшене, но реален на некоторых self-hosted серверах, когда предложенные зрителем кодеки не совпадают с теми, что сервер кодирует. Большинство плеерных библиотек падают на 406, потому что парсинг counter-offer SDP так и не был дописан. Решение – либо расширить набор предлагаемых кодеков (всегда предлагайте H.264 baseline + Opus – их поддерживает любой сервер), либо реализовать ответ с PATCH-SDP-answer.

Подводный камень 3: HTTPS не обязателен. §5 драфта говорит HTTPS SHALL be used. Несколько self-hosted серверов поставляют plaintext-HTTP режим для удобства локальной разработки; никогда не разворачивайте его в продакшене. Cleartext SDP палит bearer-токен на проводе (он едет в заголовке Authorization POST'а), а слитый токен даёт права плейбэка любому атакующему на пути. Используйте HTTPS с валидным сертификатом на каждом WHEP endpoint.

Подводный камень 4: bearer-токен в query string. Часть вендоров документирует «удобную» форму, когда bearer-токен дописывается в URL как query-параметр. Этой формы нет в драфте, и её использование палит токен в каждый HTTP-посредник, логирующий URL (балансировщики, прокси, edge-логи CDN, история браузера). Используйте заголовок Authorization: Bearer <token>.

Подводный камень 5: относиться к WHEP как к HLS по масштабированию. Каждый WHEP-зритель – это настоящий WebRTC-пир на сервере. Сервер, обслуживающий 10 000 зрителей, держит 10 000 SRTP-контекстов шифрования, 10 000 jitter buffer'ов, 10 000 ICE-сессий и 10 000 исходящих медиа-потоков. Юнит-экономика принципиально отличается от модели HLS/CDN-egress. Планируйте мощность per-viewer, не per-stream; выбирайте провайдера, который сам обрабатывает архитектуру fan-out на SFU (подробности в нашей статье по масштабированию WebRTC).

Подводный камень 6: считать драфт стабильным. WHEP сейчас – draft-ietf-wish-whep-03, истёкший в феврале 2026 года, с пометкой рабочей группы «Revised I-D Needed». Будущая ревизия может поменять семантику ETag, поток counter-offer, тему выбора слоёв или любую IANA-регистрацию. Продакшен-внедрения никакого шума не увидят – вендоры реализовали то, что реализовали, – но если вы пишете собственную плеерную библиотеку, отслеживайте mailing list рабочей группы. Текст реально движется.

Когда выбирать WHEP – фреймворк решения

WHEP – правильный выбор delivery в определённом наборе условий. Фреймворк ниже – тот, через который мы проходим с клиентами при наброске playback-архитектуры 2026 года.

Выбирайте WHEP, когда: (а) бюджет задержки меньше секунды glass-to-glass; (б) сеть зрителя – проводная или здоровый Wi-Fi/5G-канал с ожидаемыми потерями меньше 1%; (в) аудитория ограничена (типично меньше 10 000 одновременных зрителей на поток, где WebRTC fan-out экономика всё ещё работает); (г) целевая платформа уже отгрузила WHEP delivery (любая из таблицы выше); и (д) плеер работает в браузере, мобильном приложении или среде смарт-ТВ с WebRTC-стеком. Contribution-путь в идеале – WHIP для минимальной полной задержки.

Выбирайте LL-HLS, когда: задержка должна быть меньше пяти секунд, но аудитория больше 10 000 (или неограниченна), сеть смешана и неизвестна (LL-HLS деградирует переключением битрейта, не замиранием), либо требование покрытия устройств включает устаревшие смарт-ТВ и приставки без WebRTC-стека.

Выбирайте LL-DASH / CMAF chunked, когда: тулчейн уже DASH-нативный (Bitmovin, Shaka Packager) и плеерная экосистема – dash.js или Shaka.

Выбирайте HLS, когда: задержка не ограничивает (VOD, архив live, broadcast-хвост) – HLS-over-CDN самая дешёвая egress-экономика per-viewer с большим отрывом.

Выбирайте HESP, когда: тулчейн HESP-Alliance уже стоит и заявленные 400 мс задержки подтверждены на вашем пути.

Рис. 3. Дерево решений по выбору delivery в 2026. WHEP для sub-секунды на чистых путях при ограниченной аудитории; LL-HLS для sub-пятисекундной на масштабе; HLS для дешёвого CDN-egress; LL-DASH или HESP, когда уже стоит соответствующий тулчейн.

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

Мы поставляем стеки delivery WHIP → WHEP в нескольких вертикалях с момента, когда протокол стабилизировался достаточно для продакшен-доверия: телемедицина, где клиническое устройство пушит через WHIP в центральный SFU, а специалисты принимают через WHEP для sub-секундной удалённой консультации; e-learning live-классы, где преподаватель пушит через WHIP, активные участники получают через WHEP, а пассивные зрители падают на LL-HLS; live-шопинг и аукционы, где модератор пушит через WHIP, а аудитория смотрит через WHEP с LL-HLS-хвостом для broadcast-шлейфа; AR/VR live-события, где задержка WHEP держит аудиторию в пределах бюджета, который требует человеческое восприятие. Закономерность одна: когда целевая задержка однозначно sub-секунда и аудитория ограничена, WHEP – правильный инструмент, а расширения с открытыми краями (выбор слоёв, события) интегрируются под конкретного вендора, выбранного нами.

Ключевые выводы

  • WHEP – playback-зеркало WHIP: один HTTP POST возвращает SDP answer, и поток WebRTC-медиа течёт с сервера на зрителя.
  • По состоянию на май 2026 года WHEP – это draft-ietf-wish-whep-03: истёкший IETF Internet-Draft, ещё не RFC; рабочая группа в статусе «Revised I-D Needed».
  • Провод – четыре HTTP-глагола (POST, DELETE, PATCH, OPTIONS) против двух URL, плюс уникальный counter-offer-путь (406 → PATCH), которого у WHIP нет.
  • Выбор слоя и события в драфт не вошли; каждый вендор отгружает непереносимое расширение и для того, и для другого.
  • Реальная задержка glass-to-glass: 200–500 мс same-region проводной (WHIP-to-WHEP), 400–800 мс трансатлантический.
  • Выбирайте WHEP, когда задержка должна быть меньше секунды на чистой сети при ограниченной аудитории; выбирайте LL-HLS для sub-пятисекунды на масштабе.
  • Bearer-токен обязателен; HTTPS обязателен; токен никогда не в query-параметре URL.

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

CTA

Поговорить со streaming-инженером · Посмотреть наши кейсы · Скачать WHEP integration checklist (PDF)

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

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