HLS подробно: m3u8, сегменты и multivariant-плейлисты

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

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

Проверено: 2026-05-21 – по IETF RFC 8216 (HTTP Live Streaming, август 2017), draft-ietf-pantos-hls-22 (HTTP Live Streaming 2nd Edition, май 2026), Apple HLS Authoring Specification for Apple Devices, ревизия 2025-09, ISO/IEC 23000-19:2024 (CMAF), сессии WWDC 2025 «What's new in HTTP Live Streaming» и отчёту Bitmovin Video Developer Report 2025/26.

TL;DR

HLS – HTTP Live Streaming, протокол, который Apple представила в 2009 году, а IETF стандартизировала как RFC 8216 и продолжает развивать в виде draft-pantos-hls-rfc8216bis-22 (май 2026). Он передаёт видео в виде текстового файла со списком коротких медиафайлов. Плеер скачивает этот текстовый файл, читает список и последовательно загружает медиафайлы по обычному HTTP. Сам текстовый файл называют плейлистом m3u8, медиафайлы – сегментами, а верхний уровень плейлиста, перечисляющий все качества одного и того же видео, – multivariant-плейлистом. В 2026 году HLS по-прежнему обеспечивает около 45% часов прямых трансляций и большую часть минут VOD в публичном интернете, потому что он масштабируется так же, как обычные веб-файлы (любой кэш, любой CDN, любой прокси уже умеет его раздавать) и нативно воспроизводится на всех устройствах Apple, а на остальных – с помощью небольшой JavaScript-библиотеки. Цель этой статьи – сделать каждую строку m3u8-файла понятной для вас, чтобы в следующий раз, когда инженер скажет: «плеер не выбирает нужный рендишн», вы знали, какой тег проверять и какое значение искать.

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

Почти любой разговор о видеопродукте рано или поздно упирается в файл m3u8, и те, кто умеет его читать, решают проблемы быстрее остальных. Продакт, разбирающийся в multivariant-плейлисте, отвечает на вопросы о совместимости с устройствами и структуре битрейтов, не отвлекая инженеров. Новый разработчик, читающий media-плейлист, отлаживает фриз по трём тегам, не подключая дебаггер. Нетехнический основатель, понимающий, что такое сегмент, анализирует счёт CDN и задаёт правильные вопросы про cache-hit ratio. HLS – это ещё и протокол, который вы поставляете, даже если не говорите, что «поставляете HLS»: App Store отклоняет приложения, транслирующие видео по сотовой сети без использования HLS. LL-версия HLS – стандарт low-latency на устройствах Apple, а каждый CDN предлагает «live streaming» в первую очередь как HLS. Понимание HLS – это входной билет в осмысленный разговор о современной доставке видео.

Что такое HLS – в одном абзаце

HLS – это протокол доставки видео в виде списка небольших файлов через тот же HTTP, что используется для всего остального веб-контента. Продюсер кодирует видео, разбивает его на фрагменты длительностью 2–6 секунд – это сегменты – и создаёт текстовый файл со списком этих сегментов в правильном порядке. Этот файл называется media-плейлист и имеет расширение .m3u8. Все файлы размещаются на обычном веб-сервере. Плеер запрашивает плейлист, определяет, какие сегменты доступны и где они находятся, скачивает их по очереди и объединяет в непрерывный видеопоток. Всё. Любой дополнительный тег, атрибут или особенность спецификации – это уже расширение для таких функций, как адаптивный битрейт, поддержка нескольких аудиодорожек, субтитров, шифрования, динамических обновлений, вставки рекламы и режимов перемотки. Но базовая логика остаётся простой: «получи текстовый файл, в котором перечислены небольшие медиафайлы».

Протокол появился в Apple в 2009 году, а в том же году был передан в IETF в виде Internet-Draft и стал Informational RFC 8216 в августе 2017 года. RFC 8216 – каноническая опорная точка, однако протокол продолжает развиваться в серии Internet-Draft, которые в трекере IETF помечены как draft-pantos-hls-rfc8216bis-NN. Актуальная ревизия на момент написания – draft-22 от 1 мая 2026 года; при утверждении она формально заменит RFC 8216 и опишет версию 13 протокола. Параллельно Apple ведёт живой документ – HLS Authoring Specification for Apple Devices, ревизия 2025-09, – который накладывает дополнительные нормативные требования к контенту, предназначенному для воспроизведения на iPhone, iPad, Apple TV и Mac. На практике приходится опираться на оба документа: IETF-спецификацию – чтобы понять, чем является HLS, и документ Apple – чтобы понять, каким должен быть HLS, чтобы корректно воспроизводиться на устройствах Apple.

Двухуровневая модель плейлистов

В HLS существует два типа плейлистов, и почти все проблемы с HLS в продакшене возникают из-за того, что человек забывает, с каким уровнем он работает.

Multivariant-плейлист (Apple в ревизии 2023-04 переименовал бывший master playlist в multivariant playlist, поскольку один и тот же контент теперь доставляется в множестве форм, а не исходит от единого «мастера») перечисляет все варианты одной единицы контента. Вариант – это комбинация битрейта видео, разрешения, аудиодорожки, кодеков и, при необходимости, субтитров. Типичный фильм имеет один multivariant-плейлист, который ссылается на 4–7 видеовариантов, 3–5 аудиорендов и 1–2 дорожки субтитров. Сам по себе multivariant-плейлист медиа не содержит – он выполняет роль меню.

Media-плейлист содержит список сегментов для одного конкретного варианта. Если в multivariant-плейлисте указан видеовариант 1080p H.264, для него существует отдельный media-плейлист, в котором по порядку перечислены файлы сегментов 1080p с указанием длительности каждого. Плеер сначала загружает multivariant-плейлист, выбирает подходящий вариант на основе скорости соединения и размера экрана, затем скачивает соответствующий media-плейлист и начинает воспроизводить сегменты. При изменении сетевых условий плеер может переключиться на другой вариант – загрузить новый media-плейлист и продолжить воспроизведение с того же места.

Два плейлиста не обязаны находиться на одном хосте и в одном пути. Многие продакшен-стеки раздают multivariant-плейлист с одного origin, а media-плейлисты – с другого: origin пакетайзера для меню, edge CDN для сегментов. Именно такая развязка позволяет HLS масштабироваться: multivariant-плейлист небольшой и почти не меняется, сегменты – большие и обновляются каждые несколько секунд, а кэшировать их можно по совершенно разным политикам.

Рис. 1. Двухуровневая модель плейлистов. Multivariant – меню вариантов. У каждого варианта свой media-плейлист со списком сегментов.

Как на самом деле выглядит m3u8-файл

m3u8-файл – это обычный текст в кодировке UTF-8. Каждая строка может быть либо комментарием, либо тегом (строкой, начинающейся с #EXT), либо URI (строкой, не начинающейся с #). Первая строка любого HLS-плейлиста – это магический заголовок #EXTM3U. Именно он позволяет парсеру отличить HLS-плейлист от одного из вариантов старого формата M3U, использовавшегося в аудиоплеерах начала 2000-х.

Минимальный мультиязычный плейлист с тремя качествами:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-INDEPENDENT-SEGMENTS

#EXT-X-STREAM-INF:BANDWIDTH=1280000,AVERAGE-BANDWIDTH=1100000,RESOLUTION=640x360,CODECS="avc1.64001f,mp4a.40.2",FRAME-RATE=25
360p/playlist.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=3200000,AVERAGE-BANDWIDTH=2900000,RESOLUTION=1280x720,CODECS="avc1.640020,mp4a.40.2",FRAME-RATE=25
720p/playlist.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=6400000,AVERAGE-BANDWIDTH=5800000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2",FRAME-RATE=25
1080p/playlist.m3u8

Читаем сверху вниз. Строка #EXTM3U объявляет файл HLS-плейлистом. #EXT-X-VERSION:6 задаёт минимальную версию протокола, которую должен поддерживать парсер. #EXT-X-INDEPENDENT-SEGMENTS – подсказка плееру, что каждый сегмент можно декодировать независимо от предыдущего; это важно для ABR-переключений и trick play. Далее идут три строки #EXT-X-STREAM-INF, каждая из которых описывает один из вариантов, а сразу за ней – URI медиа-плейлиста этого варианта. BANDWIDTH – пиковый битрейт варианта, AVERAGE-BANDWIDTH – долгосрочный средний. RESOLUTION и FRAME-RATE задают геометрию. CODECS – формальная строка кодека: avc1.64001f означает H.264 High Profile, уровень 3.1; mp4a.40.2 – AAC-LC. По этим строкам плеер определяет, сможет ли декодер устройства воспроизвести этот вариант, ещё до начала его загрузки.

Media-плейлист выглядит иначе. Вот соответствующий 720p/playlist.m3u8:

#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init.mp4"
#EXTINF:6.000,
segment_00001.m4s
#EXTINF:6.000,
segment_00002.m4s
#EXTINF:6.000,
segment_00003.m4s
#EXTINF:4.480,
segment_00004.m4s
#EXT-X-ENDLIST

#EXT-X-TARGETDURATION:6 – ни один сегмент в списке не превышает шести секунд (округление до целого). #EXT-X-MEDIA-SEQUENCE:0 – у первого сегмента в списке номер ноль; для VOD значение остаётся неизменным, для live оно увеличивается при каждом обновлении. #EXT-X-PLAYLIST-TYPE:VOD – плейлист является конечным и больше не будет изменяться. #EXT-X-MAP:URI="init.mp4" – init-сегмент с конфигурацией кодека (этот тег появляется только для fMP4 / CMAF, но не для MPEG-TS). Далее идут пары #EXTINF + URI: длительность очередного сегмента и путь к его файлу – каждая на отдельной строке. Последняя строка #EXT-X-ENDLIST сообщает плееру, что плейлист больше не будет расширяться.

Вот и весь HLS – в двадцати строках. Всё остальное – детали.

Рис. 2. Анатомия минимальной пары HLS-плейлистов. Слева – multivariant-плейлист, справа – media-плейлист одного варианта; каждый тег снабжён аннотацией.

Форматы сегментов: MPEG-TS, fMP4, CMAF

Сегменты содержат сами байты видео и аудио. HLS поддерживает два формата контейнеров, причём третий является профилем второго.

MPEG-TS (.ts) – наследие. Это тот же MPEG-2 Transport Stream, что используется в цифровом телевидении с 1990-х годов и имеет 188-байтную пакетную структуру, оптимизированную под вещание. Когда Apple представила HLS в 2009 году, MPEG-TS был единственным доступным вариантом. У него накладные расходы на заголовки пакетов и временные метки составляют 5–10%, и его сложно эффективно использовать в связке с DASH. Современные реализации HLS редко выбирают этот формат. Однако старые системы продолжают использовать именно его, потому что MPEG-TS воспроизводится на любом устройстве, которое когда-либо поддерживало HLS – включая самые ранние set-top box и Apple TV первого поколения.

Fragmented MP4 (.m4s или .mp4, в просторечии fMP4) официально появился в HLS в iOS 10 в 2016 году. fMP4 – это профиль ISO Base Media File Format (ISO BMFF, ISO/IEC 14496-12). Структура: небольшой init-сегмент (атом moov) и серия медиа-сегментов (пары moof + mdat). Накладные расходы составляют 1–3%. Init-сегмент скачивается один раз и обозначается тегом #EXT-X-MAP; каждый последующий сегмент декодируется, пока init-сегмент остаётся в кэше плеера.

Common Media Application Format (CMAF) – стандарт 2017 года, ISO/IEC 23000-19, описывающий конкретный профиль fMP4, который можно проигрывать как в HLS, так и в DASH. CMAF-сегмент – это fMP4-сегмент с ограничениями, соответствующими требованиям DASH: одна дорожка в файле, определённые идентификаторы brand, чёткие границы чанков. Экономия очевидна: один и тот же набор файлов на диске обслуживает и HLS, и DASH, что вдвое снижает затраты на хранение и трафик CDN для контента, транслируемого в обоих форматах. К 2026 году CMAF станет доминирующим выбором для новых развертываний HLS за пределами замкнутой экосистемы Apple; каждый современный пакетайзер (Shaka Packager, AWS MediaPackage, Unified Streaming, Bento4) по умолчанию генерирует CMAF. Apple поддерживает CMAF в HLS как для H.264, так и для H.265.

Численный пример: часовой 1080p H.264-стрим на 5 Мбит/с, хранящийся одновременно как HLS-только MPEG-TS и как CMAF-совместимый fMP4. Объём по пути MPEG-TS: 1 × 5 Мбит/с × 3600 с ÷ 8 ≈ 2,25 ГБ файлов .ts плюс отдельные 2,25 ГБ DASH-сегментов .m4s, если требуется параллельная поддержка DASH – итого 4,5 ГБ. Объём по пути CMAF: один общий набор .m4s, используемый и для HLS, и для DASH, – около 2,18 ГБ. На каталоге из 10 000 часов при стоимости хранения в S3 примерно $0,023 за ГБ в месяц разница составляет около $530 в месяц – и это ещё без учёта исходящего трафика CDN.

30 тегов, которые имеют значение, сгруппированные по задаче

Спецификация HLS описывает несколько десятков тегов. На практике пятнадцать из них отвечают за 90% функциональности обоих плейлистов. Сгруппируйте их по назначению – и протокол станет гораздо понятнее.

Идентичность плейлиста и версия. #EXTM3U – маркер HLS. #EXT-X-VERSION:N – минимальная версия протокола, необходимая парсеру; её нужно повышать при добавлении тега, требующего более новой версии. #EXT-X-INDEPENDENT-SEGMENTS – указание на то, что каждый сегмент декодируется независимо (важно для ABR и функции поиска). #EXT-X-DEFINE объявляет подстановки переменных внутри плейлиста (добавлен в версии 7).

Идентичность сегмента и тайминги. #EXTINF:duration,title предшествует URI каждого сегмента и задаёт точную длительность в секундах (десятичную, а не целую). #EXT-X-TARGETDURATION:N – это верхняя граница; для VOD это просто характеристика, а для live-потока плеер не запрашивает плейлист чаще, чем раз в TARGETDURATION секунд. #EXT-X-MEDIA-SEQUENCE:N – номер первого сегмента в списке; в случае live он увеличивается при каждом обновлении. #EXT-X-DISCONTINUITY-SEQUENCE:N хранит количество разрывов, произошедших до первого сегмента в текущем списке. #EXT-X-PROGRAM-DATE-TIME:YYYY-MM-DDTHH:MM:SSZ привязывает сегмент к настенному времени – плеер синхронизирует рендеринг и внешний таймер.

Связи между сегментами. #EXT-X-MAP:URI="init.mp4" указывает init-сегмент для fMP4/CMAF; плеер загружает его один раз и использует повторно. #EXT-X-BYTERANGE:length[@offset] позволяет нескольким сегментам размещаться в одном файле в виде байтовых диапазонов – это полезно, когда нужно передать один .mp4 и дать плееру загружать его по частям. Связь #EXT-X-DISCONTINUITY между двумя сегментами сообщает плееру, что произошло фундаментальное изменение: перезапуск энкодера, рекламный блок, смена контента или splice. #EXT-X-GAP помечает пропущенный сегмент, который плеер должен пропустить.

Шифрование и DRM. #EXT-X-KEY:METHOD=AES-128,URI="key",IV=0x... указывает, что последующие сегменты зашифрованы с использованием определённого ключа и метода. Современная версия #EXT-X-KEY:METHOD=SAMPLE-AES-CTR поддерживает DRM-шифрование, применяемое в системах FairPlay, Widevine и PlayReady через фреймворк Common Encryption (CENC) по стандарту ISO/IEC 23001-7. #EXT-X-SESSION-KEY – аналогичная конструкция для мультимедийного плейлиста с несколькими вариантами: она заранее объявляет ключи, чтобы плеер мог получить их до выбора конкретного варианта.

Теги multivariant-плейлиста. #EXT-X-STREAM-INF идёт перед каждым вариантом и содержит информацию о битрейте, разрешении, кодеках и частоте кадров. #EXT-X-MEDIA объявляет альтернативный рендеринг (например, дорожку на другом языке или субтитры) и группирует его по GROUP-ID, на который ссылаются варианты. #EXT-X-I-FRAME-STREAM-INF обозначает специальный вариант «только I-кадры» для trick play (быстрой перемотки). #EXT-X-SESSION-DATA позволяет издателю прикрепить произвольные пары ключ/значение к multivariant-плейлисту (например, название шоу на нескольких языках).

Теги для live. #EXT-X-PLAYLIST-TYPE:EVENT сообщает плееру, что сегменты будут только добавляться и никогда не удаляться – плейлист постоянно растёт. #EXT-X-PLAYLIST-TYPE:VOD означает, что плейлист завершён и больше не изменяется. Отсутствие обоих тегов указывает на скользящее окно (типичный live): плейлист хранит последние N сегментов и обновляется каждые TARGETDURATION. Тег #EXT-X-ENDLIST помечает завершение любого плейлиста, который больше не должен расти.

Теги low-latency (добавлены в 2019 и в 2026 году остаются частью HLS). #EXT-X-PART объявляет partial segment – фрагмент незавершённого сегмента длиной 200–500 мс, который плеер может начать загружать ещё до завершения сегмента. #EXT-X-PRELOAD-HINT подсказывает плееру начать загружать следующий part или map ещё до появления его #EXT-X-PART. #EXT-X-RENDITION-REPORT позволяет media-плейлисту одного варианта сообщить, насколько продвинулся соседний вариант, чтобы при переключении плееру не пришлось перезагружать все плейлисты. #EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES включает блокирующий reload: плеер запрашивает playlist.m3u8?_HLS_msn=N&_HLS_part=K, и сервер держит запрос открытым, пока этот part не появится. Эти шесть механизмов превращают 30-секундный HLS в 2–5-секундный LL-HLS – подробнее в статье LL-HLS подробно.

Метаданные и реклама. #EXT-X-DATERANGE:ID=...,START-DATE=...,DURATION=...,SCTE35-OUT=... передаёт произвольные in-band метаданные, чаще всего метки SCTE-35 рекламных блоков, перетранслированные из бродкаст-фидов. #EXT-X-SKIP – механизм дельта-плейлистов: сервер может отправить сокращённый плейлист, пропустив целый диапазон старых сегментов по номерам последовательности, поскольку клиент уже их получил.

УровеньТегиЗадача
Идентичность#EXTM3U, #EXT-X-VERSION, #EXT-X-INDEPENDENT-SEGMENTS, #EXT-X-DEFINEПометить файл, задать версию протокола, дать подсказки парсеру
Сегмент#EXTINF, #EXT-X-TARGETDURATION, #EXT-X-MEDIA-SEQUENCE, #EXT-X-PROGRAM-DATE-TIME, #EXT-X-MAP, #EXT-X-BYTERANGE, #EXT-X-DISCONTINUITY, #EXT-X-GAPОбъявить и локализовать собственно медиа
Шифрование#EXT-X-KEY, #EXT-X-SESSION-KEYСвязать DRM и AES с загрузкой сегмента
Multivariant#EXT-X-STREAM-INF, #EXT-X-MEDIA, #EXT-X-I-FRAME-STREAM-INF, #EXT-X-SESSION-DATAОписать варианты, рендишны, trick play
Live#EXT-X-PLAYLIST-TYPE, #EXT-X-ENDLISTСказать плееру, растёт ли плейлист, скользит ли он или закончен
Low-latency#EXT-X-PART, #EXT-X-PRELOAD-HINT, #EXT-X-RENDITION-REPORT, #EXT-X-SERVER-CONTROL, #EXT-X-PART-INFСнизить задержку с 30 с до 2–5 с
Метаданные#EXT-X-DATERANGE, #EXT-X-SKIPМетки рекламы, дельты, произвольные метаданные

Таблица 1. HLS-теги, имеющие значение, сгруппированные по задачам. Запомните правую колонку – и большинство вопросов в продакшене сводятся к одному: «Какая строка?»

Multivariant-плейлисты и лестница битрейтов

Смысл multivariant-плейлиста – в адаптивном битрейте. Плеер выбирает начальный вариант, измеряет пропускную способность на первых сегментах и при необходимости переключается на более высокий или низкий уровень в зависимости от изменений в сети. Сам алгоритм протокол не определяет – это задача плеера, и подробности его работы рассмотрены в статьях про ABR блока 5. HLS задаёт лишь структуру меню, из которого плеер делает выбор.

Хорошо устроенная лестница битрейтов под HLS в 2026 году выглядит примерно как в таблице ниже. Конкретные числа – синтез из per-title-лестницы Netflix, рекомендаций Apple в HLS Authoring Specification и распределения полос, которое каждый год меряют Bitmovin и Conviva.

ВариантРазрешениеВидеобитрейтКодекКогда плеер выбирает
1416 × 234200 кбит/сH.264 BaselineСлабая 3G, перегруженный публичный Wi-Fi
2640 × 360400 кбит/сH.264 BaselineМедленный 4G, слабый Wi-Fi
3768 × 432800 кбит/сH.264 MainСредний 4G
4960 × 5401,6 Мбит/сH.264 MainСильный 4G, базовый домашний интернет
51280 × 7203,0 Мбит/сH.264 HighСтандартный домашний интернет
61280 × 7204,5 Мбит/сH.264 HighСильный домашний интернет (премиум 720p)
71920 × 10806,0 Мбит/сH.264 HighБыстрый интернет, большой экран
81920 × 10808,0 Мбит/сH.265 MainТа же аудитория, файлы примерно на 30% меньше
93840 × 216016 Мбит/сH.265 Main104K-устройство, гигабитный интернет

Таблица 2. Современная HLS-лестница для OTT-стрима 2026 года. H.264 обеспечивает совместимость на нижних ступенях, H.265 (HEVC) – на премиум-уровнях, где экономия битрейта уже составляет около 30%.

Apple накладывает нормативные требования поверх структурных правил спецификации HLS Authoring.

  • Соседние варианты в лестнице должны отличаться по BANDWIDTH не более чем в 2 раза и не менее чем в 1,5 – плееру нужен запас между ступенями, чтобы уверенно переключаться.
  • В каждом варианте обязательно должны быть указаны RESOLUTION, FRAME-RATE и полная строка CODECS. Варианты без CODECS не фильтруются по возможностям устройства и игнорируются на тех, где нужный кодек отсутствует.
  • Нижний вариант должен воспроизводиться на самом слабом устройстве из целевой аудитории – для iOS это примерно 192 кбит/с суммарно на аудио и видео, H.264 Baseline 480 × 270.
  • Если вы используете HEVC-варианты, параллельно предоставьте лестницу на H.264 – старым устройствам тоже нужно что-то воспроизводить.
  • Для HDR-контента обязательно предусмотрите параллельную лестницу в SDR. Спецификация HLS определяет VIDEO-RANGE=SDR|PQ|HLG в #EXT-X-STREAM-INF, чтобы плеер мог выбирать подходящий вариант в зависимости от типа сигнала.

Тег #EXT-X-MEDIA решает задачу альтернативных рендеров одного и того же контента. Типичный многоязычный фильм содержит по одной строке #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="English",LANGUAGE="en",DEFAULT=YES,URI="audio_en.m3u8" на каждый язык, все они ссылаются на общую группу GROUP-ID="aac", и каждая строка #EXT-X-STREAM-INF указывает на эту группу через атрибут AUDIO="aac". Плеер одновременно загружает медиаплейлист выбранного видеоварианта и медиаплейлист выбранного аудиорендера и синхронизирует их по времени EXT-X-PROGRAM-DATE-TIME.

Рис. 3. Современный HLS multivariant-плейлист с 9-ступенчатой видеолестницей, трёхъязычным аудио и двухъязычными субтитрами. Аудио- и субтитровые рендишны объединены в группы `#EXT-X-MEDIA`; каждый видеовариант ссылается на свои группы через `GROUP-ID`.

Live HLS: скользящее окно

Для прямого эфира плейлист не имеет конца. Энкодер каждые TARGETDURATION секунд создаёт новый сегмент, добавляет его в медиаплейлист и (как правило) удаляет самый старый, чтобы длина плейлиста оставалась ограниченной. В результате получается скользящее окно из N сегментов, которое постепенно сдвигается вперёд по времени.

Типичный live-плейлист в любой момент содержит 6–12 сегментов: трёх-четырёхкратная величина target duration обеспечивает плееру достаточный буфер для компенсации сетевых задержек, не требуя при этом хранения более минуты недавнего контента. Плеер опрашивает плейлист не чаще одного раза в TARGETDURATION (или в EXT-X-PART-INF для LL-HLS), считывает новое значение EXT-X-MEDIA-SEQUENCE, скачивает новые сегменты и удаляет те, что вышли за пределы начала плейлиста.

Механика live HLS без LL-HLS даёт задержку glass-to-glass 15–45 секунд. Возьмём target duration 6 с:

  1. Энкодер формирует сегмент за 6 секунд, пока тот не будет готов полностью. Glass-to-сегмент-готов: 6 с.
  2. Энкодер отправляет сегмент в origin. Origin–CDN: обычно 200–500 мс.
  3. Плеер опрашивает плейлист не чаще чем раз в 6 секунд, в среднем – каждые 3 секунды. Средняя задержка до обнаружения нового сегмента плеером: 3 с.
  4. Плеер скачивает сегмент с CDN. При скорости 5 Мбит/с в типичной сети – около 500 мс.
  5. Плеер накапливает два сегмента в буфере перед началом воспроизведения, чтобы компенсировать колебания скорости сети. 2 сегмента × 6 с = 12 с буфера (обычно 1,5–3× target duration).

Итого: 6 + 0,5 + 3 + 0,5 + 12 ≈ 22 секунды glass-to-glass для стандартного HLS-эфира на 6-секундных сегментах. Уменьшаем target duration до 2 с – та же арифметика даёт около 8 секунд. Включаем LL-HLS-расширения Apple – та же арифметика даёт 2–5 секунд. Минимальная задержка определяется тремя факторами: длительность сегмента, мультипликатор буфера и частота обновления плейлиста – три параметра, влияющие в одном направлении.

Типичная ошибка: строка кодека

Самая частая причина, по которой корректно закодированный HLS-вариант не воспроизводится на конкретном устройстве, – неправильная строка CODECS. Codec-строка – это формальный идентификатор по RFC 6381 / ISO/IEC 14496-15: четырёхбуквенный код плюс профиль и уровень. Для H.264 – avc1.PPCCLL, где PP – профиль, CC – флаги ограничений, LL – уровень. Для HEVC – hvc1. или hev1. плюс профиль/tier/уровень/ограничения. Для AAC-LC – mp4a.40.2. Для Opus – opus. Для AC-3 – ac-3.

Сценарий ошибки: пакетайзер записывает CODECS="avc1.640028" в multivariant-плейлисте (H.264 High Profile, уровень 4.0), хотя энкодер на самом деле выдал видео уровня 4.1. iOS воспроизводит его, потому что Safari достаточно лоялен к таким несоответствиям; декодеры Android же отбрасывают этот вариант ещё на этапе проверки возможностей и никогда его не скачивают. В результате пользователь на Android видит только более низкие варианты. Исправление: либо привести строку кодека в соответствие с реальным уровнем энкодинга (правильный путь), либо использовать hvc1.1.6.L120.90 и позволить устройству самому выбрать подходящий вариант.

Вторая частая ошибка – полностью пропустить CODECS. Спецификация Apple HLS Authoring требует его указывать для каждого варианта. Некоторые пакетайзеры 2018 года всё ещё выдавали плейлисты без него. В этом случае плеер не знает, что именно будет декодироваться, может выбрать неподходящий вариант, упасть с непонятной ошибкой или просто проигнорировать вариант на устройствах, где это правило соблюдается строго.

Третья частая ошибка – avc1. и mp4a. для потока HEVC + AC-3. Строка кодека должна точно соответствовать фактическим сегментам. Любое несоответствие – гарантированное «играет на моём Mac, не играет на Roku пользователя».

Почему HLS по-прежнему принадлежит Apple

HLS – это информационный документ IETF, однако по сути протокол определяет Apple. Три причины.

Первая – App Store и ATS. Правила App Store требуют использования HLS для видео по сотовой сети в любом приложении, которое транслирует более десяти минут непрерывного видео. Эквивалентов для DASH или WebRTC в этом сценарии нет. Если ваше приложение работает на iOS, то ваш live-стриминг и длинные VOD-трансляции должны использовать HLS – или вообще не будут работать.

Вторая – HLS Authoring Specification – нормативный документ для устройств Apple. IETF-стандарт носит информативный характер и допускает множество форм плейлистов, которые устройства Apple не поддерживают. Чтобы контент корректно воспроизводился в AirPlay, нативном AVPlayer, на Apple TV и в Safari, следует использовать именно живую спецификацию Apple, а не IETF. Apple обновляет её 1–3 раза в год: ревизия 2023-09 убрала HTTP/2 push из LL-HLS; ревизия 2023-04 переименовала master playlist в multivariant playlist; ревизии 2024 и 2025 годов добавили рекомендации по spatial-видео.

Третья – референсная реализация живёт в Safari и AVFoundation, а публичного conformance-suite сильнее этой связки нет. Инструмент Apple mediastreamvalidator – де-факто чекер, которым индустрия пользуется перед релизом. Если плейлист прошёл mediastreamvalidator и воспроизводится в Safari – он будет работать. Если нет – никакая «корректность по спецификации» не поможет на устройствах Apple.

Практическое следствие: каждый вендор стрим-стека – Bitmovin, AWS Elemental, Mux, Wowza, Cloudflare Stream, JW Player, THEO, мейнтейнеры hls.js – сначала реализует HLS по спецификации Apple, а уже потом – по стандарту IETF. Документ IETF – это то, где вы изучаете структуру протокола; документ Apple – то, где вы узнаёте правила, чтобы успешно отгрузить продукт.

Почему остальные вендоры всё равно реализуют HLS

За пределами экосистемы Apple HLS остаётся доминирующим протоколом, который продолжает использовать индустрия, даже в тех случаях, когда DASH технически более уместен. Согласно Bitmovin Video Developer Report 2025/26, HLS занимает первое место по показателю «currently in production» среди 167 разработчиков видео из 34 стран, при этом отмечается снижение интереса к его будущему внедрению. Причины остаются прежними.

Это HTTP. Любой кэш, любой CDN, любой корпоративный прокси, любой домашний роутер могут раздавать и принимать HLS без настройки. Никакого пробивания UDP-портов, никаких диапазонов портов, никакого состояния соединения на origin для каждого зрителя.

Это текст. Multivariant-плейлист и media-плейлист читаются человеком. Отладка фриза в продакшене начинается с curl и заканчивается ре-энкодом плюс однострочным исправлением.

Это повсеместно. Каждый современный браузер, каждая smart-телевизионная платформа (Tizen, webOS, Roku, Vidaa, Android TV, Fire TV), каждый set-top box, каждая игровая консоль, каждое устройство на iOS и Android поддерживает HLS нативно или с помощью небольшой JavaScript-библиотеки – hls.js в браузерах без нативной поддержки, AVPlayer или ExoPlayer на мобильных устройствах, Shaka Player как кросс-платформенное решение.

Он обеспечивает всё, что требуется индустрии: многоязычное аудио через EXT-X-MEDIA, субтитры – через WebVTT и IMSC1, защиту контента – с поддержкой FairPlay, Widevine и PlayReady по стандарту CENC. Врезку рекламы – через EXT-X-DATERANGE и SCTE-35. Поддержку режимов перемотки – за счёт использования только I-кадров. А также объединяет в одном формате прямые трансляции, видеопозапросу и событийные потоки.

Итог: HLS – это основа, на которой строится любой современный OTT-стек. Даже если основной продукт выбирает DASH для доставки (например, Netflix за пределами Apple-экосистемы), он параллельно использует HLS для iOS, AirPlay и Apple TV – через отдельный multivariant-плейлист, ссылающийся на те же CMAF-сегменты. Именно этим одним фактом и обоснован весь CMAF: один набор файлов, два плейлиста – и все устройства покрыты.

Прохождение по live-плейлисту строка за строкой

Ниже – пример реального live HLS-медиа-плейлиста в том виде, в каком он мог бы выглядеть на второй минуте трансляции. Каждая строка сопровождается комментарием.

#EXTM3U                                          ; маркер HLS-плейлиста
#EXT-X-VERSION:9                                 ; используются LL-HLS-возможности, нужна v9+
#EXT-X-TARGETDURATION:4                          ; сегмент ≈ 4 с
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=1.0,HOLD-BACK=12.0
                                                  ; плеер может пользоваться blocking reload; якоря задержки
#EXT-X-PART-INF:PART-TARGET=0.5                  ; partial-сегменты ≈ 0,5 с
#EXT-X-MEDIA-SEQUENCE:300                        ; первый полный сегмент в списке — #300
#EXT-X-DISCONTINUITY-SEQUENCE:1                  ; один разрыв уже прошёл
#EXT-X-MAP:URI="init.mp4"                        ; init-сегмент для fMP4 / CMAF
#EXT-X-PROGRAM-DATE-TIME:2026-05-21T14:00:00.000Z; настенное время для скользящего окна
#EXTINF:4.000,
segment_00300.m4s
#EXTINF:4.000,
segment_00301.m4s
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_0.m4s",INDEPENDENT=YES
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_1.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_2.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_3.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_4.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_5.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_6.m4s"
#EXT-X-PART:DURATION=0.500,URI="segment_00302_part_7.m4s"
#EXTINF:4.000,
segment_00302.m4s
#EXT-X-PART:DURATION=0.500,URI="segment_00303_part_0.m4s",INDEPENDENT=YES
#EXT-X-PART:DURATION=0.500,URI="segment_00303_part_1.m4s"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="segment_00303_part_2.m4s"
#EXT-X-RENDITION-REPORT:URI="../720p/playlist.m3u8",LAST-MSN=303,LAST-PART=1
#EXT-X-RENDITION-REPORT:URI="../1080p/playlist.m3u8",LAST-MSN=303,LAST-PART=1

Читаем по порядку. Заголовок объявляет LL-HLS плейлист версии 9+, с целевой продолжительностью сегмента 4 секунды и частичными сегментами по 0,5 секунды. Скользящее окно начинается с сегмента 300. Сегменты 300 и 301 завершены и представлены как полные файлы; сегмент 302 уже прошёл и отображается как восемь срезов EXT-X-PART (так его видел плеер, подключившийся ранее – пока сегмент формировался), а также как завершённый #EXTINF:4.000. Сегмент 303 находится в процессе формирования: два part уже готовы и перечислены, третий объявлен через preload hint. Две строки EXT-X-RENDITION-REPORT информируют плеер о прогрессе соседних плейлистов в разрешениях 720p и 1080p, чтобы при переключении не требовалось повторное скачивание.

Плеер, подключённый к этому стриму, выберет один из вариантов из многовариантного плейлиста, загрузит соответствующий медиа-плейлист, перейдёт к сегменту 303 (EXT-X-PART), чтобы установить позицию воспроизведения максимально близко к живому эфиру, и начнёт параллельно загружать следующий part по подсказке предзагрузки. Задержка «стекло-к-стеклу» составляет около 2 секунд.

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

Фора Софт с 2009 года поставляет продукты на HLS для всех значимых устройств Apple и не-Apple – телемедицинские стримы, которые должны воспроизводиться на больничных iPad, OTT-трансляции в реальном времени на Apple TV, Roku, Tizen и webOS одновременно, AR/VR-компаньон-стримы через CMAF-пакетизатор, e-learning-каталоги с многоязычным аудио с использованием групп EXT-X-MEDIA. Команды доставки поддерживают референсные лестницы HLS для live и VOD, а также CMAF-первичный пайплайн пакетирования, выдающий HLS и DASH из одного origin. Когда клиент запускает видеопродукт в iOS App Store и одновременно в одной из экосистем smart TV, ответ почти всегда один: один CMAF-пакетизатор, один мультимедийный плейлист на рынок, одна точка отказа – когда что-то сломается.

Главное

  • HLS – это набор небольших файлов, описанных текстовым плейлистом; всё остальное – детали реализации.
  • Мультивариантный плейлист – это меню вариантов; каждый вариант имеет свой медиаплейлист с реальными сегментами.
  • Форматы сегментов: MPEG-TS (наследие), fMP4 (современный), CMAF (профиль fMP4, совместимый с DASH).
  • Пятнадцать тегов несут 90% смысла; группируйте их по назначению (идентификация, сегменты, шифрование, мультивариантность, стриминг в реальном времени, низкая задержка, метаданные).
  • Корректная строка CODECS и грамотно подобранная лестница битрейтов – два ключевых решения для совместимости и корректной работы ABR.
  • Apple фактически контролирует HLS: документ IETF носит информационный характер, а спецификация Apple HLS Authoring Specification является нормативной для публикации контента на устройства Apple.

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

Призыв к действию

  • Поговорите с инженером по стримингу – принесите пример m3u8-файла, список целевых устройств и цель по задержке. За 30 минут разберём плейлист и лестницу.
  • Посмотрите наши кейсы – OTT, телемедицина, e-learning, AR/VR, видеоконференции, видеонаблюдение. HLS лежит в основе слоя доставки в большинстве из них.
  • Скачайте HLS multivariant-чек-лист (PDF) – одна страница: пятнадцать важных тегов, разбор multivariant-плейлиста, формат codec-строки. Печатайте на стену.

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

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