MPEG-DASH: подробный разбор MPD, Periods, AdaptationSets, Representations

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

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

Последняя сверка: 2026-05-21 со стандартом ISO/IEC 23009-1:2022 (Dynamic adaptive streaming over HTTP – Part 1, пятая редакция, август 2022), DASH-IF Implementation Guidelines: Restricted Timing Model (post-community-review, 2025), DASH-IF Implementation Guidelines v4.3, ISO/IEC 23000-19:2024 (CMAF, третья редакция), ISO/IEC 23001-7:2023 (Common Encryption, четвёртая редакция), исходниками референсного плеера dash.js v5 и Bitmovin Video Developer Report 2025/26.

TL;DR

MPEG-DASH – Dynamic Adaptive Streaming over HTTP, формальное обозначение ISO/IEC 23009-1 – это международно стандартизованный аналог Apple HLS и протокол доставки по умолчанию во всех экосистемах, кроме Apple. Его манифест – XML-документ под названием Media Presentation Description (MPD), описывающий поток как четырёхуровневую иерархию: Презентация содержит один или несколько Periods (временных отрезков), каждый из которых включает один или несколько AdaptationSets (групп взаимозаменяемых дорожек одного и того же контента – например, всех видеоверсий фильма или одной аудиодорожки), каждый AdaptationSet содержит один или несколько Representations (по одной закодированной версии с фиксированным битрейтом, разрешением, кодеком и языком), а каждый Representation доставляется как последовательность Segments, чьи URL либо перечислены явно (SegmentTimeline), либо генерируются по номеру из шаблона (SegmentTemplate$Number$), либо по времени из шаблона (SegmentTemplate$Time$). DASH не зависит от кодека, контейнера и DRM: один и тот же MPD может передавать H.264 в MPEG-TS, H.265 во fragmented MP4, AV1 в CMAF-чанках, с ключами Widevine, PlayReady и FairPlay, мультиплексированными через Common Encryption. В 2026 году доминирующим не-Apple стеком станет DASH-over-CMAF с CENC, на котором работают Netflix, YouTube, Disney+, Prime Video и все крупные OTT-платформы за пределами iOS Safari.

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

Половина стримингового трафика в публичном интернете идёт через MPEG-DASH, и невозможно принять обоснованное архитектурное решение по видеопродукту, не понимая его. HLS чаще на слуху, потому что Apple поставляет его как единственный протокол, который нативно поддерживает iOS Safari, но каждое Android-устройство, каждый Smart TV на ExoPlayer или Shaka, любой браузер с поддержкой Media Source Extensions, а также каждый премиальный OTT-сервис, которому требуются три параллельные DRM-системы (Widevine для Chrome и Android, PlayReady для Edge и Xbox, FairPlay для Safari и Apple TV) – используют DASH. Формат MPD плотнее и гибче, чем m3u8-плейлист, и именно эта гибкость позволяет DASH поддерживать SCTE-35-маркеры рекламы, многопериодные live-to-VOD-окна, мульти-DRM-сигнализацию и trick-режимные дорожки, которые действительно нужны вещанию и премиальному OTT. Цель статьи – превратить MPD из непрозрачного XML-документа в текст, читаемый как проза, поведение которого можно предсказать, и в котором можно разобраться, когда плеер вдруг падает на нижнюю рендицию без видимой причины.

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

MPEG-DASH – это протокол адаптивного потокового вещания на основе HTTP, стандартизированный как ISO/IEC 23009-1 в ISO/IEC JTC 1/SC 29/WG 11 (Moving Picture Experts Group). DASH-поток состоит из двух компонентов: единого XML-описания под названием Media Presentation Description (MPD) и набора медиафайлов – Segments, передаваемых по обычному HTTP. MPD содержит информацию о временной шкале потока (начало, продолжительность, формат – live или on-demand), всех доступных закодированных версиях аудио, видео и субтитров (разрешение, битрейт, кодек, язык, поддержка доступности), способах их адресации (через URL-шаблоны или прямые ссылки) и методах защиты (идентификаторы DRM-схем и метаданные шифрования).

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

Поскольку всё взаимодействие происходит по стандартному HTTP, а протоколу безразлично, что содержится внутри сегментов, DASH автоматически наследует все преимущества HTTP-доставки – кэширование в CDN, беспрепятственное прохождение через файрволы, поддержку HTTP/2 и HTTP/3 – и не требует специальной серверной инфраструктуры, в отличие от RTMP, RTSP или WebRTC.

Краткая история с датами

MPEG-DASH не возник на пустом месте. Он стал результатом объединения трёх более ранних проприетарных HTTP-протоколов стриминга – Apple HLS (2009), Microsoft Smooth Streaming (2008) и Adobe HDS (2010) – в единый вендор-нейтральный международный стандарт.

Работа началась в 3GPP в 2009 году как Adaptive HTTP Streaming (AHS) с чёткой целью – заменить RTSP/RTSP-стриминг, который использовался в 3G-сетях. В 2010 году MPEG объявил конкурс на разработку стандарта HTTP-стриминга, получил 87 заявок и включил в итоговый документ работу 3GPP. Черновик международного стандарта был утверждён в январе 2011 года. Первая редакция ISO/IEC 23009-1 вышла в апреле 2012 года; протокол получил название MPEG-Даш. Первое прямое внедрение – трансляция VRT летних Олимпийских игр в Лондоне в августе 2012 года. В том же году был создан DASH Industry Forum (DASH-IF), который публикует профили реализации и поддерживает референсный плеер.

С момента первой публикации стандарт пересматривался четыре раза. Вторая редакция – 2014 год, третья – 2019, четвёртая – 2020, пятая (ISO/IEC 23009-1:2022) – август 2022 года. Редакция 2022 года добавила дескриптор минимально требуемой защиты вывода устройства, более гибкую сигнализацию полосы пропускания для VBR-кодирования, фреймворк Service Description, на основе которого построен low-latency-профиль DASH-IF, а также уточнила механизм MPD Patch, превращающий длинные live-MPD в инкрементальные обновления. Сегодня ISO/IEC 23009 представляет собой многочастный стандарт: Part 1 – MPD и формат сегментов; Part 4 – шифрование и аутентификация сегментов; Part 5 – Server and Network Assisted DASH (SAND); Part 8 – session-based DASH operations.

В 2017 году формат Common Media Application Format (ISO/IEC 23000-19, CMAF) стандартизировал фрагментированную упаковку в формате MP4, которую могут использовать как HLS, так и DASH – благодаря этому одни и те же медиаданные теперь обслуживают оба протокола. Третья редакция CMAF 2024 года добавила нативную поддержку AV1. Связка DASH-over-CMAF с Common Encryption – фактически стандартный стек премиальной OTT-доставки в 2026 году.

Четырёхуровневая иерархия MPD

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

MPD (вся презентация)
└── Period (отрезок времени — одна реклама, одна программа, весь VOD-актив)
    └── AdaptationSet (один тип медиа в этом Period — видео, одна аудиодорожка, субтитры)
        └── Representation (одна кодированная версия с фиксированным битрейтом / разрешением / кодеком)
            └── Segment (скачиваемый файл или byte-range, покрывающий отрезок времени)

Задача каждого уровня – сдерживать следующий.

MPD – презентация

Корневой элемент содержит атрибуты документа в целом: @type ("static" для VOD, "dynamic" для live), @profiles (идентификаторы DASH-профилей, которым соответствует манифест), @mediaPresentationDuration для статичного MPD или @availabilityStartTime для динамического, @minBufferTime (минимальный буфер плеера для непрерывного воспроизведения на максимальной заявленной полосе пропускания), @suggestedPresentationDelay для live (насколько игроку отступать от live edge) и @minimumUpdatePeriod для live (как часто плеер должен перечитывать MPD). Элемент содержит один или несколько <Period>, а также, при необходимости, элемент <ServiceDescription> с low-latency-подсказками, целевой задержкой и диапазоном допустимой скорости воспроизведения.

<MPD xmlns="urn:mpeg:dash:schema:mpd:2011"
     type="dynamic"
     profiles="urn:mpeg:dash:profile:isoff-live:2011,urn:mpeg:dash:profile:cmaf:2019"
     availabilityStartTime="2026-05-21T08:00:00Z"
     minimumUpdatePeriod="PT2S"
     timeShiftBufferDepth="PT60S"
     minBufferTime="PT2S"
     suggestedPresentationDelay="PT4S">
  <Period id="p0" start="PT0S">
    …
  </Period>
</MPD>

Эта преамбула уже сообщает плееру шесть важных деталей: это live-поток; он начался в 08:00:00 UTC; плеер должен обновлять MPD каждые 2 секунды; окно DVR составляет 60 секунд; необходим буфер минимум на 2 секунды при максимальном битрейте; рекомендуемое расстояние до live edge – 4 секунды. Плеер может спланировать сессию ещё до загрузки первого сегмента.

Период – отрезок времени

Period – это непрерывный временной отрезок внутри презентации. Все остальные элементы манифеста привязаны к Period. VOD-актив – как правило, один Period от start="PT0S" до start + duration = mediaPresentationDuration. Live-поток – обычно один Period, начинающийся с availabilityStartTime и не имеющий явного окончания. Интересный случай – multi-period: live-канал, переключающийся между основной программой и рекламной паузой; VOD-фильм с пре-, мид- и пост-роллами; 24/7-канал, меняющий параметры кодирования каждый час. Каждый из таких отрезков представляет собой отдельный Period со своим набором AdaptationSets, и плеер при переходе между ними сбрасывает текущие SourceBuffer и пересоздаёт их под новый Period – обычно с разрывом в один сегмент, во время которого пользователь видит короткую паузу.

<Period id="programme" start="PT0S" duration="PT30M">
  <!-- основная программа: видео + аудио + субтитры -->
</Period>
<Period id="ad-break-1" start="PT30M" duration="PT60S">
  <!-- 60-секундный рекламный блок, отдельно закодированный, возможно с другого origin -->
</Period>
<Period id="programme-2" start="PT31M" duration="PT30M">
  <!-- программа возобновляется -->
</Period>

В элементе Period может присутствовать <BaseURL>, который добавляет префикс ко всем URL внутри – именно так Server-Side Ad Insertion (SSAI) вставляет рекламу с внешнего ad-оригина, не изменяя при этом реальные URL рекламных сегментов. В Period также может содержаться <EventStream> для передачи сигнала SCTE-35 cue-tone, обозначения границ программ или out-of-band-метаданных. Атрибут @duration является опциональным для последнего Period в статичном MPD и запрещён для бесконечного live-Period; длительность в этом случае плеер определяет либо по start следующего Period, либо по mediaPresentationDuration.

AdaptationSet – один из типов медиа в этом Period

AdaptationSet группирует взаимозаменяемые Representations одного и того же контента. Определяющий критерий: любое Representation внутри AdaptationSet должно быть допустимой заменой любого другого в середине воспроизведения – без переинициализации decoder pipeline. Классические группировки: один AdaptationSet под видео (все видеорендиции одного источника – разные разрешения и битрейты, но один и тот же кодек, соотношение сторон и цветовое пространство), по одному на каждый аудиоязык (все битрейтовые лестницы английского аудио – в одном AdaptationSet, испанского – в другом) и по одному на каждый язык субтитров. Поток с несколькими аудиокодеками – например, AAC-LC ради совместимости и xHE-AAC для новых клиентов – это два AdaptationSet, а не один, потому что один decoder pipeline не может переключаться между ними.

AdaptationSet содержит атрибуты, общие для всех Representations внутри него: @contentType ("video", "audio", "text"), @mimeType ("video/mp4", "audio/mp4", "application/mp4" для фрагментированных MP4-субтитров), @codecs (кодековая строка по RFC 6381 – "avc1.640028" для H.264 High profile level 4.0, "hev1.2.4.L150.B0" для H.265 Main10 level 5.0, "av01.0.05M.08" для AV1), @width, @height, @frameRate, @audioSamplingRate, @lang (BCP 47 – "en", "es-MX", "ja") и один или несколько дескрипторов <Role> со значениями schemeIdUri="urn:mpeg:dash:role:2011", "main", "alternate", "caption", "subtitle", "sign", "description". Дескриптор Role позволяет плееру определить, что один из трёх английских AdaptationSet предназначен для описания видео (descriptive audio) для людей с нарушениями зрения, а не является дубляжом.

<AdaptationSet id="video" contentType="video" mimeType="video/mp4"
               codecs="avc1.640028" startWithSAP="1" segmentAlignment="true"
               maxWidth="1920" maxHeight="1080" maxFrameRate="30" par="16:9">
  <Representation id="v0" width="1920" height="1080" bandwidth="6000000" />
  <Representation id="v1" width="1280" height="720"  bandwidth="3000000" />
  <Representation id="v2" width="960"  height="540"  bandwidth="1500000" />
  <Representation id="v3" width="640"  height="360"  bandwidth="800000"  />
  <Representation id="v4" width="426"  height="240"  bandwidth="400000"  />
</AdaptationSet>

@segmentAlignment="true" – это контракт: границы сегментов выровнены во всех представлениях набора. Если вы переключаетесь с v0 на v3 в конце сегмента 42, то следующий сегмент 43 в обеих версиях начинается в одно и то же мгновение по часовому времени, и плеер может склеить их без зазора. Каждый современный DASH-упаковщик по умолчанию создаёт выровненные сегменты, потому что альтернатива – четверть секунды чёрного экрана при каждом переключении.

Представление – одна закодированная версия

Representation – это одна из закодированных версий контента AdaptationSet с фиксированным битрейтом, разрешением (для видео), частотой дискретизации (для аудио) и конфигурацией кодека. Обязательные атрибуты: @id (уникальная строка внутри AdaptationSet, используемая для переключения), @bandwidth (максимальный битрейт потока в битах в секунду – плеер использует это значение, чтобы оценить, справится ли текущая пропускная способность с этой рендой), @codecs (переопределяет codec из AdaptationSet, если они различаются – редкий случай), @width / @height для видео и способ адресации сегментов (об этом – в следующей секции).

Набор <Representation> внутри AdaptationSet – это то, что неформально называют bitrate ladder. Классическая лестница в стиле Apple включает пять видеорендиций (240p / 360p / 540p / 720p / 1080p) с постепенно возрастающим битрейтом; современные подходы – per-title (отдельная лестница для каждого контента на основе анализа его сложности) или per-shot (разные сцены внутри одного контента получают лестницы разной формы). DASH одинаково описывает каждое Representation, независимо от выбранной философии.

Segment – скачиваемый файл

Segment – это единица медиа, которую плеер фактически загружает. Это фрагмент в формате fragmented MP4 (или, реже, MPEG-TS), охватывающий определённый временной отрезок – обычно 2–6 секунд для VOD и 1–2 секунды для live-трансляций. Каждый Segment может быть либо отдельным файлом с собственным URL (segments/v0/seg-42.m4s), либо диапазоном байтов внутри более крупного Indexed Single Segment, описанного в <SegmentBase>. Плеер выполняет обычный HTTP GET (или HTTP Range GET) для каждого Segment и передаёт полученные данные в SourceBuffer браузера через Media Source Extensions.

Первый байт payload сегмента – это Stream Access Point (SAP), кадр, с которого можно начать декодирование без необходимости ссылаться на более ранние кадры (например, IDR-кадр в H.264 или его аналог в других кодеках). Атрибут @startWithSAP="1" в AdaptationSet гарантирует, что каждый сегмент каждого Representation начинается с SAP – именно это делает возможным переключение ABR внутри сегмента.

Рис. 1. Четырёхуровневая иерархия MPD с проработанным примером: 90-минутный VOD-фильм, разбитый на pre-roll-рекламный Period и основной программный Period, видео и три аудиоязыка как AdaptationSets, пять видеорендиций и по одному Representation на язык, и выровненные 4-секундные сегменты снизу.

Адресация сегментов – три режима, которые нужно различать

DASH-манифест может ссылаться на свои сегменты одним из трёх способов, и выбор напрямую влияет на задержку в прямом эфире, сложность упаковки и поведение CDN. Любая статья о DASH, смешивающая эти три режима, уже со второго абзаца содержит ошибки.

Режим 1 – SegmentList

Самый простой способ – MPD перечисляет каждый URL-сегмент явно, по одному <SegmentURL> на строку, внутри <SegmentList>. Для 90-минутного фильма с 4-секундными сегментами это 1350 строк на каждое Representation, 6750 – на пятирендиционную лестницу, 27 000 – на фильм с четырьмя аудиоязыками. Манифест получается огромным, live-сценарий невозможен (пришлось бы каждый раз отправлять новый MPD с добавленными строками каждые 4 секунды), и только устаревшие VOD-энкодеры до сих пор используют такой подход. Упоминаем один раз и забываем.

Режим 2 – SegmentTemplate с $Number$

Доминирующий режим для VOD и более простой из двух режимов для трансляции в реальном времени. MPD объявляет шаблон URL, содержащий литеральный токен $Number$, а также стартовый номер и длительность между сегментами. Плеер формирует каждый URL, подставляя в $Number$ следующее целое число.

<SegmentTemplate
    media="$RepresentationID$/segment-$Number$.m4s"
    initialization="$RepresentationID$/init.mp4"
    timescale="48000"
    duration="192000"
    startNumber="1" />

Плеер видит: длительность сегмента – 192000 / 48000 = 4.0 s; сегмент 1 – по адресу v0/segment-1.m4s, сегмент 2 – по адресу v0/segment-2.m4s и так далее. Для 90-минутного фильма в манифесте нет ни одного перечисления URL – плеер вычисляет их самостоятельно. В случае live-потока плеер добавляет номер сегмента, вычисленный на основе (wall_clock_now − availabilityStartTime) / segment_duration, – поэтому атрибут availabilityStartTime является обязательным в динамическом MPD.

Шаблоны по номеру удобны для CDN: пространство URL компактное, адреса предсказуемы, ключ кэширования прост. Они не терпят переменной длительности сегментов – каждый сегмент должен строго соответствовать заявленной продолжительности, иначе плеер неправильно вычислит соответствие времени и сегментов и начнёт запрашивать ещё не существующие части. Большинство live-энкодеров решают эту проблему, жёстко фиксируя длительность сегмента и принимая вытекающие ограничения по выравниванию GOP.

Режим 3 – SegmentTemplate с $Time$ (и SegmentTimeline)

Гибкий режим. MPD объявляет шаблон с помощью $Time$, а элемент <SegmentTimeline> перечисляет записи <S>, описывающие время начала и длительность каждого сегмента в шкале времени медиа.

<SegmentTemplate
    media="$RepresentationID$/segment-$Time$.m4s"
    initialization="$RepresentationID$/init.mp4"
    timescale="48000">
  <SegmentTimeline>
    <S t="0"      d="192000" r="2" />   <!-- 3 сегмента по 4.000 s, начиная с t=0 -->
    <S            d="240000"      />   <!-- 1 сегмент 5.000 s -->
    <S            d="192000" r="9" />   <!-- ещё 10 сегментов по 4.000 s -->
  </SegmentTimeline>
</SegmentTemplate>

У <S> три атрибута: @t (время начала в единицах временной шкалы медиа, необязательно после первой записи – вычисляется как previous @t + previous @d), @d (длительность в единицах временной шкалы медиа) и @r (счётчик повторов – значение r="2" означает эта запись плюс два повторения, то есть три одинаковых сегмента). Значение r="-1" означает повторять бесконечно до следующего @t.

SegmentTimeline поддерживает сегменты переменной длительности – энкодер может укоротить сегмент, чтобы выровняться по границе вставки рекламы, или удлинить, чтобы сохранить выравнивание GOP на IDR. Манифест точно описывает оба случая. Однако его размер растёт по мере жизни live-стрима: каждый новый сегмент добавляет запись <S> или расширяет существующую @r. Поэтому существует MPD Patch (ISO/IEC 23009-1:2022, приложение M, подробно описано в DASH-IF guidelines): вместо полного перечитывания MPD каждый @minimumUpdatePeriod плеер запрашивает небольшой XML-диф, содержащий только новые записи <S>.

DASH-IF Implementation Guidelines: Restricted Timing Model рекомендует SegmentTemplate с SegmentTimeline для любого live-воспроизведения, требующего точного соответствия времени и сегментов – например, catch-up DVR, точный переход к нужному моменту (seek) или границы multi-period. SegmentTemplate с $Number$ остаётся допустимым решением для VOD и для live-трансляций, где все сегменты действительно имеют одинаковую продолжительность. Чистый SegmentList подходит только для статичного VOD и фактически устарел.

Режим адресацииЛучше всего дляПоддержка liveПеременная длительностьCDN cache keyРазмер манифеста
SegmentListLegacy VODНетДаТривиальный (URL per segment)Большой
SegmentTemplate + $Number$VOD и live с фиксированным шагомДаНетТривиальныйКрошечный
SegmentTemplate + $Time$ + SegmentTimelineDVR live, multi-period, ad-insertionДаДаТривиальныйРастёт со временем (использовать MPD Patch)
Рис. 2. Три режима адресации сегментов рядом. MPD-источник – слева; URL, которые конструирует плеер, – справа. Обратите внимание, как размер уменьшается от SegmentList (одна строка на сегмент) до SegmentTemplate+$Number$ (одна строка-шаблон на всю презентацию).

Live vs VOD – два типа презентации

Один атрибут в корне MPD – @type – переключает протокол между двумя режимами, которые плеер реализует с использованием совершенно разной логики.

Static (VOD)

type="static" объявляет записанный актив известной длины. MPD содержит @mediaPresentationDuration (общая продолжительность презентации в формате XML-duration – "PT1H30M" для девяноста минут, "PT4500S" – то же самое время в секундах). MPD остаётся неизменным. Каждый сегмент существует с момента публикации MPD. Плеер может перейти к любой точке таймлайна, запросить любой сегмент в любом порядке и при желании предзагрузить весь поток. Здесь нет @availabilityStartTime, нет @minimumUpdatePeriod, нет @timeShiftBufferDepth. Субтитры, аудиодорожки и главы могут быть более насыщенными, поскольку всё уже окончательно определено.

<SegmentTimeline> или <SegmentTemplate> статичного MPD описывает всю презентацию. Плеер вычисляет полный список URL во время парсинга и может больше не общаться с manifest-сервером, пока пользователь не уйдёт со страницы.

Динамический (в реальном времени)

type="dynamic" объявляет поток в реальном времени. Теперь MPD содержит @availabilityStartTime (момент реального времени, когда первый сегмент потока стал доступен для скачивания; всё остальное в таймлайне представления отсчитывается от него), @minimumUpdatePeriod (насколько часто плеер должен перезагружать MPD), @timeShiftBufferDepth (окно DVR – насколько плеер может отмотать назад от live edge, прежде чем сегменты перестанут быть доступны) и @suggestedPresentationDelay (насколько отступать от live edge – обычно в 2–4 раза больше длительности сегмента, но не менее 4 секунд).

Соответствие времени и номера сегмента – сердце live-формата DASH. Для манифеста с нумерованным шаблоном и availabilityStartTime="2026-05-21T08:00:00Z", startNumber="1", timescale="48000", duration="192000":

seconds_into_presentation = (now_utc - availabilityStartTime).total_seconds()
segment_duration_seconds  = 192000 / 48000 = 4.0
current_segment_number    = startNumber + floor(seconds_into_presentation / segment_duration_seconds)

В 08:00:40 UTC seconds_into_presentation = 40, current_segment_number = 1 + floor(40/4) = 11. Сегмент 11 только что стал доступен: его первый байт появился в 08:00:40, а последний – примерно в 08:00:44 с учётом задержки в одну длительность сегмента в энкодере. Плеер, соблюдающий suggestedPresentationDelay="PT4S", начал бы воспроизведение с сегмента 10, а не с 11, оставив один сегмент буфера между собой и live edge.

Динамический MPD обычно содержит дескрипторы <UTCTiming>, чтобы плеер мог синхронизировать свои часы с серверными. Без надёжного UTCTiming плееры на устройствах со сбитыми часами неправильно определяют current_segment_number и либо перебуферизуются (запрашивая несуществующие сегменты), либо отстают от live edge.

<UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-iso:2014"
           value="https://time.akamai.com/?iso" />
<UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-head:2014"
           value="https://time.akamai.com/" />

DASH-IF guidelines настаивают, что каждый динамический MPD должен нести хотя бы один <UTCTiming>. В продакшене его отсутствие – самая частая причина ситуации «у одних пользователей live-поток подвисает, у других – нет»: часы у этих пользователей дрейфуют.

Рис. 3. Модель live-тайминга в DASH. Wall-clock now – справа; availabilityStartTime – слева. suggestedPresentationDelay – расстояние от now назад до точки, с которой начинает воспроизведение плеер. timeShiftBufferDepth – DVR-окно. Сегменты, старше левого края timeShiftBufferDepth, удаляются и становятся недоступны (404).

XML-преамбула – что объявляет каждый MPD

Каждый MPD начинается с четырёх одинаковых объявлений, которые сообщают парсеру, какой документ он обрабатывает.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="static"
     mediaPresentationDuration="PT1H30M"
     minBufferTime="PT2S"
     profiles="urn:mpeg:dash:profile:isoff-on-demand:2011,urn:mpeg:dash:profile:cmaf:2019">

xmlns="urn:mpeg:dash:schema:mpd:2011" – URI пространства имён MPD-схемы. Он не изменялся с момента первой публикации ISO/IEC 23009-1 в 2012 году: пятая редакция 2022 года полностью обратно совместима на уровне XML, хотя в ней появились новые атрибуты и элементы. В URI 2011 указан год, когда MPEG зафиксировал пространство имён; не путайте его с годом выпуска редакции стандарта.

@profiles – список идентификаторов профилей через запятую, которым MPD заявляет соответствие. Два важнейших в 2026 году:

  • urn:mpeg:dash:profile:isoff-live:2011 – профиль ISOBMFF (фрагментированный MP4) для прямых трансляций. Обязателен для любого live-видео.
  • urn:mpeg:dash:profile:isoff-on-demand:2011 – профиль ISOBMFF для on-demand-контента. Обязателен для VOD.
  • urn:mpeg:dash:profile:cmaf:2019 – CMAF-профиль, утверждённый поправкой 2019 года к стандарту DASH. Манифест с этим профилем гарантирует, что каждый сегмент соответствует ISO/IEC 23000-19 (CMAF) – именно это позволяет одним и тем же медиаданным воспроизводиться как в HLS-, так и в DASH-плеерах.

@minBufferTime="PT2S" – контракт между энкодером и плеером: если плеер поддерживает буфер минимум на 2 секунды при максимальной заявленной пропускной способности, он не будет ребуферить из-за кратковременных всплесков coded-content. Атрибут обязателен в MPD. Рекомендации DASH-IF предписывают minBufferTime в пределах одной–трёх длительностей сегмента: меньшее значение заставляет плеер полагаться на мгновенную пропускную способность, а большее – неоправданно увеличивает задержку.

XML-синтаксис длительностей – PT1H30M, PT2S, PT0.5S – соответствует стандарту ISO 8601. P открывает элемент duration, T переключает с части даты на часть времени, а H / M / S обозначают часы / минуты / секунды соответственно. Десятичные дроби в секундах допускаются. Такой формат сбивает с толку инженеров, привыкших работать с миллисекундами в целых числах; чтение PT1.5S как «полторы секунды» быстро тренирует глаз.

ContentProtection – мульти-DRM в одном манифесте

Ключевая особенность DASH для премиального OTT – Common Encryption (CENC), определённая в ISO/IEC 23001-7:2023. Один и тот же зашифрованный медиаконтент может быть расшифрован с помощью Widevine, PlayReady или FairPlay – в зависимости от поддерживаемой системой защиты ключей на устройстве. При этом используется единый набор сегментов и один ключ контента. MPD указывает на это, размещая элементы <ContentProtection> внутри AdaptationSet – один для базовой схемы шифрования и по одному для каждой поддерживаемой DRM-системы.

<AdaptationSet contentType="video" mimeType="video/mp4" codecs="avc1.640028" segmentAlignment="true">
  <!-- Схема шифрования: AES-128 CTR, объявляется один раз -->
  <ContentProtection
      schemeIdUri="urn:mpeg:dash:mp4protection:2011"
      value="cenc"
      cenc:default_KID="34e5db32-8625-47cd-ba06-68fca0655a72"
      xmlns:cenc="urn:mpeg:cenc:2013" />
  <!-- Widevine: UUID DRM-системы — опубликованное Google значение -->
  <ContentProtection
      schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
    <cenc:pssh>AAAAW3Bzc2gAAAAA…(Base64 PSSH box)…</cenc:pssh>
  </ContentProtection>
  <!-- PlayReady: UUID DRM-системы — опубликованное Microsoft значение -->
  <ContentProtection
      schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95">
    <cenc:pssh>AAAAlHBzc2gAAAAA…(Base64 PSSH box)…</cenc:pssh>
    <mspr:pro xmlns:mspr="urn:microsoft:playready">…(Base64 PlayReady Object)…</mspr:pro>
  </ContentProtection>
  <Representation id="v0" width="1920" height="1080" bandwidth="6000000" />
  …
</AdaptationSet>

Первый <ContentProtection> говорит: «эти Representations зашифрованы AES-128 CTR по ISO/IEC 23001-7, и default Key Identifier – GUID 34e5db32-…». Следующие два блока объявляют две DRM-системы, имеющие лицензию на этот ключ – Widevine и PlayReady – и содержат Protection System Specific Header (PSSH) каждой системы в формате Base64. Плеер в Chrome выбирает блок Widevine, отправляет PSSH на лицензионный сервер Widevine, получает ключ и расшифровывает контент. Плеер в Microsoft Edge выбирает блок PlayReady и отправляет его на лицензионный сервер PlayReady. Те же сегменты работают в обоих случаях.

FairPlay – исключение: Apple не использует паттерн in-MPD PSSH-бокса, и контент FairPlay доставляется через HLS, а не DASH. Премиальный OTT-сервис, поддерживающий все устройства, обычно отдаёт DASH для Chrome / Edge / Firefox / Android / Smart TV (Widevine + PlayReady, иногда ClearKey для диагностики) и HLS для Safari и Apple TV (FairPlay). Профиль CMAF позволяет одним и тем же зашифрованным медиаданным обслуживать оба формата – меняется только манифест.

Официальные UUID DRM-систем публикует DASH-IF (https://dashif.org/identifiers/content_protection/). Наиболее распространённые:

DRM-системаUUID
Widevine (Google)edef8ba9-79d6-4ace-a3c8-27dcd51d21ed
PlayReady (Microsoft)9a04f079-9840-4286-ab92-e65be0885f95
FairPlay (Apple – только HLS)94ce86fb-07ff-4f43-adb8-93d2fa968ca2
Marlin5e629af5-38da-4063-8977-97ffbd9902d4
ClearKey (W3C, диагностика)e2719d58-a985-b3c9-781a-b030af78d30e

urn:mpeg:dash:mp4protection:2011 – это то, как MPD сообщает «здесь CENC»; @value – CENC-схема: "cenc" для AES-128 CTR (чаще всего используется с HEVC/AVC/AV1) или "cbcs" для AES-128 CBC с подвыборочным шаблоном (требуется Apple FairPlay и рекомендована с 2018 года).

EssentialProperty и SupplementalProperty – механизм расширения

Оба элемента имеют тип DescriptorType в схеме и оба несут @schemeIdUri, а также опциональный @value. Разница заключается в семантике обязательности: если в EssentialProperty встречается незнакомый @schemeIdUri, плеер обязан проигнорировать охватывающий элемент; если же в SupplementalProperty встречается незнакомый @schemeIdUri, он может быть проигнорирован без предупреждений. Именно такой подход позволяет DASH развиваться, не нарушая работу старых клиентов.

Реальные примеры EssentialProperty: сигнализация о том, что Representation – часть стереоскопической пары, что AdaptationSet является trick-режимной дорожкой (превью для перемотки), что Period представляет собой SCTE-35-рекламный блок, который клиент должен передать отдельному ad-серверу. Реальные примеры SupplementalProperty: объявление override соотношения сторон, блока метаданных цветового пространства или схемы упаковки кадров, которая помогает умному плееру, но не мешает более простому.

<!-- AdaptationSet с trick-mode-превьюшками — плееры, не понимающие схемы, обязаны его пропустить -->
<AdaptationSet contentType="image" mimeType="image/jpeg">
  <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
  <Representation id="tm0" bandwidth="32000" width="320" height="180">
    <SegmentTemplate media="trick/$Number$.jpg" duration="20" startNumber="1" />
  </Representation>
</AdaptationSet>

CMAF, fragmented MP4 и Segment изнутри

Тело каждого современного DASH-сегмента – это фрагментированный MP4, формально ISO Base Media File Format, ISO/IEC 14496-12, та же семья контейнеров, что и .mp4 и .mov. Фрагментированный MP4 разбивает файл на последовательность movie fragments (боксов moof), за которыми следуют их данные (боксы mdat) – по одному фрагменту на сегмент. Бокс styp (тип сегмента) в начале каждого сегмента содержит идентификатор бренда и позволяет упаковщику пометить сегмент как соответствующий определённому профилю.

CMAF – ISO/IEC 23000-19:2024, третья редакция – это ограниченный профиль fragmented MP4, который поддерживают как HLS, так и DASH. CMAF- сегмент состоит из styp + sidx (индекс сегмента для адресации по байтовым диапазонам) + moof + mdat; CMAF-чанк – это один moof и один mdat внутри сегмента, и именно эту единицу загружают плееры LL-DASH и LL-HLS при передаче по chunked HTTP. CMAF Initialisation Segment – это пара ftyp + moov, содержащая конфигурацию кодека (SPS/PPS для H.264, VPS/SPS/PPS для H.265, OBU sequence header для AV1), но без медиаданных. Плеер загружает Init Segment один раз на Representation, парсит его, настраивает декодер, а затем скачивает сегменты и передаёт их на обработку.

Обещание CMAF – один набор медиабайтов, два манифеста – определило развитие индустрии. Netflix, YouTube, Disney+, Prime Video, Hulu и HBO Max используют одни и те же CMAF-совместимые fragmented-MP4-файлы, к которым добавляются два тонких манифеста: HLS-.m3u8 для пользователей Safari и Apple TV, а DASH-.mpd – для всех остальных. Стоимость хранения снизилась вдвое, кодирования – вдвое, а тестирования (QA) – более чем вдвое. Именно CMAF сделал так, что выбор между «HLS и DASH» перестал быть вопросом упаковки и стал вопросом формата манифеста.

Проработанный пример – читаем реальный MPD строка за строкой

30-секундный фрагмент MPD делает четырёхуровневую иерархию конкретной. Приведённые ниже числа – реальные; URL-фрагменты разрешались бы относительно одного и того же источника.

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011"
     type="static"
     mediaPresentationDuration="PT1H30M"
     minBufferTime="PT2S"
     profiles="urn:mpeg:dash:profile:isoff-on-demand:2011,urn:mpeg:dash:profile:cmaf:2019">
  <BaseURL>https://cdn.example.com/movie-42/</BaseURL>
  <Period id="main" duration="PT1H30M">
    <!-- 5-рендиционная H.264 видеолестница, CMAF-чанки, 4-секундные сегменты -->
    <AdaptationSet id="video" contentType="video" mimeType="video/mp4"
                   codecs="avc1.640028" segmentAlignment="true" startWithSAP="1"
                   maxWidth="1920" maxHeight="1080" frameRate="24" par="16:9">
      <SegmentTemplate
          media="video/$RepresentationID$/seg-$Number$.m4s"
          initialization="video/$RepresentationID$/init.mp4"
          timescale="12288" duration="49152" startNumber="1" />
      <Representation id="v0" width="1920" height="1080" bandwidth="6000000" />
      <Representation id="v1" width="1280" height="720"  bandwidth="3000000" />
      <Representation id="v2" width="960"  height="540"  bandwidth="1500000" />
      <Representation id="v3" width="640"  height="360"  bandwidth="800000"  />
      <Representation id="v4" width="426"  height="240"  bandwidth="400000"  />
    </AdaptationSet>
    <!-- Английское стерео-аудио 128 kbps AAC-LC -->
    <AdaptationSet id="audio-en" contentType="audio" mimeType="audio/mp4"
                   codecs="mp4a.40.2" lang="en" audioSamplingRate="48000">
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
      <SegmentTemplate
          media="audio/en/seg-$Number$.m4s"
          initialization="audio/en/init.mp4"
          timescale="48000" duration="192000" startNumber="1" />
      <Representation id="a-en-0" bandwidth="128000" />
    </AdaptationSet>
    <!-- Испанское аудио -->
    <AdaptationSet id="audio-es" contentType="audio" mimeType="audio/mp4"
                   codecs="mp4a.40.2" lang="es" audioSamplingRate="48000">
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="alternate" />
      <SegmentTemplate
          media="audio/es/seg-$Number$.m4s"
          initialization="audio/es/init.mp4"
          timescale="48000" duration="192000" startNumber="1" />
      <Representation id="a-es-0" bandwidth="128000" />
    </AdaptationSet>
    <!-- Английские субтитры, WebVTT в fMP4 -->
    <AdaptationSet id="subs-en" contentType="text" mimeType="application/mp4"
                   codecs="wvtt" lang="en">
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle" />
      <SegmentTemplate
          media="subs/en/seg-$Number$.m4s"
          initialization="subs/en/init.mp4"
          timescale="1000" duration="4000" startNumber="1" />
      <Representation id="s-en-0" bandwidth="2000" />
    </AdaptationSet>
  </Period>
</MPD>

Математика, строка за строкой. minBufferTime="PT2S" означает, что плеер буферит минимум две секунды на верхней полосе – 6 Мбит/с на видео и 128 кбит/с на аудио. Буфер в байтах составляет минимум (6_000_000 + 128_000) × 2 / 8 = 1.53 MB. timescale="12288" на видеошаблоне и duration="49152" дают 49152 / 12288 = 4.0 s на сегмент; 90 минут – это 5400 секунд, то есть 1350 сегментов. Английское аудио использует timescale="48000" (частоту дискретизации) и duration="192000" для 192000 / 48000 = 4.0 s; границы аудио- и видеосегментов выровнены. Испанское аудио – те же параметры. Английский субтитровый трек использует timescale="1000", то есть длительность указана в миллисекундах; duration="4000" – тот же 4-секундный шаг в единицах timescale субтитров. Плеер, выбирающий v2 (540p), a-en-0 (английское аудио) и s-en-0 (английские субтитры), делает три HTTP-запроса каждые 4 секунды в течение 90 минут – итого 1350 × 3 = 4050 запросов на сегменты за сессию.

Ключ кеширования CDN для этих запросов – только URL; параметры строки запроса не учитываются. Уровень попаданий в кеш CDN на edge для популярного VOD составляет 95–99 %. Сам файл MPD небольшой (пример выше – около 2 КБ; MPD в продакшене – 3–30 КБ) и хранится в кеше недолго (типичный срок – 60 секунд для VOD, @minimumUpdatePeriod – для live).

DASH vs HLS – сравнение, важное в 2026 году

Два протокола решают одну и ту же задачу. Различия – в деталях.

ИзмерениеDASHHLS
СтандартизаторISO/IEC (open)IETF (RFC 8216 → draft-pantos-hls-rfc8216bis) + Apple Authoring Spec
Формат манифестаXML (MPD)Текст (m3u8)
Охват кодековКодек-агностиченКодек-агностичен с 2017 (изначально MPEG-TS-only)
Охват контейнеровКонтейнер-агностичен; fMP4 / CMAF доминируютИзначально MPEG-TS; CMAF с 2017
Нативная поддержка в браузерахЧерез MSE (Chrome, Edge, Firefox, Android-браузеры)iOS Safari (нативно); macOS Safari (нативно и через MSE); Android (через Exo/Shaka MSE)
Поддержка устройств AppleНе нативно; нужен Shaka/dash.js + MSE; работает в macOS Safari, не работает в iOS SafariНативно везде
Мульти-DRMНативно через CENC ContentProtection (Widevine + PlayReady + ClearKey, всё в одном MPD)Нативно FairPlay через EXT-X-KEY и HLS Authoring Spec; CENC cbcs тоже мостит HLS с Widevine и PlayReady
Low-latencyLL-DASH + DASH-IF Low-Latency Profile (CMAF chunked)LL-HLS (parts + preload hints + blocking reload)
Вставка рекламыSCTE-35 <EventStream>; multi-period SSAI зрелыйSCTE-35 EXT-X-DATERANGE; SSAI зрелый
Рост размера манифеста в liveРастёт, пока не используется MPD PatchРастёт, пока не используются playlist delta updates
Форматы субтитровWebVTT в fMP4, TTML/IMSC в fMP4, SRTWebVTT (.vtt), TTML/IMSC (с 2018)
Trick-mode (FF/RW)Нативно через EssentialProperty:trickmode и image-AdaptationSetНативно через EXT-X-IMAGE-STREAM-INF (I-frame playlists)
Reference implementationsdash.js (DASH-IF), Shaka Player (Google), ExoPlayer (Google для Android)Apple AVPlayer (нативно), hls.js (open), Shaka Player (multi-protocol)
Крупнейшие внедренияNetflix, YouTube, Disney+, Prime Video, Hulu, TwitchApple TV+, каждое iOS-приложение, live в экосистеме Apple

В 2026 году практический ответ на вопрос «DASH или HLS» – оба, с единым набором CMAF-сегментов в основе. Два манифеста стоят недорого; дорого – медиаконтент. Согласно отчёту Bitmovin Video Developer Report 2025/26, 64 % опрошенных разработчиков используют DASH, 82 % – HLS, а пересечение этих групп составляют сервисы, транслирующие оба формата с одного CMAF-источника.

Low-Latency DASH – краткий обзор (подробное рассмотрение в разделе 4.5)

Профиль низкой задержки DASH-IF (формализованный в DASH-IF IOP v4.3 и модели ограниченного времени) обеспечивает задержку «от стекла до стекла» на уровне 2–4 секунды при использовании обычного HTTP/1.1 с передачей по частям. Четыре механизма:

  1. CMAF-чанки (обычно короче сегментов – порядка 200 мс) становятся единицей, которую плеер загружает по HTTP/1.1 с использованием chunked transfer.
  2. Элемент <ServiceDescription> в MPD задаёт целевую задержку (target latency) и диапазон скорости воспроизведения, в пределах которого плеер может корректировать скорость, чтобы поддерживать заданную задержку.
  3. availabilityTimeOffset на <SegmentTemplate> указывает, что сегменты становятся доступны на availabilityTimeOffset секунд раньше, чем предсказывает строгая формула availabilityStartTime + segmentNumber × segmentDuration – поскольку энкодер публикует чанки по мере их создания, не дожидаясь завершения сегмента.
  4. MPD Patch позволяет манифесту оставаться компактным на протяжении всего потока.

Результаты сопоставимы с LL-HLS – 2–5 секунд от начала до конца воспроизведения – на протоколе, совместимом с любой CDN, поддерживающей HTTP/1.1. Подробный разбор LL-DASH представлен в разделе 4.5.

Типичные ошибки

Краткая экскурсия по сценариям сбоев, через которые Фора Софт прошла в продакшене.

Нет <UTCTiming> или он неправильный. Динамический MPD без источника UTC заставляет плеер использовать локальные часы. Локальные часы на Smart TV и embedded-устройствах могут отклоняться на десятки секунд. Плееры неправильно вычисляют current_segment_number, запрашивают несуществующие сегменты, переходят на фоллбэк, повторяют попытку – и в результате возникает прерывистый ребуферинг, который QA не удаётся воспроизвести на чистых лабораторных устройствах. Фикс: добавьте в каждый динамический MPD минимум один <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-iso:2014" value="…">, направленный на надёжный HTTP-источник времени (например, Akamai, Cloudflare или собственный ntpd-фронтенд).

Расхождение между реальной длительностью сегмента и @duration на шаблоне. Пирамида боли: упаковщик, настроенный на 4-секундные сегменты, на практике формирует сегменты длительностью 3,997 с (из-за того, что GOP закрывается на 3 кадра раньше – чтобы выровняться по следующему IDR). При этом MPD всё ещё объявляет duration="49152" (4,0 с). Через 10 минут трансляции плеер и энкодер расходятся примерно на 600 мс; через час – уже на 3,6 с; в результате плеер начинает запрашивать ещё не существующие сегменты. Фикс: либо заставить энкодер строго придерживаться GOP-выровненных 4-секундных сегментов (closed-gop + gop-size = framerate × duration), либо переключить манифест на SegmentTemplate с SegmentTimeline, где указана реальная длительность каждого сегмента.

ContentProtection в неправильной области видимости. <ContentProtection> допустим внутри <AdaptationSet> (применяется ко всем Representations набора) или внутри <Representation> (переопределение для одного). Размещение его внутри <Period> – частая ошибка при копировании; одни лояльные плееры это принимают, другие молча отклоняют. Фикс: размещайте ContentProtection на уровне AdaptationSet в типичном случае (одно шифрование применяется ко всей группе) и опускайте на уровень Representation только тогда, когда у отдельных рендиций разное шифрование.

@startWithSAP не равен 1. Некоторые энкодеры генерируют сегменты, начинающиеся с P-кадра вместо IDR. MPD-файл @startWithSAP="1" содержит неверную информацию, из-за чего плеер либо постоянно ребуферится при каждом переключении ABR, либо – что хуже – выводит блочное видео на границе сегментов. Фикс: проверять закодированный вывод с помощью инструмента CMAF-конформности (shaka-packager, Bento4 mp4info); отклонять любой сегмент, не начинающийся с SAP типа 1.

Смешивание $Number$ и $Time$ шаблонов в одном AdaptationSet. Спецификация это допускает, но ни один плеер с этим не справляется хорошо. Фикс: один режим адресации на AdaptationSet – и придерживаться его.

Ротация init.mp4 на границе Period без сигнализации <SupplementalProperty> continuity. Если два соседних Period используют разные Init Segments (разная конфигурация кодека), часть плееров воспринимает границу как фатальную ошибку и останавливается. Фикс: сигнализировать Period continuity через <SupplementalProperty schemeIdUri="urn:mpeg:dash:period-continuity:2015">, когда следующий Period продолжает дорожку предыдущего с той же конфигурацией кодека – тогда плеер понимает, что пересобирать decoder pipeline не нужно.

MPD слишком большой, чтобы перечитывать его каждый @minimumUpdatePeriod. Live-MPD на SegmentTimeline, растущий часами, может занять сотни килобайт. Перечитывание его каждые 2 секунды жжёт трафик и CPU на каждом подключённом плеере. Фикс: включить MPD Patch в упаковщике (Unified Streaming, AWS MediaPackage, Wowza, Bitmovin Live Server – все поддерживают). Плеер тогда забирает ~/manifest_patch.mpd (несколько сотен байт) на каждом refresh и сливает его в свой in-memory MPD.

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

Фора Софт обеспечивает DASH-стриминг для видеоконференций, OTT, e-learning, телемедицины, видеонаблюдения и AR/VR с тех пор, как протокол ещё находился на стадии Working Draft. Обычно мы развёртываем DASH-over-CMAF с общей шифрованием (Common Encryption) в качестве основного стека доставки для всех клиентов вне экосистемы Apple, параллельно предоставляя HLS-манифест поверх тех же CMAF-сегментов – для iOS Safari. Наши инженеры знают, какой рычаг продакшена нужно дёрнуть, когда MPD не загружается на Smart TV на базе Tizen, когда LL-DASH-поток зависает за балансировщиком нагрузки гипермасштабируемого провайдера или когда требуется развернуть ротацию мульти-DRM, не нарушая работу уже существующих клиентов с Widevine. Технология – это лишь половина успеха; другая половина – операционная дисциплина при запуске на сорока классах устройств. Если в вашем roadmap присутствуют и то, и другое – свяжитесь с нами до того, как вы зафиксируете выбранный стек.

Ключевые тезисы

  • MPEG-DASH = ISO/IEC 23009-1; действующая редакция – пятая, 2022 год.
  • MPD представляет собой четырёхуровневую структуру: Презентация → Period → AdaptationSet → Representation → Segment.
  • Три режима адресации сегментов: SegmentList (устаревший), SegmentTemplate+$Number$ (по умолчанию для VOD), SegmentTemplate+$Time$+SegmentTimeline (для сегментов переменной длительности / DVR / ad-aware live).
  • Для потоковой передачи в режиме live требуются availabilityStartTime, minimumUpdatePeriod, timeShiftBufferDepth, suggestedPresentationDelay и хотя бы один <UTCTiming>.
  • Поддержка нескольких систем DRM через Common Encryption (CENC, ISO/IEC 23001-7) – ключевое преимущество DASH: один и тот же набор медиафайлов может использовать Widevine, PlayReady и ClearKey одновременно в одном MPD.
  • Профиль CMAF (urn:mpeg:dash:profile:cmaf:2019) позволяет использовать одни и те же медиаданные как для DASH, так и для HLS.

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

CTA

  • Поговорить с инженером по стримингу – забронируйте 30-минутный скоупинг-колл, чтобы обсудить вашу архитектуру DASH или гибридную DASH/HLS.
  • Посмотреть наши кейсы – OTT, телемедицина и e-learning продукты, которые Фора Софт реализовала на DASH-стеке доставки.
  • Скачать DASH MPD anatomy cheat sheet (PDF) – одностраничный справочник по каждому элементу, атрибуту и значению MPD, которые реально используются в продакшене.

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

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