Simulcast и SVC: как SFU обслуживает разнородную аудиторию

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

Коротко

Selective Forwarding Unit пересылает медиа подписчикам как есть, без перекодирования. Это значит, что без специальных мер каждый подписчик получит один и тот же закодированный поток – это устраивает зал с одинаковыми ноутбуками на одинаковом гигабите, но бесполезно в реальности, где один зритель сидит на смартфоне с LTE, а другой – за десктопом с гигабитным ethernet. Simulcast решает это так: publisher отправляет несколько независимых закодированных копий одной и той же камеры в разных разрешениях и битрейтах, а сервер выбирает подходящую копию для каждого подписчика в каждый момент. Scalable Video Coding (SVC) решает ту же задачу иначе: один закодированный поток с вложенными временными и пространственными слоями, любой префикс которых декодируется в валидную картинку. В 2026 году simulcast – это умолчание для VP8 и H.264 во всех браузерах, SVC – это умолчание для VP9 и AV1 в Chromium, и обе техники сосуществуют внутри каждого современного SFU, включая мульти-кодек simulcast у LiveKit, где один publisher обслуживает оба типа подписчика из одной комнаты.

Зачем это знать

Если вы запускаете WebRTC-продукт с более чем пятью участниками в комнате, выбор между simulcast и SVC лежит под каждой жалобой на качество, под каждым счётом за CPU на устройстве publisher, под каждым тикетом «почему у мобильного зрителя стрим десктопа с 4K-таблицей выглядит как мыло» и под измеримой строкой в счёте за TURN. Решение не абстрактное: оно меняет, что делает ваш конвейер кодирования, что делает код пересылки RTP в SFU, что делают декодеры подписчиков и что вы можете отгрузить в Safari, а что работает только в Chromium. В этой статье – архитектура, стандарты, числа и продакшен-реальность 2026 года для пяти основных SFU, чтобы, когда инженер скажет «давайте перейдём на AV1 SVC», вы точно знали, что покупаете и от чего отказываетесь.

Задача, которую создаёт разнородная аудитория

Представьте видеозвонок на двенадцать человек. Трое сидят за столом на гигабитной оптике, четверо – на гостиничном Wi-Fi, который колеблется от 3 до 30 Mbps, двое – на смартфонах между сотами, один смотрит конференцию в браузере Smart TV через ненадёжный mesh-роутер, а ещё двое – ИИ-агенты в датацентре, которым можно отдать любое качество. Publisher каждой камеры заливает поток в Selective Forwarding Unit – сервер, который по построению не декодирует и не перекодирует медиа: он смотрит заголовки пакетов и пересылает нужные пакеты нужным подписчикам. (Контекст по топологиям – в SFU, MCU и Mesh.) Если каждый publisher загружал бы один поток одного битрейта, SFU был бы обязан пересылать ровно его всем подписчикам. Поток высокого разрешения, который радует десктоп, утопил бы LTE-канал смартфона и вызвал неуправляемый congestion-event; поток низкого разрешения, который умещается в трубу смартфона, на десктопе оказался бы расплывчатым прямоугольником.

Это и есть проблема разнородной аудитории. Каждый реальный WebRTC-продукт сталкивается с ней в первый же день. Два решения, которые WebRTC-экосистема реально отгружает в 2026 году, – simulcast и SVC, и почти ни один продукт не выбирает одно в ущерб другому: оба сосуществуют внутри одного сервера, часто внутри одной комнаты.

Рисунок 1. Форма задачи. Один publisher; много подписчиков с очень разной сетевой и экранной реальностью. Работа SFU – отдать каждому подписчику ту версию, которой он реально сможет воспользоваться.

Simulcast простыми словами

Simulcast – более простая из двух идей. Вместо того чтобы просить кодировщик publisher сделать один поток, вы просите его сделать несколько – обычно три – в разных разрешениях и битрейтах из одного и того же кадра камеры. Типичная конфигурация – 180p около 150 kbps, 360p около 500 kbps и 720p около 1500 kbps. Каждый из этих потоков – полностью независимое, самостоятельное видео: 180p-поток – это полноценное видео, декодируемое любым совместимым декодером без обращения к другим, и то же верно для 360p и 720p. Publisher загружает все три на SFU в одной RTP-сессии. SFU видит три потока, помеченных идентификаторами, которые сообщают, что это альтернативы одного и того же медиаисточника.

Когда подписчик заходит, SFU решает, какой из трёх потоков ему пересылать. Решение непрерывное и опирается на три сигнала: оценку полосы со стороны приёмника, запрошенный приложением слой (потому что приложение может попросить «самый низкий слой», когда тайл подписчика свёрнут в превью), и собственные данные SFU о том, какие потоки реально производятся. Когда сеть подписчика улучшается, SFU апгрейдит – начинает пересылать пакеты более высокого потока вместо нижнего, исключая нижний из решения. Когда сеть ухудшается, SFU даунгрейдит, пересылая нижний поток и останавливая верхний.

Механизм нормативно описан в RFC 8853 (январь 2021), Using Simulcast in Session Description Protocol (SDP) and RTP Sessions. RFC 8853 описывает, как заявлять способность к simulcast в обмене SDP offer/answer (медиа-атрибут a=simulcast) и как идентифицировать разные RTP-потоки одного медиаисточника на уровне RTP (источниковый дескриптор RtpStreamId, при этом метод RTP header extension – это SHOULD-implement). Документ написан рабочей группой IETF MMUSIC; смежный RFC 8852 определяет сам RtpStreamId.

Цена simulcast – измеряется в CPU, памяти и аплинке

Платит publisher. Кодировщик publisher параллельно прогоняет три независимых кодирования одной и той же камеры. CPU-стоимость суб-линейная, потому что уменьшенные по разрешению входы кодируются дешевле, а многие кодеки переиспользуют motion-оценку между разрешениями, – но стоимость реальна: типичные коэффициенты от 1,5 до 2,5 относительно одного потока в зависимости от кодека, набора разрешений и аппаратного ускорения. Память – аналогично. Аплинк-полоса – это сумма трёх потоков: если кодировать 180p в 150 kbps, 360p в 500 kbps и 720p в 1500 kbps, publisher загружает примерно 2150 kbps для этой камеры против 1500 kbps для одного 720p – это примерно на 43% больше байтов на проводе, чтобы дать SFU свободу выбора.

Арифметика вслух. Один 720p в 1500 kbps съедает 1500 kbps аплинка. Трёхступенчатый simulcast 150 + 500 + 1500 kbps в сумме даёт 2150 kbps. Отношение 2150 ÷ 1500 = 1,43. Publisher платит на 43% больше аплинка за то, чтобы SFU мог переключать качество по подписчику.

Стоимость на стороне подписчика – нулевая. Каждый подписчик получает ровно один поток – тот, который ему выбрал SFU, – и декодирует его как обычный RTP-видеопоток. Декодер подписчика никак не меняется по сравнению с одним потоком. В этом великий подарок simulcast: вся сложность живёт на publisher и на сервере. Подписчик – обычно более многочисленная сторона уравнения – остаётся нетронутым.

Где simulcast буксует

CPU и аплинк у publisher – очевидные затраты. Менее очевидные всплывают, когда вы начинаете оптимизировать. Три независимых кодирования – это три независимых rate-control-цикла, три расписания keyframe'ов и три long-tail-момента, когда keyframe одного потока приходится посередине обновления другого. Латентность переключения качества небольшая, но не нулевая: когда SFU решает переключить подписчика с 360p на 720p, декодеру подписчика нужен keyframe в 720p, чтобы начать декодировать его, и SFU либо ждёт следующего штатного keyframe'a 720p, либо отправляет PLI (Picture Loss Indication) – RTCP-обратную связь к publisher с просьбой о keyframe немедленно. PLI к publisher вызывает дополнительный keyframe во всех simulcast-слоях, что на короткое время стоит лишних байтов. Подбор интервала keyframe'ов так, чтобы балансировать задержку переключения и эффективность по полосе, – одна из стандартных эксплуатационных задач simulcast.

Simulcast также даёт грубую ручку качества. С тремя слоями у вас три варианта на подписчика. Если нужна более плавная адаптация между ними, её нет – кодировщик производит ровно три потока. SVC, следующий раздел, как раз снимает это ограничение.

Рисунок 2. Цена simulcast по полосе и CPU на publisher. Подписчик видит один поток; publisher платит «налог на много-кодирование».

SVC простыми словами

Scalable Video Coding – другой ответ на тот же вопрос. Вместо того чтобы просить кодировщик сделать N независимых потоков, вы просите его сделать один поток, организованный во вложенные слои. Базовый слой – это полная, декодируемая, низкокачественная версия видео. Слои-расширения, добавленные к базовому, декодируются в более высокое качество. Любой префикс слоёв – от «только базовый» до «все» – сам по себе валидный поток, декодируемый в валидную картинку. Кодировщик использует motion-compensated- и frequency-domain-зависимости между слоями так, чтобы суммарная битовая цена «базовый + расширения» была близка (но не равна) цене кодирования высококачественной версии напрямую.

Слои бывают в двух измерениях, иногда в трёх. Временные слои разделяют частоту кадров: базовый temporal-слой на 7,5 fps, плюс один слой-расширение, дающий 15 fps, плюс ещё один до 30 fps. Пространственные слои разделяют разрешение: базовый spatial-слой 180p, плюс расширение до 360p, плюс ещё одно до 720p. Некоторые кодеки поддерживают и качественные (SNR) слои – то же разрешение и frame rate при разной достоверности. W3C Scalable Video Coding (SVC) Extension for WebRTC стандартизирует компактное именование: LxTy означает x пространственных и y временных слоёв. L1T3 – один пространственный слой с тремя временными, чисто временной SVC, доступен в любом WebRTC-кодеке, включая VP8 и H.264. L3T3 – три пространственных слоя и три временных, полный spatial+temporal SVC, доступен только в VP9 и AV1.

Когда SFU получает SVC-поток, он пересылает только пакеты, относящиеся к слоям, которые нужны подписчику. Поскольку кодировщик пометил каждый пакет своим слоем (через payload-format-specific header – VP9 payload descriptor для VP9, AV1 Dependency Descriptor для AV1), SFU может per-packet решать, дропнуть или переслать. Декодер подписчика собирает пришедшие пакеты в валидную картинку того разрешения и frame rate, что соответствует пересланным слоям.

Цена SVC – измеряется в сложности кодировщика и поддержке кодеков

CPU publisher ниже, чем у simulcast, потому что в работе одно кодирование, но кодировщик делает более сложную работу, чем одиночное: он поддерживает reference-связи поверх иерархии слоёв и помечает каждый выходной пакет принадлежностью к слою. Эмпирически SVC-кодирование того же качества и разрешения стоит примерно 1,1–1,4× от одиночного – заметно меньше, чем 1,5–2,5× у трёх-ступенчатого simulcast. Аплинк-полоса тоже ниже: слоевые зависимости означают, что суммарный размер «180p + 360p + 720p» в SVC-доставке примерно на 10–25% меньше, чем те же три потока в simulcast, потому что слои-расширения несут разницы, а не полные переизлагания.

Стоимость на стороне подписчика снова по существу нулевая. Декодер подписчика получает частичный поток – только те слои, которые SFU решил переслать – и декодирует его как обычное видео. Декодер должен поддерживать SVC-профиль кодека, но любой современный декодер VP9 и AV1 это умеет.

Подвох – в поддержке кодеков. SVC требует кодека, определяющего семантику масштабируемости, а SDP/RTP-механизмы требуют, чтобы оба конца понимали эту семантику. В 2026 году практическая карта такая:

  • VP8: только temporal SVC (L1T2, L1T3). Никаких пространственных слоёв. Поддерживается в каждом браузере, поддерживающем VP8, – то есть во всех.
  • H.264: только temporal SVC (L1T2, L1T3). Поддерживается в каждом браузере с H.264, что сейчас тоже все, включая Chromium-браузеры с момента появления в них simulcast-поддержки.
  • VP9: полный spatial+temporal SVC до L3T3 и его варианта L3T3_KEY. Поддерживается в Chrome, Firefox и Edge; Safari умеет декодировать VP9, но не кодировать, то есть пользователь Safari не может публиковать VP9 SVC.
  • AV1: полный spatial+temporal SVC, включая L3T3 и много дополнительных режимов. Encode и decode – в Chromium-браузерах и Firefox (с некоторыми ограничениями); Safari умеет декодировать AV1 на устройствах с аппаратным AV1 (iPhone 15 Pro и новее, Apple Silicon Mac), но кодировать AV1 пока нет.

Гэп в Safari – практическая стена, держащая simulcast в живых. Если в вашем продукте есть Safari-publisher'ы, на VP9 или AV1 SVC рассчитывать нельзя; падаете на simulcast в VP8 или H.264. Поэтому каждый продакшен-SFU 2026 года поддерживает и simulcast, и SVC, нередко в одной комнате.

Рисунок 3. Simulcast (слева) против SVC (справа). Simulcast – это N независимых потоков; SVC – один поток с N вложенными слоями. Логика пересылки в SFU структурно похожа; семантика кодировщика и кодека – нет.

Режимы масштабируемости на примерах

Спецификация W3C webrtc-svc называет режим масштабируемости, который вы запрашиваете на стороне кодировщика. Вы передаёте строку вроде "L1T3" или "L3T3_KEY" в поле encodings[i].scalabilityMode у вызова RTCRtpSender.setParameters(). Кодировщик, если он поддерживает запрошенный режим для запрошенного кодека, настраивает свой граф зависимостей соответствующим образом и помечает каждый выходной пакет. Приёмнику не нужно знать, какой режим был использован, – членство в слое лежит в payload descriptor.

Соглашение об именовании читается ясно, если один раз освоить:

  • L1T1 – один пространственный, один временной. Без SVC; это обычное одиночное кодирование.
  • L1T2 – один пространственный, два временных. Делит частоту кадров на половину и полный rate. SFU может отдать «каждый второй кадр» зажатому подписчику и «каждый кадр» – свободному, из того же загруженного потока.
  • L1T3 – один пространственный, три временных. Делит частоту на четверть / половину / полный rate. Самый распространённый temporal SVC в продакшене 2026 года.
  • L2T3 / L3T3 – два или три пространственных слоя, три временных. Полный spatial+temporal. Только VP9 и AV1.
  • L3T3_KEY – вариант, где нижние пространственные слои не зависят от верхних на keyframe'ах, что делает переключение слоёв чище ценой чуть большего числа байтов. Это режим, который LiveKit просит по умолчанию при публикации VP9 или AV1.

Числовой пример: temporal-слои и сколько полосы съедает 360p-подписчик

Пусть publisher кодирует 720p VP9-поток в L1T3 – один пространственный слой 720p, три временных слоя, делящих частоту 7,5 / 15 / 30 fps. Кодировщик целится в суммарный битрейт 1500 kbps при 30 fps. Типичное распределение бюджета SVC отдаёт примерно половину битов базовому temporal-слою и по четверти на расширение, то есть типичная разбивка – 750 / 375 / 375 kbps на три слоя.

Подписчик на зажатой мобильной сети просит «только нижний temporal-слой» – SFU пересылает только базовый, и подписчик декодирует 720p при 7,5 fps, потребляя 750 kbps. Подписчик на здоровом десктопном канале получает все три слоя – SFU пересылает всё, и подписчик декодирует 720p при 30 fps, потребляя 1500 kbps. Та же одна загрузка publisher (1500 kbps) обслуживает обоих подписчиков одновременно; меняется лишь решение SFU. Сравните с simulcast, где publisher обязан был бы закодировать и загрузить два отдельных потока – один на 7,5 fps, один на 30 fps, – чтобы дать SFU тот же выбор.

В этом преимущество SVC по полосе, и оно масштабируется: каждый дополнительный слой, который SFU может раздать, добавляет вариант качества без добавления полного нового закодированного потока в аплинк publisher. Недостаток – ограничение по кодекам, уже разобранное выше. Преимущество живёт в комнатах, где кодеки publisher'ов умеют декодировать подписчики.

Как SFU реально решает, какие слои пересылать

Эффективная receive-полоса подписчика – главный вход SFU. Большинство продакшен-SFU гоняют per-subscriber bandwidth estimator поверх transport-wide congestion control – TWCC RTP header extension поддерживают LiveKit, mediasoup, Janus и SFU на базе Pion. TWCC даёт подписчику возможность сообщать publisher (через SFU) о времени прихода каждого пакета, что кормит bandwidth estimator на SFU, выдающий per-subscriber оценку байт/сек, которую подписчик способен переварить. Estimator подробно описан в работе IETF transport-wide congestion control и в реализации Google Congestion Control в libwebrtc.

Зная полосу подписчика, SFU выбирает набор слоёв, использующий её как можно полнее, но без превышения. Для simulcast: пересылать самый высокий поток, чей средний битрейт укладывается в оценку, с гистерезисом против дребезга. Для SVC: пересылать наибольший префикс слоёв, который умещается. SFU также выставляет приложению API для подсказок – ограничение, которое перекрывает полосу и используется, когда тайл подписчика настолько мал, что 180p достаточно, что бы ни выдержала сеть. consumer.setPreferredLayers() в mediasoup и параметры подписки в LiveKit делают именно это; SFU воспринимает их как потолок для слоя, который выбирает bandwidth estimator.

Решение о пересылке – непрерывное. Каждые 100–500 мс (зависит от SFU) per-subscriber-цикл пересчитывается: пере-оценить полосу, пере-выбрать слой, реагировать на PLI от подписчика (что заставляет SFU либо запросить keyframe у publisher, либо упасть на слой, у которого недавний keyframe уже есть). Когда тайл подписчика меняет размер – участника пина́ют, превью разворачивается – приложение зовёт SFU обновить preferred layers, и следующая итерация цикла учитывает новый потолок.

Распространённая ошибка: предполагать, что SFU «знает» экран подписчика

Частая ошибка на первом деплое – забыть, что SFU сам по себе не знает, насколько большой у подписчика тайл. SFU видит полосу подписчика и его RTCP receiver reports. Он не видит DOM подписчика и не видит разрешение его экрана. Если подписчик отображает участника в 90×90 пиксельном превью в сайдбаре, SFU с радостью пошлёт 720p-пакеты на заполнение этого превью, если приложение явно не скажет иначе. Результат – счёт: аплинк SFU к подписчику тащит куда больше байтов, чем подписчик реально съедает визуально. Лечится так: проводить состояние UI подписчика – пин / превью, развёрнуто / свёрнуто, видно / скрыто за экраном – в вызов, который ставит preferred layer на подписку. mediasoup, LiveKit, Janus, Jitsi Videobridge и Pion – все выставляют этот хук; забыть его – самая частая причина, по которой счёт за WebRTC-продакшен оказывается вдвое больше нужного.

Что пять основных SFU реально делают в 2026 году

Пять проектов, разобранных в Выборе SFU, поддерживают и simulcast, и SVC, но реализуют логику выбора слоёв и API publisher по-разному. Карта 2026 года ниже.

mediasoup даёт first-class поддержку simulcast и SVC по VP8, VP9, H.264 и AV1. API consumer выставляет preferredLayers и setPreferredLayers() для целевого spatial+temporal-слоя; SFU гоняет собственный per-consumer scoring loop, который выбирает фактический слой по оценке полосы consumer и доступным слоям producer. Поддержка AV1 SVC была добавлена в C++-ядро mediasoup раньше большинства других серверов и активно используется в продакшене у клиентов с крупномасштабными гибридами Pion/mediasoup.

LiveKit по умолчанию использует simulcast для VP8- и H.264-publisher'ов и автоматически переключается на SVC для VP9 и AV1, запрашивая L3T3_KEY как режим по умолчанию. Фича LiveKit Dynacast связывает решение о пересылке слоёв с видимостью подписчика, автоматически ставя поток на паузу, когда его никто не смотрит, и приостанавливая отдельные слои (для simulcast) или целые потоки (для SVC, где отдельные слои ставить на паузу нельзя) при даунгрейде подписчика. LiveKit также реализует мульти-кодек simulcast: publisher может крутить резервный кодек (VP8 simulcast) параллельно с основным (AV1 SVC), чтобы legacy-Safari-подписчики получили рабочий поток, а Chromium-подписчики – пользу от AV1. В 2026 году мульти-кодек simulcast – единственный архитектурный ответ на гэп AV1 SVC в кросс-браузерных сценариях, не требующий отказаться от плюсов SVC для тех подписчиков, которым SVC доступен.

Janus реализует simulcast в плагине videoroom и добавил начальную поддержку AV1-SVC Dependency Descriptor в 2022 году (Meetecho слил работу в PR #2741); с тех пор поддержка зрелa и в 2026 году продакшен-готова для AV1 в режимах L1T2/L1T3 и частично – для spatial AV1 SVC. Плагинная модель Janus означает, что логика выбора слоёв живёт внутри janus_videoroom и конфигурируется по подписчику через request-API плагина.

Jitsi Videobridge реализует temporal-aware пересылку для VP8 simulcast ещё с до-Octo-времён: bridge выбирает самый низкий temporal-слой, удовлетворяющий ограничениям подписчика. Bridge также поддерживает VP9 SVC; AV1 пришёл вместе с работой по dependency descriptor в libwebrtc, но в типовом деплое Jitsi Meet, по умолчанию использующем VP8 simulcast ради кросс-браузерной стабильности, AV1 пока менее валидирован в продакшене, чем VP8 simulcast.

Pion – это WebRTC-библиотека, а не SFU, но она несёт протокольные примитивы (RTP header extensions, парсер AV1 Dependency Descriptor, RTCP feedback messages), нужные SFU на её базе для слой-aware пересылки. ion-sfu и LiveKit (построенный на Pion) ставят сверху уже саму логику выбора слоёв.

Параллельно: что пишет publisher

// Simulcast на стороне publisher (работает на любом кодеке во всех браузерах)
const sender = pc.addTransceiver(track, {
  direction: 'sendonly',
  sendEncodings: [
    { rid: 'q', maxBitrate: 150_000,  scaleResolutionDownBy: 4 },   // 180p
    { rid: 'h', maxBitrate: 500_000,  scaleResolutionDownBy: 2 },   // 360p
    { rid: 'f', maxBitrate: 1_500_000, scaleResolutionDownBy: 1 },  // 720p
  ],
}).sender;

// SVC на стороне publisher (VP9 или AV1)
const sender = pc.addTransceiver(track, {
  direction: 'sendonly',
  sendEncodings: [
    { scalabilityMode: 'L3T3_KEY', maxBitrate: 1_500_000 },
  ],
}).sender;

Simulcast явно перечисляет три encodings с rid и scale-фактором; SFU видит три потока. SVC просит одно encoding с scalabilityMode; SFU видит один поток с встроенными метаданными слоёв. Прикладной код у SVC проще – цена этого в ограничении по кодекам.

Полоса, качество и реальный продакшен-trade-off

При одинаковом целевом качестве на верхней ступени SVC съедает аплинк publisher меньше, чем simulcast, – обычно на 10–25%, в зависимости от кодека и контента. При одинаковом CPU publisher SVC кодирует сопоставимый объём пикселей с чуть меньшей сложностью, чем три независимых simulcast-кодирования. Стоимость на стороне SFU широко сопоставима: оба решения – это пересылка на уровне RTP-пакетов, и зрелый SFU обрабатывает оба примерно одинаковой CPU/поток.

Вторая сторона ведомости – устойчивость. Simulcast устойчив к смерти слоя: если 720p ломается на мгновение из-за всплеска CPU на publisher, 360p и 180p продолжают работать, и SFU продолжает их пересылать. SVC менее устойчив к тому же сбою: если ломается верхний spatial-слой, зависимые enhancement-кадры становятся недекодируемыми, и короткий глюк может тянуться дольше из-за стопора в графе зависимостей. Вариант L3T3_KEY спроектирован именно чтобы смягчить это – его keyframe-структура отвязывает нижние spatial-слои от верхних, что делает переключение слоёв чище и восстановление после сбоя – быстрее.

Латентность переключения качества тоже разная. У simulcast переключение требует нового keyframe'а на целевом слое; в худшем случае SFU шлёт PLI и ждёт следующий принудительный keyframe от publisher. У SVC переключение на более низкий слой по сути бесплатно (дропаем верхние пакеты, декодируем остаток), тогда как переключение на более высокий нуждается в восстановлении цепочки зависимостей, что L3T3_KEY делает практичным без полного round-trip по keyframe'у publisher.

Продакшен-паттерн 2026 года для большинства команд: simulcast по умолчанию, SVC там, где покрытие кодеков это позволяет, и мульти-кодек fallback ради Safari-publisher'ов. Цахи Левент-Леви в Five WebRTC Predictions for 2026 отмечает, что в 2026 году AV1 ещё не станет доминирующим WebRTC-кодеком; VP8 и H.264 остаются рабочими лошадьми, а AV1 SVC будет расти там, где история выигрыша по полосе оправдывает дополнительную интеграционную работу. Реалистичный выход AV1 SVC на роль умолчания для кросс-браузерных publisher'ов – не ранее 2028 года, гейт – момент, когда Safari отгрузит AV1-encoder.

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

В нашей практике WebRTC, конференций, телемедицины и e-learning simulcast в VP8 остаётся кросс-браузерным умолчанием для новых сборок – особенно для продуктов с Safari-publisher'ами, где SVC рассчитывать нельзя. VP9- или AV1 SVC мы включаем в Chromium-only деплоях, в комнатах с ИИ-агентами и в broadcast-хвостах, где выигрыш по полосе двигает реальную строку затрат. Самая стабильная эксплуатационная победа во всех этих проектах – это проводка состояния UI подписчика (pin, превью, скрыто) в подсказку выбора слоёв SFU, независимо от того, какую технику использует publisher. Эта проводка регулярно срезает egress SFU на 30–60% в комнатах с большим числом мелких тайлов и работает одинаково для simulcast- и SVC-подписчиков.

Рисунок 4. Как выбирать между simulcast и SVC по-2026-му. Покрытие publisher'ов по браузерам – первый разрез; всё остальное торгуется потом.

Главное

  • Simulcast – это N независимых кодирований; SVC – одно кодирование с N вложенными слоями. Работа SFU по пересылке структурно похожа.
  • Simulcast работает на каждом WebRTC-кодеке, включая VP8 и H.264; SVC требует VP9 или AV1 для пространственных слоёв (temporal-only SVC работает везде).
  • Платит publisher в обеих техниках – 1,5–2,5× CPU у simulcast против 1,1–1,4× у SVC; стоимость на подписчике по сути нулевая.
  • Safari-гэп на encode VP9 и AV1 – причина того, что мульти-кодек simulcast (simulcast в VP8 + SVC в AV1 в одной комнате) – это продакшен-ответ 2026 года.
  • Проводка UI-состояния подписчика в подсказку выбора слоёв SFU – самая высокоокупаемая оптимизация независимо от выбранной техники.

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

CTA

  • Поговорить с инженером стриминга – ревью архитектуры simulcast/SVC под реальный продакшен.
  • Посмотреть кейсы – конференции, телемедицина и e-learning в портфолио Фора Софт.
  • Скачать чек-лист simulcast vs SVC – одностраничный PDF: side-by-side, scalabilityMode по кодекам и дерево решений 2026. Скачать (PDF)

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

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