Содержание статьи +
- TL;DR
- Кому и зачем это нужно
- Что на самом деле делает пакетайзер
- Где упаковка стоит в пайплайне
- Фрагменты, сегменты, чанки: три слова
- Длительность сегмента: компромисс 2 / 4 / 6
- Контейнеры: ISO BMFF, fMP4 и почему MPEG-TS уходит в прошлое
- CMAF: контейнер, объединивший HLS и DASH
- Манифесты: HLS-плейлисты и DASH MPD
- Common Encryption: зашифруй один раз – расшифруй везде
- Рынок пакетайзеров: open source
- Рынок пакетайзеров: коммерческие
- Static vs Just-in-Time: две формы развёртывания
- Рабочий пример: стоимость статической упаковки для каталога из 1 000 тайтлов
- Частая ошибка: рассинхрон keyframe и границ сегмента
- Где здесь Фора Софт
- Ключевые выводы
- Что читать дальше
TL;DR
Видеопакетайзер – это программное обеспечение, которое берёт готовый энкод (одну mezzanine-дорожку или целую лесенку вариантов битрейта) и превращает его в то, что стриминговый плеер действительно может скачать: короткие медиа-сегменты, упакованные в контейнер (в 2026 году это почти всегда fragmented MP4), текстовый манифест со списком этих сегментов (плейлист HLS .m3u8, файл DASH .mpd или оба сразу) и – для платного контента – ключи шифрования по стандарту Common Encryption (ISO/IEC 23001-7), чтобы те же сегменты могли расшифровать три разные DRM-системы. Рынок 2026 года делится на open-source инструменты – Shaka Packager от команды Google Widevine (стабильная версия 3.7.2, апрель 2026) и Bento4 от Axiomatic Systems – и коммерческие пакетайзеры, в основном серверные: Unified Origin (CodeShop), AWS Elemental MediaPackage, Wowza, Norsk (id3as), а также open-source GPAC. Доминируют две архитектуры: статическая упаковка, при которой каждый сегмент один раз записывается на диск при ингесте, и упаковка по требованию (just-in-time, JIT), генерирующая сегменты и манифесты для каждого запроса плеера на основе меньшего набора исходных MP4-файлов. Стандартом по умолчанию в 2026 году для любой платформы с более чем парой сотен тайтлов стали CMAF-сегменты, зашифрованные по схеме AES-CBC pattern cbcs, индексируемые манифестами HLS и DASH, ссылающимися на одни и те же байты на диске: «закодировал один раз, упаковал один раз, расшифровал везде».
Кому и зачем это нужно
Упаковка – самый недооценённый слой стримингового стека и тот самый, который тихо определяет, сколько вы платите за хранилище, насколько быстро сможете запустить новую платформу или устройство, и придётся ли через два года при ротации DRM перепаковывать весь каталог или достаточно просто перевыпустить ключи. Продакт-менеджер, который воспринимает упаковку как «то, что происходит после энкода», теряет ключевой рычаг влияния на баланс между затратами на хранилище и вычисления, определяющими месячный счёт за origin. Основатель, выбирающий пакетайзер без понимания различий между «static» и «JIT», сам загоняет себя в workflow, где затраты на хранилище вчетверо растут в тот день, когда каталог превышает тысячу тайтлов. Стриминговым инженерам нужна картина с другой стороны: какой пакетайзер поддерживает последний драфт LL-HLS, у кого действительно корректно реализована запись CMAF, в чём именно командная разница между Shaka и Bento4 при работе с multi-DRM CMAF VOD. Эта статья даёт обеим аудиториям одну и ту же карту – с номерами стандартов, реальными командами и арифметикой стоимости, по которой можно принимать решение.
Что на самом деле делает пакетайзер
Пакетайзер – это программа, которая читает закодированное видео и аудио, разбивает их по времени на фрагменты, называемые сегментами, упаковывает каждый фрагмент в контейнерный формат, понятный плееру, создаёт текстовый манифест, который плеер сначала читает, чтобы узнать о наличии сегментов, и – при необходимости – шифрует сегменты ключами, выданными DRM-системой. Это всё описание работы.
Удобно представить пакетайзер как продавца в гастрономе. Энкодер – это разделочный цех на кухне: он готовит длинные, полностью закодированные «бока туши», называемые mezzanine-файлами – по одному на каждое качество в bitrate-лесенке. Пакетайзер – продавец у прилавка, который режет бок на одинаковые 4-секундные порции, упаковывает каждую в фирменную бумагу (контейнер fragmented MP4), наклеивает этикетки и вывешивает прайс-лист на стену (манифест), чтобы покупатели могли заказать нужные куски в нужном качестве. Если в гастрономе есть «премиальные» отрубы по подписке, тот же продавец накладывает на каждый ломтик защитную пломбу, которую могут снять только покупатели с правильным ключом (Common Encryption). Покупатели – плееры на телефонах, в браузерах, на смарт-ТВ – никогда не видят целого бока; они получают только подписанные куски.
Три работы идут вместе: fragment, manifest, encrypt. Пакетайзер существует потому, что плеер не может обрабатывать многогигабайтный единый файл-энкод. Плееры работают с HTTP-запросами к коротким файлам, которые индексируются манифестом и опционально защищены DRM-ключом. Всё ниже – детали этих трёх процессов.
Где упаковка стоит в пайплайне
Стриминговый пайплайн до пакетайзера выглядит следующим образом. Камера или мастер-файл подаются на энкодер (FFmpeg, AWS Elemental Live, Bitmovin, NETINT, x264/x265/SVT-AV1, libvpx и т. д.). Энкодер генерирует по одному mezzanine-файлу для каждой ступени лесенки – полный набор кодировок 240p/360p/480p/720p/1080p/4K в H.264, HEVC, AV1 или VVC, каждый со своим целевым битрейтом. Эти mezzanine-файлы становятся входом для пакетайзера.
Выход пакетайзера подключается к origin – небольшому серверу (или S3-бакету за CloudFront), который хранит сегменты и отдаёт их по HTTP. За origin’ом находится content delivery network (CDN) – глобальный кеширующий слой, который один раз загружает сегмент с origin и раздаёт его зрителям с краевых узлов, расположенных рядом с их физическим местоположением. Плеер у зрителя сначала запрашивает манифест, парсит список ступеней, выбирает одну из них, а затем последовательно скачивает сегменты с ближайшего edge-узла.
Это канонический стриминговый пайплайн, описанный в Конвейер стриминга от и до. Для данной статьи важны два аспекта работы пакетайзера. Во-первых, пакетайзер – это первое звено в пайплайне, где формат выходных данных зависит от протокола, по которому зритель будет смотреть трансляцию. Энкодер выдаёт универсальный битовый поток, а пакетайзер формирует презентацию, готовую к использованию в HLS или DASH (или в обоих форматах). Во-вторых, пакетайзер – это последнее место в пайплайне, где контент остаётся открытым, прежде чем шифрование навсегда заблокирует его на диске.
Фрагменты, сегменты, чанки: три слова
Самая частая путаница в терминологии упаковки – это разница между фрагментом, сегментом и чанком. Спецификация ISO/IEC 23000-19 CMAF (2018, второе издание – 2020) даёт каждому термину точное определение, и серьёзные пакетайзеры придерживаются этих различий.
CMAF chunk – это один box moof, за которым следует один box mdat внутри fragmented-MP4. moof – это movie fragment box; он содержит метаданные о времени и таблицах сэмплов для байтов, идущих за ним. mdat – это media data box; он содержит сами закодированные сэмплы видео или аудио. Чанк – минимальная независимо декодируемая единица в CMAF, обычно один фрагмент видео, выровненный по GOP, длиной около 200 мс.
CMAF фрагмент – это один или несколько идущих подряд чанков, имеющих общий адрес относительно сегмента. Большинство production-пакетайзеров в 2026 году используют отображение один к одному – один фрагмент равен одному чанку – а сам термин «фрагмент» сохраняется в основном потому, что базовый формат ISO base media file format (ISO/IEC 14496-12) использует его.
CMAF segment – это один или несколько фрагментов, образующих адресуемую единицу, которую плеер загружает одним HTTP-запросом – обычно это 2, 4 или 6 секунд видео. Сегмент представляет собой единицу, указанную в HLS-плейлисте или в DASH MPD-таймлайне. Он начинается с keyframe, чтобы его можно было декодировать независимо от предыдущих сегментов.
Отношение такое: chunk ≤ fragment ≤ segment. В low-latency-стриминге (LL-HLS, LL-DASH) значимой транспортной единицей становится чанк: плеер запрашивает partial-сегменты, собранные из чанков по мере их поступления в живой поток, вместо ожидания полного сегмента. Во всех остальных случаях значимой единицей является сегмент.
Два следствия для инженера, собирающего шаг упаковки. Во-первых, пакетайзер обязан выровнять границы сегментов с интервалом keyframe энкодера – иначе плеер скачает сегмент, первый кадр которого – P-кадр, зависящий от данных, которых у плеера нет. Большинство production-энкодеров имеют параметр --gop-size, который читает пакетайзер; ошибка в этом выравнивании – самый частый баг при упаковке. Во-вторых, длительность сегмента определяет нижнюю границу задержки переключения. Если сегменты по 6 секунд, плеер может менять качество не чаще раза в 6 секунд; если по 2 секунды – в четыре раза чаще. Trade-off ниже.
Длительность сегмента: компромисс 2 / 4 / 6
Какой длины должен быть сегмент? Десять лет индустрия спорила об этом. Консенсус 2026 года – узкий: 4 секунды для VOD, 2 секунды для live. Для VOD-только каталогов, где приоритет – эффективность кеширования в CDN, а не скорость переключения качества, допустимы длинные сегменты (6 секунд). В live-трансляциях, где важна низкая задержка, применяются короткие сегменты – 1 секунда или меньше, включая partial-сегменты LL-HLS. Apple HLS Authoring Specification (ревизия 2025-09, §4.3.2.2) рекомендует использовать 6-секундные сегменты для стандартного HLS и partial-сегменты по 0,33 секунды для LL-HLS.
Арифметика компромисса проста.
HTTP-запросов в час на рендицию = 3600 / segment_duration
При 2 с: 1 800 запросов/час/рендиция
При 4 с: 900 запросов/час/рендиция
При 6 с: 600 запросов/час/рендицияКороткие сегменты значительно увеличивают нагрузку на origin и CDN за счёт роста числа запросов. Поскольку CDN тарифицирует как количество запросов, так и объём переданных данных, каждый дополнительный запрос напрямую влияет на итоговый счёт. Кроме того, каждый запрос несёт с собой около 500–800 байт HTTP-заголовков, что при использовании коротких сегментов приводит к неоправданному росту общего трафика.
Обратная сторона.
Задержка переключения качества ≥ segment_duration
При 2 с: минимум 2 с на ответ на изменение пропускной способности
При 4 с: минимум 4 с
При 6 с: минимум 6 с
Задержка старта ≥ segment_duration × buffer_segments
При 2 с × 3 сегмента до старта: 6 с старт
При 4 с × 3 сегмента до старта: 12 с старт
При 6 с × 3 сегмента до старта: 18 с стартПлеер должен забуферизовать достаточное количество сегментов, чтобы пережить кратковременный сбой сети, прежде чем начать воспроизведение. Типичный минимум – три сегмента. Соответственно, 6-секундный сегмент при трёх сегментах на старте даёт 18 секунд времени до первого кадра в худшем случае – поэтому VOD-платформы для мобильных пользователей в условиях нестабильного соединения обычно ограничиваются сегментами по 4 секунды, а live-платформы для спортивных трансляций – по 2 секунды.
Для low-латентного стриминга сегмент разбивается на частичные сегменты (LL-HLS, или LL-HLS) или чанки (LL-DASH / CMAF), каждый длительностью 200–333 мс. Полный сегмент по-прежнему присутствует в манифесте для клиентов, не поддерживающих LL-HLS, но клиент, осведомлённый о LL, подписывается на поступление частичных сегментов по мере их появления. Подробнее о механизмах протоколов – в статьях LL-HLS подробный разбор и LL-DASH и CMAF-чанки на практике.
Контейнеры: ISO BMFF, fMP4 и почему MPEG-TS уходит в прошлое
Контейнер – это файловый формат, в котором хранятся закодированные аудиосэмплы и метаданные, необходимые плееру для декодирования и синхронизации по времени. В 2026 году для потоковой передачи важны два семейства контейнеров.
Fragmented MP4 (fMP4), он же ISO Base Media File Format (ISO/IEC 14496-12) или ISO BMFF, – это стандартный контейнер для большинства современных медиафайлов. Файл в формате Fragmented MP4 начинается с инициализационного сегмента – ftyp (file-type box) и moov (movie box, содержит конфигурацию кодека) – за которым следуют произвольное количество пар moof/mdat (фрагменты). Файлы сегментов, создаваемые Shaka Packager, Bento4 или любым пакетайзером, поддерживающим CMAF, – это и есть fMP4-файлы. CMAF представляет собой подмножество fMP4 с дополнительными ограничениями, обеспечивающими совместимость между различными платформами.
MPEG-2 Transport Stream (MPEG-TS или .ts) – более старый контейнер, изначально разработанный для спутникового и кабельного вещания. До 2016 года HLS использовал исключительно MPEG-TS – спецификация HLS требовала .ts сегментов. Apple внедрил fMP4 в HLS с выходом iOS 10 (июнь 2016), а HEVC в рамках HLS требует fMP4 (MPEG-TS не может передавать HEVC согласно спецификации HLS). DASH в основных профилях никогда не поддерживал MPEG-TS; DASH изначально работал только с fMP4.
Почему это важно для пакетайзера? Потому что некоторые legacy-устройства всё ещё не поддерживают декодирование fMP4 HLS – старые смарт-ТВ, Apple TV на tvOS 9, отдельные медиаприставки. Пакетайзер, обслуживающий такие устройства, вынужден генерировать как MPEG-TS-, так и fMP4-варианты, что удваивает объём хранилища. Реальность 2026 года – этот сегмент устройств настолько мал, что большинство платформ полностью отказались от MPEG-TS и перешли на CMAF-fMP4, оставив MPEG-TS только на стороне контрибьюшен-пайплайна (RIST, SRT), где его структура мультиплексирования действительно оказывается полезной.
Вторая причина успеха fMP4: один и тот же fMP4-сегмент может использоваться как в HLS-манифесте, так и в DASH-манифесте. Раньше для MPEG-TS-страниц HLS и DASH одного и того же контента требовалась отдельная упаковка. А с fMP4 – особенно с CMAF, который ограничивает fMP4 настолько, чтобы и Apple, и DASH-IF согласились на общее подмножество – один и тот же набор байт подходит для обоих форматов. Объём хранилища сокращается вдвое, а частота попаданий в CDN-кэш примерно удваивается.
CMAF: контейнер, объединивший HLS и DASH
Common Media Application Format (CMAF), стандартизированный как ISO/IEC 23000-19 в 2018 году (второе издание – в 2020 году), – это формат, завершивший десятилетие дублирующихся упаковочных пайплайнов. CMAF определяет два аспекта: строгое подмножество fMP4, которому должны соответствовать все CMAF-совместимые инструменты и плееры, и набор медиа-профилей (CMAF-AVC, CMAF-HEVC, CMAF-AV1), фиксирующих выбор кодека и формата битстрима.
Самое важное следствие CMAF для инженера упаковки: один CMAF-сегмент может использоваться как в HLS-плейлисте, так и в DASH MPD. Тот же файл .m4s на диске отображается как #EXT-X-MAP + #EXTINF в HLS-плейлисте и как ссылка в <SegmentTemplate> DASH MPD. Два манифеста – один набор байт.
Для OTT-платформы с тысячей тайтлов это сразу уполовинивает хранилище. Для CDN – удваивает фактическую кеш-эффективность: зритель на iOS (HLS) и зритель на смарт-ТВ (DASH) греют один и тот же кеш-объект на edge, а не два разных.
CMAF также ограничивает историю шифрования (см. раздел Common Encryption ниже). Все CMAF-совместимые пакетайзеры и плееры поддерживают схему AES-CBC pattern cbcs – единственный режим Common Encryption, который все три крупные системы DRM (Widevine, PlayReady, FairPlay) поддерживают в текущих релизах. С использованием CMAF + cbcs один зашифрованный сегмент может быть расшифрован любой из трёх систем DRM при наличии соответствующей лицензии – впервые реализован принцип «зашифровать один раз, доставить всем».
CMAF рассмотрен отдельно: CMAF – формат упаковки, объединивший HLS и DASH. Итог для этой статьи: по умолчанию упаковка в 2026 году – это CMAF, точка, если у вас нет веской причины поддерживать устаревший MPEG-TS или вариант DASH без CMAF для определённого класса устройств.
Манифесты: HLS-плейлисты и DASH MPD
Манифест – это текстовый файл, который плеер загружает первым. Он сообщает плееру две вещи: какие рендиции существуют (multivariant playlist в HLS, MPD в DASH), и какие URL сегментов составляют каждую рендицию (media playlists в HLS, <SegmentTemplate> или <SegmentTimeline> в DASH).
HLS multivariant playlist – небольшой текстовый файл, начинающийся с #EXTM3U. Каждая рендиция описывается одной строкой #EXT-X-STREAM-INF (bandwidth, resolution, codec), за которой следует URL её media-плейлиста. Минимальный multivariant-плейлист для трёхступенчатой 1080p/720p/480p лесенки занимает 12 строк текста. Apple HLS Authoring Specification (ревизия 2025-09) определяет рекомендуемые формы и теги. Сам протокол готовится к публикации как RFC 8216bis (последний драфт draft-pantos-hls-rfc8216bis-22, 2026), который заменит RFC 8216 после финализации.
HLS media playlist описывает сегменты одной рендиции. Сначала открываются #EXTM3U, #EXT-X-VERSION:7, #EXT-X-TARGETDURATION:4, затем для fMP4-рендиции указывается #EXT-X-MAP:URI="init.mp4" (initialization-сегмент), после чего следует список пар #EXTINF:4.0 и URL-адресов сегментов. Двухчасовой фильм при длительности сегментов в 4 секунды составляет 1 800 строк сегментов.
DASH MPD (Media Presentation Description) – это XML-файл, в котором корневым элементом является <MPD>. Внутри него содержится один или несколько блоков <Period> (Period – непрерывный временной отрезок, как правило, весь контент VOD или окно трансляции в режиме live). Внутри каждого Period для каждого типа медиа (одно видео, один аудиопоток, по одному для каждого языка субтитров) размещается по одному <AdaptationSet>. Внутри AdaptationSet для каждой ступени качества определяется по одному <Representation>. Внутри каждого Representation ровно один из элементов <BaseURL>, <SegmentBase>, <SegmentList> или <SegmentTemplate> описывает способ адресации сегментов. Стандарт ISO/IEC 23009-1:2022 (пятое издание) определяет схему, а DASH Industry Forum (DASH-IF) публикует руководства по реализации, ограничивающие допустимые комбинации на практике.
Три способа адресации сегментов в DASH имеют значение для упаковки.
- <SegmentBase> – для single-segment representations: вся рендиция представляет собой один большой fMP4, а адресация фрагментов внутри осуществляется через byte-range-запросы. Подходит для VOD, когда важно минимизировать количество HTTP-запросов; используется редко.
- <SegmentList> – явный список URL сегментов. Пакетайзер записывает каждый URL в манифест. Подход многословный, но однозначный; предпочтителен при нерегулярной длительности сегментов.
- <SegmentTemplate> с плейсхолдером $Number$ или $Time$ – дефолт 2026. Пакетайзер формирует одну шаблонную строку, например media="segment-$Number$.m4s", и либо использует <SegmentTimeline> (указание времени начала и длительности для каждого сегмента), либо атрибут duration (для сегментов с фиксированной длительностью). Плеер вычисляет URL в реальном времени. Это наиболее дружественный к кешированию подход.
Для live-потока пакетайзер объединяет <SegmentTemplate> с <SegmentTimeline> – таймлайн постепенно увеличивается по мере поступления новых сегментов, а плеер периодически опрашивает MPD, чтобы узнавать о них.
<!-- Минимальный DASH MPD для одной live-видео-рендиции через SegmentTemplate -->
<MPD type="dynamic" availabilityStartTime="2026-05-23T12:00:00Z" minBufferTime="PT4S">
<Period>
<AdaptationSet contentType="video" mimeType="video/mp4" codecs="avc1.640028">
<Representation id="v1" bandwidth="3000000" width="1280" height="720">
<SegmentTemplate timescale="1000" initialization="init-$RepresentationID$.m4s"
media="seg-$RepresentationID$-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="4000" r="20"/> <!-- 20 сегментов по 4000 мс, начиная с t=0 -->
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>Два манифеста ссылаются на одни и те же fMP4-сегменты при использовании workflow CMAF. Именно в этом и заключается суть CMAF.
Common Encryption: зашифруй один раз – расшифруй везде
Если контент платный – серия Netflix, оплаченный курс, трансляция по системе pay-per-view – пакетайзер шифрует каждый сегмент с помощью content-ключа, а сервер лицензий DRM выдаёт соответствующий ключ для расшифровки авторизованным плеерам. Технический контракт между пакетайзером и плеером – это Common Encryption (CENC), стандартизированный как ISO/IEC 23001-7 (третье издание – 2016, четвёртое – 2023).
CENC определяет четыре схемы; в 2026 году в production актуальны только две.
- Схема cenc – AES-128 в режиме CTR (счётчик), применяется к полным данным образца. Изначально единственный режим, поддерживаемый Widevine и PlayReady.
- Схема cbcs – AES-128 в режиме CBC (цепочка шифрованных блоков), применяется по паттерну 1:9 (зашифровать один 16-байтовый блок, пропустить девять). Разработана для эффективной работы с аппаратными декодерами. Единственный режим, поддерживаемый Apple FairPlay.
Большую часть 2010-х cbcs был «только Apple», а cenc – «только Widevine/PlayReady». Платформам приходилось шифровать контент дважды: один раз cenc для DASH/Widevine/PlayReady, второй раз cbcs для HLS/FairPlay – и хранить обе копии. Конвергенция произошла в два этапа: Google добавил cbcs в Widevine в 2017 году, а Microsoft – cbcs в PlayReady 4.0 в 2018 году. К 2020 году все три крупные DRM-системы могли расшифровывать cbcs напрямую, и индустрия перешла к workflow с однократным шифрованием.
Дефолт 2026 года – cbcs-шифрование CMAF-сегментов, индексируемых как HLS-, так и DASH-манифестами. Один и тот же зашифрованный файл .m4s можно расшифровать на iOS (FairPlay), на Android и в Chrome (Widevine), а также в Edge и на Xbox (PlayReady) – при наличии правильного ключа. Сам ключ поступает с multi-DRM лицензионного сервера (BuyDRM, EZDRM, castLabs, Axinom, AWS Elemental MediaTailor, Mux Video DRM, Bitmovin), выдающего лицензии FairPlay, Widevine и PlayReady на основе единого content-ключа.
Одна оговорка: если целевая аудитория включает устройства Android старше версии 7.0 (август 2016), нужен cenc, а не cbcs – поддержка cbcs была добавлена в медиафреймворк Android именно в версии 7.0. К 2026 году доля устройств с версией Android ниже 7.0 в мире составит менее 0,5%; компромисс почти всегда сводится к тому, чтобы отказаться от этих устройств и выпускать только cbcs.
Шаг пакетайзера короткий. Shaka Packager, Bento4, AWS MediaPackage, Unified Origin, Wowza и GPAC поддерживают обе схемы с помощью одного флага командной строки. Настройка лицензионного сервера – отдельная, более сложная тема, см. DRM 101: почему три системы и зачем выпускать все три и отдельную статью Common Encryption (CENC) подробно.
Рынок пакетайзеров: open source
Два open-source пакетайзера доминируют на рынке. Оба – командно-строчные утилиты, оба могут использоваться как библиотеки.
Shaka Packager (разработан командой Google Widevine, MIT-лицензия, github.com/shaka-project/shaka-packager) – де-факто стандарт. Последний стабильный релиз – v3.7.2 (апрель 2026). Написан на C++. Поддерживает HLS, DASH, шифрование cenc и cbcs, интеграцию с лицензионными серверами Widevine, PlayReady и FairPlay, CMAF-выход, стримы в режиме live и VOD. Интерфейс командной строки у Shaka Packager строгий и последовательный: один аргумент stream на рендицию, один флаг – на упаковочный концепт.
Минимальный вызов Shaka Packager, который превращает видео- и аудио-mezzanine в CMAF HLS+DASH презентацию с cbcs-шифрованием:
packager \
'in=video_720p.mp4,stream=video,init_segment=v720/init.mp4,segment_template=v720/$Number$.m4s,playlist_name=v720.m3u8' \
'in=audio.m4a,stream=audio,init_segment=a/init.mp4,segment_template=a/$Number$.m4s,playlist_name=a.m3u8' \
--hls_master_playlist_output master.m3u8 \
--mpd_output stream.mpd \
--protection_scheme cbcs \
--enable_raw_key_encryption \
--keys label=video:key_id=<32-hex>:key=<32-hex>,label=audio:key_id=<32-hex>:key=<32-hex>На выходе получается структура директорий с fMP4 init-сегментами и $Number$.m4s media-сегментами, а также мультимедийный плейлист HLS (master.m3u8), отдельные медиаплейлисты HLS для каждого варианта и DASH MPD (stream.mpd). Каждый сегмент зашифрован с использованием ключа, привязанного к треку. Multi-DRM-лицензионный сервер выдаёт лицензии FairPlay, Widevine и PlayReady по переданным key ID.
Bento4 (Axiomatic Systems, GPL-лицензия для open-source ядра, отдельная коммерческая лицензия SDK, bento4.com) – более старый из двух инструментов и до сих пор широко используется в production. Высокоуровневые упаковочные утилиты – mp4dash для DASH и mp4hls для HLS – представляют собой Python-обёртки над низкоуровневыми C++ бинарниками (mp4fragment, mp4encrypt, mp42hls).
Типичный запуск Bento4 для DASH с одним видео-mezzanine на ступень:
mp4dash --output-dir=dash/ \
--hls \
--encryption-cenc-scheme=cbcs \
--encryption-key=<key_id_hex>:<key_hex> \
video_360p.mp4 video_720p.mp4 video_1080p.mp4 audio.m4aФлаг --hls говорит mp4dash также выдать HLS multivariant playlist, ссылающийся на те же fMP4-сегменты, что и DASH MPD, – это CMAF-стиль двойного выхода у Bento4. Сегменты лежат в пронумерованных поддиректориях под dash/; stream.mpd и master.m3u8 – на верхнем уровне.
Анализ Motion Spell (компания за GPAC) от 2024 года сравнил три open-source пакетайзера – Shaka, Bento4 и GPAC – на нагрузке CMAF VOD. Главный вывод: GPAC упаковал 90-минутный фильм примерно в 3 раза быстрее Shaka Packager и в 5 раз быстрее Bento4 на одном и том же оборудовании, и стал единственным, кто сгенерировал spec-совместимый CMAF без ручных правок для двух тестовых входов. Shaka остаётся выбором по умолчанию для команд, которым важна поддержка сообщества и Google; Bento4 – для тех, кто уже использует mp4-инструменты в своих пайплайнах; GPAC – для тех, кому нужна максимальная производительность или полный контроль над CMAF-чанками.
Encore Packager от Eyevinn (github.com/Eyevinn/encore-packager) – высокоуровневый сервис-обёртка вокруг Shaka Packager, обновлённая в январе 2026 года. Это не отдельный упаковочный движок – под капотом используется Shaka – но предоставляет API в стиле managed pipeline, удобное для медиа-воркфлоу, управляемых CI/CD.
Рынок пакетайзеров: коммерческие
Четыре коммерческих пакетайзера – managed-сервисы упаковки – покрывают большую часть неоткрытого программного обеспечения в продакшене.
Unified Origin (CodeShop, unified-streaming.com) – программное решение для потоковой передачи, реализующее упаковку «по требованию» на основе небольшого набора исходных fMP4-файлов («Unified» source-файлы – это фрагментированные MP4 с встроенным индексом). Unified Origin хранит на диске набор из N fMP4-файлов и динамически генерирует манифесты и сегменты в форматах HLS, DASH, MSS или HDS при каждом запросе плеера, поддерживая любую комбинацию схем шифрования. Ключевое коммерческое преимущество – операционное: один формат на диске, любой формат в эфире, с полной поддержкой multi-DRM в момент запроса.
AWS Elemental MediaPackage – управляемый сервис упаковки от AWS. Принимает один или несколько входов в форматах fMP4, HLS или DASH от MediaLive (live-энкодер AWS), упаковывает их в HLS, DASH, CMAF или Microsoft Smooth Streaming, применяет CENC-шифрование через AWS SPEKE для одной из трёх основных систем DRM и отдаёт через CloudFront. Обработка происходит just-in-time при выходе; финальные сегменты не сохраняются на S3. Оплата производится за объём исходящего трафика (в гигабайтах) и за каждую секунду работы сервиса. Именно это – одна из главных причин, по которой компании, работающие с более чем парой сотен конкурентных live-каналов, в итоге переходят на self-managed origin.
Wowza Streaming Engine – давно зарекомендовавший себя Java-стриминговый сервер, объединяющий упаковку, приём (ingest), origin и live-транскодирование в одном процессе. Wowza предоставляет собственный JIT-упаковочный пайплайн для HLS и DASH, интегрированный с партнёрами по multi-DRM. В 2026 году основная роль Wowza – enterprise-развёртывания на собственных серверах и на edge-узлах, где использование AWS невозможно (регулируемые среды, вещательные комплексы, спутниковые уплинк-сайты).
Norsk (id3as, norsk.video) – это TypeScript SDK и runtime для построения live-стриминговых пайплайнов, включая упаковку. В отличие от одноразовых CLI-инструментов вроде Shaka, Norsk представляет собой программируемый runtime, в котором разработчик соединяет узлы: ingest, transcode, package, encrypt, output. Уникальное преимущество Norsk – поддержка LL-HLS (LL-HLS) и LL-DASH, а также возможность описывать сложные live-воркфлоу (мультиязычное аудио, графика в реальном времени, динамическая вставка рекламы) с помощью кода, а не конфигурационных файлов.
Паттерн на коммерческом рынке – услуги с добавленной стоимостью сверху, а не принципиально иная упаковка. Под капотом большинство коммерческих пакетайзеров либо используют Shaka, либо реализуют те же ISO-стандарты напрямую; ключевой дифференциатор – управляемый сервисный интерфейс.
Static vs Just-in-Time: две формы развёртывания
Развёртывание упаковки основано на двух архитектурах. Выбор между ними – главный фактор, влияющий на затраты в упаковочном слое.
Статическая упаковка один раз записывает каждый сегмент на диск при ингесте. 90-минутный фильм, упакованный в шестиступенчатую лесенку, с 4-секундными сегментами, аудио на трёх языках и в форматах HLS-MPEG-TS, HLS-fMP4 и DASH-fMP4, создаёт примерно 24 000 сегментов на диск на один тайтл. На тысяче тайтлов – 24 миллиона файлов. Пакетайзер запускается один раз на тайтл (или при добавлении нового языка), после чего сегменты остаются на origin навсегда. У CDN отличная частота попаданий в кэш, поскольку URL каждого файла стабилен для всех зрителей; единственным ограничением остаётся стоимость хранения.
Just-in-time упаковка (JIT) хранит по одному fMP4-исходнику на рендицию – по шесть файлов на шестиступенчатую лесенку – и при каждом запросе плеера синтезирует сегментные файлы и записи манифеста. Пакетайзер запускается на каждый запрос. Каталог из тысячи тайтлов содержит 6 000 source-файлов (по шесть на каждый тайтл) вместо 24 миллионов сегментных файлов – это примерно ×4 000 экономии по объёму хранилища.
Trade-off – origin-compute. JIT-origin выполняет упаковочную логику в горячем пути каждого запроса плеера, каждого fetch’а сегмента. Современные JIT-оригины (Unified Origin, AWS MediaPackage, MediaPackage на Lambda) делают это эффективно – за доли миллисекунды на сегмент – но счёт за вычисления заменяет часть расходов, которые раньше покрывали затраты на хранение.
История с кешированием здесь иная. При статической упаковке URL-сегментов остаются стабильными навсегда: CDN кэширует каждый сегмент один раз и отдаёт его миллиарды раз из кеша. При JIT-подходе URL-сегменты также стабильны (JIT-источник генерирует детерминированные URL на основе исходных файлов и параметров манифеста), поэтому коэффициент попаданий в кэш CDN остаётся сопоставимым – но origin вынужден защищаться за счёт агрессивного front-кэша, поскольку промах в кэше теперь запускает процесс упаковки, а не просто чтение с диска. JIT-оригиналы почти всегда размещаются за origin shield.
Точка перелома 2026, где JIT окупается, примерно такова:
- Под 100 тайтлов: статика обычно выигрывает за счёт простоты. Стоимость хранилища не имеет значения; вы экономите на лицензировании и операциях с JIT-оригином.
- 100–1000 тайтлов: выбор зависит от частоты обновлений каталога. Если тайтлы часто добавляются или удаляются – JIT предпочтительнее, поскольку при статике требуется перепаковка для каждого нового устройства или при ротации шифрования. Если каталог стабилен – статика выигрывает за счёт простоты кэширования.
- Больше 1000 тайтлов: JIT почти всегда выигрывает по объёму хранилища. Редкие исключения – платформы с экстремальной оптимизацией cache-hit rate (например, Netflix, YouTube), которые строят собственный origin-слой и амортизируют затраты на хранилище по всему флоту.
Это каноническая разбивка; более детальное сравнение – в следующей статье: JIT-упаковка vs пре-пакетированный origin.
Рабочий пример: стоимость статической упаковки для каталога из 1 000 тайтлов
Чтобы trade-off хранилища стал конкретным, приведём арифметику для типичного OTT-сервиса, упаковывающего 1000 фильмов по 90 минут каждый с шестиступенчатой лесенкой разрешений: 1080p/720p/540p/360p/240p/144p, 4-секундными CMAF-сегментами, аудио на трёх языках и шифрованием cbcs.
Сегменты на рендеринг по титлу:
90 минут × 60 секунд / 4 с на сегмент = 1 350 видео-сегментов на рендицию на тайтлВсего видеосегментов на тайтл:
1 350 × 6 видео-рендиций = 8 100 видео-сегментов на тайтлАудиосегментов на тайтл:
1 350 × 3 аудио-рендиции = 4 050 аудио-сегментов на тайтлInit-сегментов на тайтл:
6 видео + 3 аудио = 9 init-сегментов на тайтлВсего сегментных файлов в титле:
8 100 + 4 050 + 9 = 12 159 сегментных файлов на тайтлПо каталогу из 1000 тайтлов:
12 159 × 1 000 = 12,159 миллиона сегментных файловСредний размер сегмента при H.264 с битрейтами 5/3/1,5/0,8/0,4/0,2 Мбит/с для видео (с меньшим весом для нижних ступеней в соответствии со средним паттерном просмотра) и 128 кбит/с для аудио:
Видео-байты на сегмент (среднее 720p при 3 Mbps): 3 Mbps × 4 с / 8 = 1,5 MB на сегмент
Аудио-байты на сегмент: 128 kbps × 4 с / 8 = 64 KB на сегментВсего хранилищ:
Видео: 8 100 сегментов × 1 000 тайтлов × ~1 MB ср. = ~8 TB
Аудио: 4 050 сегментов × 1 000 тайтлов × 64 KB = ~260 GB
Итого: ~8,3 TB на дискеПо тарифу S3 Standard (май 2026, US-East-1): около $0,023 за ГБ в месяц – $190 в месяц за статически упакованный каталог. Это стоимость статического workflow.
JIT-воркфлоу хранит на каждый тайтл 6 видео и 3 аудио – всего 9 исходных fMP4-файлов. Каждый из них содержит полную 90-минутную кодировку одного битрейта. Размер исходных файлов:
720p 3 Mbps × 90 минут = ~2 GB на файл
Всего на тайтл: ~6 GB по шести видео-ступеням + ~80 MB аудио = ~6,1 GB
1 000 тайтлов × 6,1 GB = ~6 TBХранилище JIT в этом примере фактически сопоставимо, потому что исходные файлы содержат те же суммарные байты. Преимущество JIT проявляется, когда платформе требуется другой упаковочный выход – новый профиль устройства (например, Android TV с иным набором поддерживаемых кодеков), смена схемы шифрования, добавление новой аудиодорожки. Статический workflow перепакует 12 миллионов файлов, тогда как JIT-workflow повторно применит упаковочную логику в момент запроса и не сохранит ничего дополнительно.
Вот суть работы JIT в одном предложении: JIT отделяет стоимость добавления выходных данных от размера каталога.
Частая ошибка: рассинхрон keyframe и границ сегмента
Самый частый баг упаковки – мы наблюдали его примерно в половине стриминговых кодовых баз, которые аудировали, – это использование энкодера с интервалом ключевых кадров, не кратным длительности сегмента. Пакетайзер, настроенный на 4-секундные сегменты, при подаче энкодера с интервалом ключевых кадров 2,5 секунды выдаёт часть сегментов, начинающихся с keyframe, и часть – без него. Сегменты без keyframe формально соответствуют стандарту fMP4, но плеер может их декодировать, только пересобрав предыдущие сегменты – что сводит на нет смысл адресуемых сегментов.
Хуже того, когда плеер меняет рендицию – например, с 1080p на 720p посреди потока – переключение может произойти только на границе сегмента, которая одновременно является границей keyframe в новой рендиции. Различие интервалов между keyframe на разных ступенях «лесенки» приводит к невидимым задержкам: плеер вынужден ждать ещё один дополнительный сегмент, прежде чем новая рендиция станет пригодной для декодирования.
Исправление – установить во всех энкодерах одинаковые закрытые GOP с длиной группы кадров, равной длительности сегмента. Для 4-секундных сегментов при 30 fps: GOP-размер = 120 кадров. При 25 fps: GOP-размер = 100. При 60 fps: GOP-размер = 240. Все энкодеры и все рендиции должны быть настроены одинаково. Shaka Packager выдаст предупреждение при обнаружении рассинхронизации; Bento4 – нет, и ошибка проявится только тогда, когда в логе плеера у пользователя появится stall при переключении.
Где здесь Фора Софт
Мы выпустили упаковочные пайплайны для OTT-платформ, систем онлайн-обучения в реальном времени, телемедицинских платформ с платным контентом и архивов видеонаблюдения, раздающих записи следователям между отделами полиции. Через все эти проекты проходит один и тот же паттерн: упаковочный слой берёт на себя большую часть операционных решений, возникающих после запуска продукта – каждое новое устройство, каждая ротация DRM, каждое требование к низкой задержке сначала попадают на пакетайзер. По умолчанию мы используем CMAF + cbcs + JIT-origin для каталогов, насчитывающих более нескольких сотен титров, и статичную упаковку CMAF через Shaka для небольших платформ с живыми событиями, где простота важнее гибкости. Полная картина кода и инфраструктуры таких стеков – в соответствующих кейсах на нашем сайте.
Ключевые выводы
- Пакетайзер разбивает закодированные mezzanine-файлы на сегменты, генерирует манифесты HLS или DASH (или оба формата) и при необходимости шифрует их с использованием Common Encryption.
- По умолчанию в 2026 году используется контейнер CMAF (ограниченный fMP4), на который ссылаются как HLS-, так и DASH-манифесты, указывая на одни и те же байты на диске.
- По умолчанию в 2026 году применяется шифрование cbcs; все три основные DRM-системы (Widevine, PlayReady, FairPlay) способны его расшифровывать при наличии корректной лицензии.
- Shaka Packager и Bento4 – ведущие open-source решения; на коммерческом рынке лидируют Unified Origin, AWS MediaPackage, Wowza и Norsk.
- При статической упаковке каждый сегмент записывается на диск заранее; при JIT-подходе сегменты генерируются по запросу. JIT становится выгоднее при количестве тайтлов свыше ~1000 или при частой смене устройств и DRM.
- Наиболее распространённая ошибка при упаковке – несоответствие границ сегментов интервалу между ключевыми кадрами (keyframe) энкодера. Исправлять нужно настройки энкодера, а не пакетайзера.
Что читать дальше
- CMAF – формат упаковки, объединивший HLS и DASH – подробное описание контейнера, обеспечивающего принцип «один сегмент – два манифеста».
- JIT-упаковка vs пре-пакетированный origin – когда JIT-упаковка окупается, а когда лучше выбрать статическую упаковку.
- DRM 101: почему три системы и зачем выпускать все три – взгляд с позиции лицензионного сервера на процесс шифрования.