Звук в HLS, DASH и CMAF: как плеер на самом деле выбирает аудиодорожку

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

Опубликовано: 5 июня 2026 · Время чтения: 21 мин · Автор: Николай Сапунов, CEO Фора Софт

Кратко

Когда видео транслируется в интернете, плеер загружает небольшой текстовый файл – манифест, – в котором перечислены все доступные аудиодорожки. Выбор нужной дорожки осуществляет сам плеер, а не сервер. В HLS от Apple аудиодорожки объединяются в именованную «группу рендиций» с помощью тегов EXT-X-MEDIA, и каждое качество видео ссылается на ту группу, которую может использовать; в MPEG-DASH каждый язык или конфигурация каналов представлен отдельным AdaptationSet, содержащим несколько битрейтных Representation. CMAF – это универсальный формат файлов, совместимый с обоими стандартами, поэтому один и тот же набор аудиосегментов может использоваться одновременно в манифесте HLS и манифесте DASH. Большинство ошибок типа «приложение включило не тот язык» и «не могу переключиться на surround» возникает не из-за самих аудиофайлов, а из-за того, как заданы эти группировки и их флаги DEFAULT / AUTOSELECT / Role.

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

Если вы транслируете видео по запросу или в прямом эфире в браузер, на телефон, смарт-ТВ или приставку, плеер автоматически выбирает аудиодорожку для зрителя в каждой сессии – и управлять этим выбором можно только через манифест. Эта статья предназначена для менеджера продукта, основателя или операционного руководителя без опыта в стриминге, который хочет понять, почему испаноязычный зритель получил английский звук, почему дорожка 5.1 так и не появилась или почему рекламная вставка нарушила синхронизацию – и обсудить эти вопросы с инженерами. К концу статьи вы сможете прочитать аудиочасть манифеста HLS или DASH, назвать тег, отвечающий за выбор дорожки по умолчанию, и узнать, какие ошибки в оформлении манифеста вызывают самые частые жалобы пользователей. Каждое правило основано на официальной спецификации – спецификации HLS, ISO/IEC 23009-1 для DASH, ISO/IEC 23000-19 для CMAF, – а не на интерпретации от вендоров.

Одна идея, объясняющая всё: выбирает плеер

Начнём с модели, на которой построена вся остальная статья. В стриминговом видео сервер не передаёт зрителю выбранную аудиодорожку. Вместо этого он публикует меню – небольшой текстовый файл, называемый манифестом, – а плеер на устройстве зрителя читает его и решает, что скачивать. Звук, который вы слышите, выбирает код, работающий на телефоне или телевизоре, по правилам, которые вы задали в манифесте неделями раньше.

Это противоположность телефонному звонку, где живое согласование выбирает кодек для обеих сторон, и скачанному файлу, где звук – просто то, что внутри. Стриминговый манифест больше похож на ресторанное меню с отмеченной «рекомендацией шефа»: кухня перечисляет все блюда, помечает одно как выбор по умолчанию, отмечает некоторые как доступные по запросу, а посетитель – здесь плеер – делает окончательный выбор. Если в меню рекомендация указана не на то блюдо, каждый посетитель, который не выбирает сам, получит не то. Запомните: почти каждая ошибка выбора звука – это ошибка вёрстки меню.

В открытом интернете 2026 года доминируют два формата манифеста. HTTP Live Streaming (HLS) от Apple использует плейлист в виде построчного текстового файла. Dynamic Adaptive Streaming over HTTP (DASH) от MPEG применяет XML-документ под названием Media Presentation Description, или MPD. Эти форматы описывают один и тот же контент на разных языках, и одна и та же библиотека медиафайлов – упакованная как CMAF, о котором мы поговорим в конце, – может описываться одновременно и тем, и другим.

Рис. 1. Сервер публикует меню, плеер выбирает. Одну и ту же библиотеку сегментов CMAF можно описать и плейлистом HLS, и MPD DASH одновременно; плеер читает тот формат, который поддерживает его платформа, и выбирает нужную аудиодорожку.

Как HLS описывает звук: группы рендиций

В HLS меню верхнего уровня называется мультивариантным плейлистом (в старых документах – master playlist). Он выполняет две функции: перечисляет уровни качества видео и альтернативные аудиодорожки. Аудиодорожки описываются тегом EXT-X-MEDIA, и ключевой приём, обеспечивающий работу HLS, заключается в том, что эти дорожки объединяются в именованный набор – группу рендиций.

Группа рендиций – это просто метка. Все аудиодорожки с одинаковым значением GROUP-ID относятся к одной группе. Каждый уровень качества видео, обозначенный тегом EXT-X-STREAM-INF, имеет атрибут AUDIO, указывающий, из какой группы он может брать звук. Видео как бы говорит: «для своей дорожки используй любой элемент из группы с именем aac-stereo». Такая косвенность позволяет плееру менять качество видео вверх и вниз в зависимости от состояния сети, при этом продолжая воспроизводить выбранный язык.

Вот минимальный мультивариантный плейлист с тремя языковыми дорожками в формате стерео- AAC и двумя разрешениями видео:

#EXTM3U
#EXT-X-VERSION:7

# --- группа рендиций "aud-aac" ---
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud-aac",NAME="English",LANGUAGE="en",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2",URI="audio/en/main.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud-aac",NAME="Spanish",LANGUAGE="es",DEFAULT=NO,AUTOSELECT=YES,CHANNELS="2",URI="audio/es/main.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud-aac",NAME="Commentary",LANGUAGE="en",DEFAULT=NO,AUTOSELECT=NO,CHANNELS="2",URI="audio/commentary/main.m3u8"

# --- варианты видео, оба ссылаются на одну аудиогруппу ---
#EXT-X-STREAM-INF:BANDWIDTH=2200000,CODECS="avc1.640028,mp4a.40.2",AUDIO="aud-aac"
video/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=6000000,CODECS="avc1.640028,mp4a.40.2",AUDIO="aud-aac"
video/1080p.m3u8

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

DEFAULT помечает дорожку, которую плеер должен выбрать, когда пользователь не выразил предпочтения. Обычно ровно одна дорожка в группе помечена DEFAULT=YES; здесь это английский. AUTOSELECT помечает дорожки, на которые плеер вправе переключиться сам, чтобы удовлетворить системную настройку – например, если язык устройства испанский, плеер может сам выбрать испанскую дорожку, хотя по умолчанию стоит английский, потому что у испанской AUTOSELECT=YES. У дорожки комментария AUTOSELECT=NO, что значит: плеер никогда не должен выбирать её автоматически; зритель обязан запросить её по имени. Атрибут CHANNELS указывает число каналов – "2" для стерео, – а дорожка 5.1 несла бы CHANNELS="6".

«Ловушка – две дорожки с DEFAULT=YES или ни одной. Самая частая ошибка при работе со звуком в HLS – пометить более одной дорожки в группе как DEFAULT=YES или вообще не пометить ни одной. Спецификация допускает не более одной дорожки по умолчанию на группу; если их две – разные плееры разрешают конфликт по-разному: одни выбирают первую, другие – последнюю, третьи ориентируются на язык устройства – и зрители сталкиваются с непредсказуемым поведением воспроизведения. Помечайте ровно одну DEFAULT=YES на группу, а выбор остальных оставьте на усмотрение AUTOSELECT и LANGUAGE.»

Почему surround обычно получает свою группу

Стерео и surround 5.1 – это не просто две дорожки в одном списке. Спецификация авторинга HLS от Apple прямо требует разделять звуковые дорожки с разным числом каналов на отдельные группы, каждая со своими атрибутами AUDIO у соответствующих вариантов видео. Причина – бюджет битрейта: дорожка 5.1 требует значительно больше бит, чем стереодорожка, поэтому группа 5.1 привязывается к высокобитрейтным версиям видео, а стереогруппа – к более лёгким. Если поместить стерео 192 kbit/s и surround 640 kbit/s в одну группу, плеер сможет сопоставить тяжёлую аудиодорожку с лёгким видео и нарушить баланс битрейта, который гарантируют варианты.

Практическая форма – две группы, aud-aac-stereo и aud-ac3-51, и каждый вариант видео указывает соответствующую аудиогруппу в зависимости от уровня битрейта. Сам компромисс по битрейту мы подробно разбираем в статье аудио-лестницы адаптивного битрейта.

Как DASH описывает звук: AdaptationSet и Representation

DASH передаёт ту же информацию, но в другом контейнере. Его манифест, MPD, представляет собой XML-документ, а медиафайлы в нём организованы в три уровня, которые необходимо хранить отдельно.

Period – это отрезок таймлайна: основной фильм – один Period; вставленная рекламная пауза обычно – другой Period. Внутри Period находятся AdaptationSet, которые группируют взаимозаменяемые версии одного и того же компонента. В каждом AdaptationSet содержатся Representation – непосредственно закодированные файлы с разными битрейтами. Важное правило для звука: каждый язык и каждая отдельная конфигурация каналов получают свой AdaptationSet. Английское стерео – один AdaptationSet; испанское стерео – другой; английский 5.1 – третий. Внутри AdaptationSet с английским стерео может быть три Representation на 96, 128 и 192 кбит/с, и плеер переключается между ними в зависимости от качества сети – это аудиоаналог изменения разрешения видео.

<Period>
  <!-- Английское стерео: один AdaptationSet, три битрейтных Representation -->
  <AdaptationSet contentType="audio" lang="en" audioSamplingRate="48000">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
    <Representation id="en-96"  codecs="mp4a.40.2" bandwidth="96000"/>
    <Representation id="en-128" codecs="mp4a.40.2" bandwidth="128000"/>
    <Representation id="en-192" codecs="mp4a.40.2" bandwidth="192000"/>
  </AdaptationSet>

  <!-- Испанское стерео: отдельный AdaptationSet -->
  <AdaptationSet contentType="audio" lang="es" audioSamplingRate="48000">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="alternate"/>
    <Representation id="es-128" codecs="mp4a.40.2" bandwidth="128000"/>
  </AdaptationSet>

  <!-- Английский авторский комментарий -->
  <AdaptationSet contentType="audio" lang="en" audioSamplingRate="48000">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="commentary"/>
    <Representation id="comm-96" codecs="mp4a.40.2" bandwidth="96000"/>
  </AdaptationSet>
</Period>

DASH заменяет флаги HLS DEFAULT / AUTOSELECT дескриптором Role. Элемент Role со значением value="main" выполняет роль DEFAULT=YES в HLS: он помечает основную дорожку. value="alternate" помечает вторичную дорожку, например, другой язык; value="commentary" – комментарии; value="dub" – дублированную дорожку; value="description" – аудиоописание для незрячих зрителей, о котором мы пишем в многоязычном и описательном звуке. Атрибут lang указывает язык, как и LANGUAGE в HLS.

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

ЗадачаHLSDASH
Сгруппировать один логический выбор звукагруппа рендиций (GROUP-ID)AdaptationSet
Одна битрейтная версия этого звукаMedia Playlist (URI)Representation
«Играй это, если нет предпочтения»DEFAULT=YES<Role value="main">
«Можешь сам выбрать под настройку»AUTOSELECT=YES<Role value="alternate"> + lang
Тег языкаLANGUAGE="es"lang="es"
Число каналовCHANNELS="6"audioChannelConfiguration / отдельный set
Не выбирать сам; пусть просит пользовательAUTOSELECT=NO<Role value="commentary">
Отрезок таймлайна (например, реклама)discontinuity / отдельный плейлистотдельный Period

Таблица 1. Соответствие понятий звука в диалектах HLS и DASH. Источник: спецификация HLS (атрибуты EXT-X-MEDIA) и ISO/IEC 23009-1:2022 (AdaptationSet, Representation, Role).

«Ловушка – surround и стерео в одном AdaptationSet. Как и в HLS, плееры DASH не должны переключаться между разными конфигурациями каналов внутри одного AdaptationSet, а рекомендации DASH-IF предполагают размещение стерео и 5.1 в отдельных set. Если поместить стерео- и 5.1-Representation в один AdaptationSet, плеер, адаптируясь под пропускную способность, может посреди сцены переключиться с surround на стерео – это звучит так, будто комната вдруг сжалась до передних колонок. Разделяйте конфигурации каналов: пусть плеер один раз выберет раскладку, а затем адаптирует битрейт уже внутри неё.»

CMAF: один набор файлов для обоих манифестов

Пока HLS и DASH воспринимались как два отдельных мира – и исторически так и было: сервису, желавшему поддерживать оба формата, приходилось дважды упаковывать аудио, что удваивало объём хранилища и расходы на CDN. Common Media Application Format, стандартизированный как ISO/IEC 23000-19, положил конец этому дублированию для большинства современных сервисов.

CMAF – это не третий манифест. Это формат файлов медиасегментов, на которые ссылаются манифесты. CMAF определяет медиа как фрагментированный MP4 – то же семейство ISO base media file format, что разбиралось в звуке в контейнерах, – построенный так, что один физический набор аудио- и видеосегментов может использоваться одновременно в плейлисте HLS и MPD DASH. Вы кодируете и храните звук один раз; над ним вы пишете два небольших текстовых манифеста. Байты на CDN общие.

CMAF объединяет альтернативные кодировки в CMAF Switching Set – набор дорожек, которые можно переключать и склеивать на границах фрагментов. Именно так организуются дорожки группы рендиций в HLS или Representation в AdaptationSet DASH. Все дорожки одного switching set должны иметь одинаковые ограничения по кодированию и упаковке, чтобы декодер не сталкивался с разрывами, которые он не сможет обработать при смене битрейта. Базовой единицей переключения является CMAF Fragment, а CMAF Chunk – это более мелкий фрагмент, используемый для снижения задержки, что особенно важно для стриминга с низкой задержкой.

Одна тонкость, на которую стандарт обращает особое внимание, – режим шифрования. Common Encryption в CMAF предлагает две схемы: cenc (AES в режиме счётчика) и cbcs (AES в режиме CBC с шаблонным шифрованием). На платформах Apple HLS требует cbcs. Презентация CMAF должна использовать одну схему целиком – смешивать cenc и cbcs в одной презентации нельзя. Если нужно, чтобы одна библиотека CMAF поддерживала и плеер HLS (которому нужен cbcs), и устаревший плеер DASH, зашифрованный по cenc, приходится снова упаковывать дважды – поэтому большинство сервисов, полностью перешедших на CMAF, стандартизируются на cbcs, чтобы хранить одну зашифрованную копию. Правило для звука простое: выбирайте cbcs и шифруйте один раз.

Рис. 2. Switching set CMAF объединяет версии одной аудиодорожки с разными битрейтами так, что плеер может переключаться между ними на любой границе фрагмента без щелчков. Шифрование cbcs применяется один раз ко всему набору – и HLS, и DASH используют одни и те же байты.

Как плеер на самом деле решает – алгоритм выбора по шагам

Сложите всё вместе – и решение плеера превращается в короткую и предсказуемую последовательность. Точный порядок может немного отличаться между плеерами, но логика остаётся одинаковой: iOS AVPlayer, ExoPlayer на Android, Shaka Player, hls.js и dash.js.

Сначала плеер читает манифест и находит аудиогруппу (HLS) или аудио-AdaptationSet (DASH). Во-вторых, проверяет, задал ли пользователь или приложение явное предпочтение звука для этой сессии – «играй на испанском», «включи комментарий». Если да и подходящая дорожка есть – побеждает она, точка. В-третьих, при отсутствии явного выбора плеер смотрит на язык и локаль системы устройства; если дорожка совпадает и ей разрешён автовыбор (AUTOSELECT=YES в HLS, Role alternate-или-main с совпадающим lang в DASH), он берёт её. В-четвёртых, не найдя совпадения по языку, он откатывается к дорожке по умолчанию (DEFAULT=YES / Role=main). В-пятых, выбрав какую дорожку, он затем выбирает, с какого битрейта начать, и адаптируется вверх-вниз по мере изменения сети – но не меняет язык или раскладку каналов при этом.

Отсюда два следствия, объясняющих большинство обращений в поддержку. Зритель в Мексике, чей телефон настроен на испанский язык, услышит испанский звук только если вы пометили испанскую дорожку AUTOSELECT=YES тегом LANGUAGE="es"; если же тег указан неверно – он получит английский по умолчанию. А зритель никогда не сможет выбрать дорожку 5.1, если вы забыли назначить высокобитрейтным версиям видео группу AUDIO, включающую рендеринг 5.1: surround-дорожка есть в библиотеке, но недоступна в меню.

Рис. 3. Порядок решения плеера: явный выбор пользователя, затем совпадение по языку устройства, если дорожку можно автовыбрать, затем дорожка по умолчанию. Язык и раскладка каналов выбираются один раз; дальше адаптируется только битрейт.

Разбор с числами: во сколько обходятся несколько дорожек

Числа делают компромисс осязаемым. Возьмём 90-минутный фильм, представленный на трёх языках в формате стерео- AAC, плюс одна дорожка 5.1 surround на языке оригинала. Стерео- AAC – 128 кбит/с, 5.1 E-AC-3 – 384 кбит/с. Арифметика для одной полной копии каждой дорожки:

Длительность         = 90 мин = 5 400 секунд
Размер стереодорожки = 128 kbit/s ÷ 8 × 5 400 с = 86 400 kbit ÷ 8
                     = 86 400 килобайт ≈ 86,4 МБ на язык
Три стереоязыка      = 3 × 86,4 МБ ≈ 259 МБ
Surround-дорожка 5.1 = 384 kbit/s ÷ 8 × 5 400 с ≈ 259 МБ
Итого звук (по одному битрейту) ≈ 259 МБ + 259 МБ ≈ 518 МБ

Эти 518 МБ соседствуют с видеофайлом объёмом в несколько гигабайт, так что звук занимает лишь малую часть хранилища. Однако его объём умножается с каждым новым языком и уровнем битрейта, который вы добавляете. А на популярном контенте трафик CDN оплачивается за каждый гигабайт при каждом просмотре. С CMAF вы платите за хранение один раз и обслуживаете клиентов HLS и DASH из одного источника; без CMAF – приходится платить дважды. Полную модель хранения и CDN, включая рекомендации по отключению редко используемых языковых дорожек, мы описываем в статье хранилище и арифметика CDN для звука.

Многопериодный DASH и ловушка вставки рекламы

Самые трудные ошибки звука в стриминге возникают на стыке Period. Вспомните, что вставка рекламной паузы – это обычно отдельный Period DASH. Аудио-AdaptationSet основного контента и аудио-AdaptationSet рекламы описываются независимо, и ничто не гарантирует их совпадение. Если основной контент предлагает английский, испанский и комментаторскую дорожку, а рекламный Period содержит лишь одну непомеченную английскую дорожку, плеер, дойдя до рекламы, не найдёт испанскую дорожку, которую слушал зритель, – и либо замолчит, либо переключится на английский, либо, в худших реализациях, вообще не запустит рекламу.

Тот же класс проблем возникает в HLS через EXT-X-DISCONTINUITY – тег, обозначающий точку разрыва, где могут измениться тайминг и кодирование. Звук, до разрыва чистый 48 кГц стерео-AAC, может смениться рекламой в 44,1 кГц – и изменение частоты дискретизации заставляет плеер переинициализировать аудиодекодер, что приводит к щелчкам, провалам и рассинхрону губ. Решение – строгость на этапе упаковки: каждый Period и каждый сегмент в пределах discontinuity должны иметь одинаковую структуру аудиодорожек – те же языки, те же роли, ту же частоту дискретизации, те же конфигурации каналов – чтобы плеер сохранил выбор пользователя при переходе через разрыв, не запрашивая его повторно. Серверная вставка рекламы, согласующая параметры кодирования с аудиоконфигурацией основного контента, – это решение на уровне производства.

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

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

Мы создаём продукты OTT и прямого эфира, где аудиоменю – это то, что делает продукт успешным, а не провальным с однозначными отзывами вроде «не тот язык» или «нет surround». В стриминговых проектах – видео по запросу, e-learning, прямые трансляции – дефекты звука, с которыми нас просят разобраться, почти никогда не связаны с аудиофайлами напрямую, а вызваны ошибками в манифесте: пропущенный AUTOSELECT, surround-дорожка, недоступная в высокобитрейтных вариантах, рекламный период, AdaptationSet которого не соответствует основному контенту. Мы стандартизируем клиентов на CMAF с cbcs, чтобы одна упакованная библиотека обслуживала и HLS, и DASH, и тестируем логику выбора на реальных плеерах iOS, Android и ТВ, а не на десктопных браузерах – ведь плееры по-разному интерпретируют неоднозначные манифесты. Правильно собрать меню один раз и проверить его на целевых устройствах – это предотвращает целую категорию жалоб.

Главные выводы

  • Аудиодорожку выбирает плеер, а не сервер – на основе манифеста, который вы подготовили.
  • HLS объединяет дорожки в группы рендиций; варианты видео ссылаются на группу через AUDIO.
  • DASH размещает каждый язык и конфигурацию каналов в отдельный AdaptationSet.
  • В каждой группе – ровно одна дорожка по умолчанию: DEFAULT=YES в HLS, Role=main в DASH.
  • CMAF позволяет одной библиотеке с cbcs обслуживать как HLS, так и DASH.
  • Большинство ошибок «не тот язык» и «отсутствует surround-звук» – следствие некорректной верстки манифеста.
  • Рекламные Period должны повторять структуру аудио основного контента, иначе язык будет сброшен.

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

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

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