Содержание статьи +
- TL;DR
- Почему это важно
- Что такое HLS – в одном абзаце
- Двухуровневая модель плейлистов
- Как на самом деле выглядит m3u8-файл
- Форматы сегментов: MPEG-TS, fMP4, CMAF
- 30 тегов, которые имеют значение, сгруппированные по задаче
- Multivariant-плейлисты и лестница битрейтов
- Live HLS: скользящее окно
- Типичная ошибка: codec-строка
- Почему HLS по-прежнему принадлежит Apple
- Почему остальные вендоры всё равно реализуют HLS
- Прохождение по live-плейлисту строка за строкой
- Где здесь Фора Софт
- Главное
- Что почитать дальше
- Призыв к действию
Опубликовано: 2026-05-21 · Время чтения: 22 мин · Автор: Николай Сапунов, CEO Фора Софт
Проверено: 2026-05-21 – по IETF RFC 8216 (HTTP Live Streaming, август 2017), draft-pantos-hls-rfc8216bis-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) и кладёт всё на обычный веб-сервер. Плеер запрашивает плейлист, читает, какие сегменты есть и где они лежат, скачивает их по порядку и склеивает в непрерывное видео. Всё. Любой другой тег, атрибут или тонкость в спецификации – это надстройка для адаптивного битрейта, нескольких аудио, субтитров, шифрования, обновлений в эфире, врезки рекламы и trick play. Но базовая механика – «забери текстовый файл, в котором указаны маленькие медиа-файлы».
Протокол появился в 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, – который накладывает нормативные требования поверх RFC для контента, который должен играть на iPhone, iPad, Apple TV и Mac. На практике вы читаете оба: IETF-документ – про то, чем HLS является, документ Apple – про то, каким HLS должен быть, чтобы попасть на устройства Apple.
Двухуровневая модель плейлистов
В HLS два вида плейлистов, и почти любая путаница про HLS в продакшене сводится к тому, что человек забыл, какой уровень перед ним.
Multivariant-плейлист (Apple переименовал бывший master playlist в multivariant playlist в ревизии 2023-04, потому что один и тот же контент доставляется в множестве форм, а не от одного «мастера») перечисляет все варианты одной единицы контента. Вариант – это одна комбинация битрейта видео, разрешения, аудиодорожки, кодеков и, опционально, субтитров. Типичный фильм имеет один multivariant-плейлист, который указывает на 4–7 видеовариантов, 3–5 аудио-рендишнов и 1–2 дорожки субтитров. Multivariant-плейлист сам по себе не содержит медиа. Это меню.
Media-плейлист перечисляет фактические сегменты для одного варианта. Если multivariant-плейлист указывает на видеовариант 1080p H.264, у него есть отдельный media-плейлист, и в этом media-плейлисте идёт список файлов сегментов 1080p по порядку с указанием длительности каждого. Плеер сначала скачивает multivariant-плейлист, выбирает вариант по полосе и размеру экрана, потом скачивает его media-плейлист и начинает тянуть сегменты. Когда меняется сеть, плеер может переключиться на другой вариант – скачать другой media-плейлист и продолжить с него.
Два плейлиста не обязаны жить на одном хосте и в одном пути. Многие продакшен-стеки отдают multivariant-плейлист с одного origin, а media-плейлисты – с другого: origin пакетайзера для меню, edge CDN для сегментов. Эта развязка и позволяет HLS масштабироваться: multivariant-плейлист маленький и почти не меняется, сегменты огромные и меняются каждые несколько секунд, и кэшировать их можно с совершенно разными политиками.
Как на самом деле выглядит m3u8-файл
m3u8-файл – это plain text в UTF-8. Каждая строка – либо комментарий, либо тег (строка, начинающаяся на #EXT), либо URI (строка, не начинающаяся на #). Первая строка любого HLS-плейлиста – магический заголовок #EXTM3U. Только он сообщает парсеру, что перед ним именно HLS-плейлист, а не один из вариантов старого M3U-формата для аудио-плееров нулевых.
Минимальный multivariant-плейлист с тремя качествами:
#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 media-плейлиста этого варианта. BANDWIDTH – пиковый битрейт варианта. AVERAGE-BANDWIDTH – долгосрочный средний. RESOLUTION и FRAME-RATE задают геометрию. CODECS – формальная codec-строка: avc1.64001f означает H.264 High Profile, level 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 в двадцати строках. Всё остальное – детали.
Форматы сегментов: 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, что вдвое уменьшает хранение и egress 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-only MPEG-TS и как CMAF-fMP4 одновременно. Путь MPEG-TS: 1 × 5 Мбит/с × 3 600 с ÷ 8 ≈ 2,25 ГБ файлов .ts плюс отдельные 2,25 ГБ DASH-сегментов .m4s, если параллельно нужен DASH, – итого 4,5 ГБ. Путь CMAF: один набор .m4s, используемый и HLS, и DASH, около 2,18 ГБ всего. На каталоге в 10 000 часов при стоимости S3 примерно $0,023 за ГБ-месяц разница – около $530 в месяц, и это ещё до egress CDN.
30 тегов, которые имеют значение, сгруппированные по задаче
Спецификация HLS описывает несколько десятков тегов. На практике пятнадцать из них несут 90% смысла в обоих плейлистах. Сгруппируйте их по задаче, и протокол станет гораздо понятнее.
Идентичность плейлиста и версия. #EXTM3U – маркер HLS. #EXT-X-VERSION:N – минимальная версия протокола, нужная парсеру; поднимайте её, когда добавляете тег, требующий более новой версии. #EXT-X-INDEPENDENT-SEGMENTS – подсказка, что каждый сегмент декодируется самостоятельно (важно для ABR и seek). #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-плейлиста: предобъявляет ключи, чтобы плеер мог получить их заранее, ещё до выбора варианта.
Теги 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.
| Вариант | Разрешение | Видеобитрейт | Кодек | Когда плеер выбирает |
|---|---|---|---|---|
| 1 | 416 × 234 | 200 кбит/с | H.264 Baseline | Слабая 3G, перегруженный публичный Wi-Fi |
| 2 | 640 × 360 | 400 кбит/с | H.264 Baseline | Медленный 4G, слабый Wi-Fi |
| 3 | 768 × 432 | 800 кбит/с | H.264 Main | Средний 4G |
| 4 | 960 × 540 | 1,6 Мбит/с | H.264 Main | Сильный 4G, базовый домашний интернет |
| 5 | 1280 × 720 | 3,0 Мбит/с | H.264 High | Стандартный домашний интернет |
| 6 | 1280 × 720 | 4,5 Мбит/с | H.264 High | Сильный домашний интернет (премиум 720p) |
| 7 | 1920 × 1080 | 6,0 Мбит/с | H.264 High | Быстрый интернет, большой экран |
| 8 | 1920 × 1080 | 8,0 Мбит/с | H.265 Main | Та же аудитория, файлы примерно на 30% меньше |
| 9 | 3840 × 2160 | 16 Мбит/с | H.265 Main10 | 4K-устройство, гигабитный интернет |
Таблица 2. Современная HLS-лестница для OTT-live-события 2026 года. H.264 несёт нижние ступени совместимости, H.265 (HEVC) – премиум-уровни, где экономия ~30% битрейта уже реальна.
Поверх структурных правил Apple HLS Authoring Specification накладывает нормативные требования:
- Соседние варианты в лестнице должны различаться по 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". Плеер параллельно скачивает media-плейлист выбранного видеоварианта и media-плейлист выбранного аудио-рендишна и синхронизирует их по EXT-X-PROGRAM-DATE-TIME.
Live HLS: скользящее окно
Для прямого эфира плейлист не конечен. Энкодер выпускает новый сегмент каждые TARGETDURATION секунд, дописывает его в media-плейлист и (обычно) удаляет самый старый, чтобы длина плейлиста оставалась ограниченной. Получается скользящее окно из 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 с:
- Энкодер 6 секунд формирует файл сегмента, пока он не появился целиком. Glass-to-сегмент-готов: 6 с.
- Энкодер заливает сегмент в origin. Origin-CDN: обычно 200–500 мс.
- Опрос плейлиста плеером происходит не чаще чем раз в 6 с, в среднем – каждые 3 с. Средняя пауза до того, как плеер заметит новый сегмент: 3 с.
- Плеер скачивает сегмент с CDN. На 5 Мбит/с по типичному интернету – около 500 мс.
- Плеер копит два сегмента в буфере перед воспроизведением, чтобы переварить вариативность сети. 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 секунд. Минимум задержки определяется тройкой: длительность сегмента, мультипликатор буфера, частота обновления плейлиста – три ручки, тянущие в одну сторону.
Типичная ошибка: codec-строка
Самая частая причина, по которой корректно закодированный 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, level 4.0), а энкодер на самом деле выдал видео level 4.1. iOS играет, потому что Safari терпимый; декодеры Android отбраковывают вариант на стадии capability-check и никогда его не скачивают. Пользователь на Android видит только нижние варианты. Исправление: либо привести codec-строку к фактическому энкоду (правильный путь), либо использовать hvc1.1.6.L120.90 и дать устройству самому решить.
Вторая частая ошибка – вообще пропустить CODECS. Apple HLS Authoring Specification требует его на каждом варианте. Некоторые пакетайзеры 2018 года всё ещё отдают плейлисты без него. Тогда плеер не знает, что собирается декодировать, может выбрать неправильный вариант, может упасть без понятной ошибки и просто пропустит вариант на устройствах, где правило соблюдается строго.
Третья частая ошибка – avc1. и mp4a. для потока HEVC + AC-3. Codec-строка обязана совпадать с фактическими сегментами. Несовпадение – гарантированное «играет на моём Mac, не играет на Roku пользователя».
Почему HLS по-прежнему принадлежит Apple
HLS – Informational-документ 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 hole-punching, никакого диапазона портов, никакого пер-зрительского состояния соединения на origin.
Это текст. Multivariant-плейлист читается человеком; media-плейлист читается человеком. Отладка фриза в проде начинается с curl и заканчивается ре-энкодом плюс однострочным фиксом.
Это везде. Каждый современный браузер, каждый smart TV (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. DRM через FairPlay, Widevine, PlayReady по CENC. Врезку рекламы через EXT-X-DATERANGE и SCTE-35. Trick play через I-frame-only варианты. Live, VOD и event-режим – в одном формате.
Итог: HLS – это пол, на котором стоит любой современный OTT-стек. Даже если продукт основной доставкой выбирает DASH (например, Netflix за пределами Apple-экосистемы), он параллельно отдаёт HLS для iOS, AirPlay и Apple TV – отдельным multivariant-плейлистом, тянущим те же CMAF-сегменты. Этим одним предложением и обоснован весь CMAF: один набор файлов, два плейлиста, все устройства закрыты.
Прохождение по live-плейлисту строка за строкой
Ниже – реальной формы live HLS media-плейлист в виде, как он выглядел бы на второй минуте эфира. Каждая строка прокомментирована.
#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-плейлист v9+ с target duration 4 с и partial-сегментами по 0,5 с. Скользящее окно начинается с сегмента 300. Сегменты 300 и 301 завершены и идут как целые файлы; сегмент 302 для текущего обновления уже в прошлом и показан и как восемь срезов EXT-X-PART (так его видел плеер, подключившийся раньше – пока сегмент формировался), и как завершённый #EXTINF:4.000. Сегмент 303 в процессе: два part уже готовы и перечислены, третий объявлен через preload hint. Две строки EXT-X-RENDITION-REPORT сообщают плееру, насколько продвинулись соседние 720p и 1080p плейлисты, чтобы переключение не требовало их повторной выгрузки.
Плеер, подключающийся к этому стриму, выберет вариант из multivariant-плейлиста, заберёт этот media-плейлист, прыгнет на EXT-X-PART сегмента 303, чтобы поставить голову воспроизведения как можно ближе к live, и начнёт параллельно тянуть следующий part по preload-подсказке. Задержка glass-to-glass – около 2 секунд.
Где здесь Фора Софт
Фора Софт с 2009 года поставляет продукты на HLS на каждое устройство Apple и не-Apple, которое имеет значение, – телемедицинские стримы, которые обязаны играть на больничных iPad, OTT-live на Apple TV, Roku, Tizen и webOS параллельно, AR/VR-companion-стримы за CMAF-пакетайзером, e-learning-каталоги с многоязычным аудио через группы EXT-X-MEDIA. Команды доставки поддерживают референс-лестницы HLS для live и VOD и CMAF-first пакетинг-пайплайн, выдающий HLS и DASH из одного origin. Когда заказчик выпускает видеопродукт в iOS App Store и одновременно в одну из smart-TV-экосистем, ответ почти всегда один: один CMAF-пакетайзер, один multivariant-плейлист на рынок, один баг – когда сломается.
Главное
- HLS – это список маленьких файлов, описанный текстовым плейлистом; всё остальное – детали поверх.
- Multivariant-плейлист – меню вариантов; у каждого варианта свой media-плейлист с реальными сегментами.
- Форматы сегментов: MPEG-TS (наследие), fMP4 (современный), CMAF (профиль fMP4, расшаренный с DASH).
- Пятнадцать тегов несут 90% смысла; группируйте их по задаче (идентичность, сегмент, шифрование, multivariant, live, low-latency, метаданные).
- Корректная строка CODECS и хорошо расставленная лестница битрейтов – два самых выигрышных решения для совместимости и поведения ABR.
- Apple владеет HLS на практике: IETF-документ – информативный, Apple HLS Authoring Specification – нормативная для отгрузки на устройства Apple.
Что почитать дальше
- LL-HLS подробно: parts, preload hints, blocking reload, rendition reports – шесть механизмов, которые превращают обычный HLS в задержку 2–5 секунд.
- CMAF: формат пакетинга, объединивший HLS и DASH – почему один набор файлов теперь обслуживает оба протокола.
- Дерево протоколов доставки – где HLS среди восьми протоколов доставки 2026 года.
Призыв к действию
- Поговорите с инженером по стримингу – принесите пример m3u8-файла, список целевых устройств и цель по задержке. Разберём плейлист и лестницу за 30-минутный звонок.
- Посмотрите наши кейсы – OTT, телемедицина, e-learning, AR/VR, видеоконференции, видеонаблюдение. HLS лежит в основе слоя доставки в большинстве из них.
- Скачайте HLS multivariant-чек-лист (PDF) – одна страница: пятнадцать важных тегов, разобранный multivariant-плейлист, формат codec-строки. Печатайте на стену.