If you’ve opened Chrome’s DevTools on Netflix or YouTube and seen requests for files ending in .mpd and .m4s, you’ve watched MPEG-DASH in action. The XML file is a manifest, the .m4s files are short fragmented-MP4 segments of video and audio, and your browser is stitching them together in real time over plain HTTP.
DASH is the open-standard cousin of HLS. Where Apple owns HLS, the MPEG/ISO standards body owns DASH. Where HLS uses .m3u8 text playlists, DASH uses .mpd XML manifests. Where HLS originally insisted on H.264, DASH never had a codec preference. The two protocols solve the same problem from different starting points, and a thoughtful streaming service in 2026 ships both. MPEG-DASH — Dynamic Adaptive Streaming over HTTP — is the ISO/IEC 23009-1 standard for delivering video as a chain of short fMP4 segments described by an XML manifest (.mpd) and fetched over ordinary HTTP.
This guide walks through what an .mpd actually contains, how DASH’s Period / AdaptationSet / Representation hierarchy works, where DRM fits in, the case for and against DASH versus HLS, and what happens when you try to save one of these streams to disk.
Key Takeaways
- MPEG-DASH is the ISO open standard for adaptive HTTP streaming — ISO/IEC 23009-1. HLS is RFC 8216.
- The
.mpdmanifest is XML, not plaintext. It describes Periods, AdaptationSets, and Representations — a strict hierarchy the player walks at startup and on every quality switch. - DASH is codec-agnostic by design. H.264, H.265, VP9, AV1, AAC, Opus — the manifest declares codec strings and the player decodes.
- Media segments are fragmented MP4 (
.m4s), the same CMAF fragments used by modern HLS. One set of bytes can serve both protocols. - DRM uses MPEG Common Encryption (CENC) so a single encrypted file works with Widevine, PlayReady, or FairPlay depending on the client’s decryption module.
- Apple platforms do not natively support DASH. iPhone, iPad, Safari, and Apple TV require HLS — DASH-only is a non-starter.
- Netflix, YouTube, Disney+, Hulu, and Max all ship DASH and HLS side by side; Apple TV+, iTunes, and Twitch ship HLS only.
The Simple Explanation
Forget the acronyms for a moment. A streaming service has the same problem either way: ship a long video to viewers over messy connections, let them seek instantly, let them adapt to bandwidth changes mid-playback, and do it cheaply over commodity HTTP. The industry-wide solution is to chop the video into short segments, write a manifest that lists them, and let the player fetch what it needs in order. HLS does this with text playlists; DASH does this with XML manifests. The job is the same; the paperwork is different.
From a player’s seat, the DASH approach feels almost identical to HLS. The player fetches a small manifest at startup, learns which qualities and audio tracks are available, picks one of each based on bandwidth and viewport, then fetches a stream of short segments and feeds them to the decoder. Quality switches happen between segments. Live streams work by having the manifest grow over time. Seeking is instant because the player jumps to whichever segment covers the target timestamp.
The user-visible difference between the two protocols is small but real. HLS playlists are plain text; DASH manifests are XML. HLS segments were historically .ts (MPEG-2 Transport Stream) and are now usually fMP4; DASH segments have always been fMP4, with the .m4s extension. The sponsoring organizations are different too: Apple invented and stewards HLS, while DASH came out of MPEG and the DASH Industry Forum as an open ISO standard with no single vendor in charge. For the matching primer, HLS in detail covers what an .m3u8 playlist looks like end to end.
How DASH Actually Works
A DASH stream is an XML manifest plus a pile of fragmented-MP4 segments, all served over ordinary HTTP. Same shape as HLS, different format on every layer.
The .mpd Manifest
The first thing a DASH player fetches is the Media Presentation Description — the .mpd. Unlike HLS’s plaintext playlist, this is an XML document with a defined schema. Here’s a lightly trimmed example:
<?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-live:2011">
<Period id="0" start="PT0S">
<AdaptationSet mimeType="video/mp4" segmentAlignment="true"
startWithSAP="1" maxWidth="1920" maxHeight="1080">
<Representation id="v1" codecs="avc1.640028"
width="1920" height="1080" bandwidth="5000000">
<SegmentTemplate timescale="1000" duration="4000"
initialization="v1/init.mp4"
media="v1/seg-$Number$.m4s"
startNumber="1"/>
</Representation>
<Representation id="v2" codecs="avc1.4d401f"
width="1280" height="720" bandwidth="2800000">
<SegmentTemplate timescale="1000" duration="4000"
initialization="v2/init.mp4"
media="v2/seg-$Number$.m4s"
startNumber="1"/>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="audio/mp4" lang="en">
<Representation id="a1" codecs="mp4a.40.2" bandwidth="128000">
<SegmentTemplate timescale="1000" duration="4000"
initialization="a1/init.mp4"
media="a1/seg-$Number$.m4s"
startNumber="1"/>
</Representation>
</AdaptationSet>
</Period>
</MPD>
Every attribute means something concrete. type="static" flags this as VOD (a live stream is type="dynamic"). mediaPresentationDuration="PT1H30M" is an ISO 8601 duration. Each Representation carries a codec string and bandwidth budget. The SegmentTemplate is where the magic happens: instead of listing every segment URL the way HLS does, DASH lets the manifest declare a URL pattern and the player computes the URLs on the fly.
Periods, AdaptationSets, and Representations
The strict hierarchy inside the manifest is the conceptual heart of DASH:
- Period — a contiguous slice of the timeline. Most movies are one period; broadcasters use multiple periods to splice in ads or chapter boundaries.
- AdaptationSet — a collection of alternative encodings of the same content, interchangeable at runtime. A typical movie has one video AdaptationSet, one or more audio AdaptationSets (one per language), and one or more subtitle AdaptationSets.
- Representation — a single concrete encoding. 1080p H.264 at 5 Mbps is a Representation; 720p H.264 at 2.8 Mbps is another; 720p VP9 at 1.5 Mbps is another. The player picks one Representation per AdaptationSet and can swap to a different one at any segment boundary inside the same AdaptationSet.
This three-level model is more structured than HLS’s flat variants-and-segments approach, which is why DASH wins on extensibility: multiple audio tracks, trick-play tracks, thumbnail tracks, and per-period ad insertion fit cleanly without inventing new manifest syntax.
Segments and Initialization
A Representation’s bytes come in two flavors. The initialization segment is a small fMP4 file containing the moov box — codec parameters, track metadata, and decoder configuration. The player fetches it once per Representation. The media segments are the actual audio and video, each typically 2 to 6 seconds long, cut on keyframe boundaries for video tracks so the player can start decoding from the beginning of any segment.
When the manifest sets startWithSAP="1", each segment begins with a Stream Access Point — DASH’s equivalent of HLS’s EXT-X-INDEPENDENT-SEGMENTS flag, guaranteeing that segments are independently decodable. Without that guarantee, downstream segments may depend on earlier ones, which makes adaptive switching unsafe. Because the SegmentTemplate URLs are pattern-driven (v1/seg-$Number$.m4s), the manifest can describe a 90-minute movie in a few hundred bytes of XML. SegmentTimeline is the alternative when durations aren’t uniform.
Common Encryption (CENC)
DASH’s DRM story runs through MPEG Common Encryption (CENC), ISO/IEC 23001-7. CENC encrypts the media segments themselves with AES-128 in CTR mode under a content key, then declares which DRM systems can issue that key. In the .mpd, you’ll see ContentProtection elements like this:
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"
cenc:default_KID="34e5db32-8625-47cd-ba06-68fca0655a72"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
<cenc:pssh>AAAAW3Bzc2gAAAAA...</cenc:pssh>
</ContentProtection>
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95">
<cenc:pssh>AAACfHBzc2gAAAAA...</cenc:pssh>
</ContentProtection>
The first block declares the default key ID under CENC. The second is Widevine’s UUID; the third is PlayReady’s. Your browser’s Content Decryption Module reads whichever block matches its supported DRM, sends a license request to the service’s license server with the embedded PSSH (Protection System Specific Header) data, and gets back the content key needed to decrypt the segments. For the full picture, see how Widevine and PlayReady gate premium streams. FairPlay support in DASH is uncommon historically — FairPlay was designed for HLS — but CMAF + CBCS encryption has made cross-DRM FairPlay-over-DASH technically possible on a small set of platforms.
Codec-Agnostic by Design
HLS originally privileged H.264 (early Apple devices couldn’t decode anything else), and adding new codecs took a multi-year specification process. DASH never picked a codec — the manifest just declares codec strings (avc1.640028, hev1.1.6.L150.B0, vp09.00.50.08, av01.0.05M.08) and the player checks whether its decoder supports them. This is why YouTube could ship AV1 over DASH years before equivalent HLS support shipped at Apple. Because the manifest layer is the only thing DASH players need to understand, VidMost can parse an .mpd, walk the SegmentTemplate URLs, fetch every fMP4 fragment, and remux the result without caring which codec is inside.
DASH vs HLS: The Honest Comparison
DASH and HLS solve the same problem with different tradeoffs. Neither is universally better. Here’s the case for each across the axes that actually matter.
Manifest Format
DASH’s .mpd is XML with a defined schema — extensible (new features get new elements, validated by schema, old players ignore what they don’t understand) but verbose. HLS’s .m3u8 is plaintext with #EXT-X- tags, readable at a glance and easy to grep. DASH wins for structure and machine-validation; HLS wins for human readability.
Latency
Both started with seconds-to-tens-of-seconds latency. Both have shipped low-latency extensions: LL-HLS uses partial segments, blocking playlist reloads, and preload hints (Apple replaced its earlier HTTP/2 push design with EXT-X-PRELOAD-HINT), while LL-DASH uses chunked-transfer-encoded segments and the Common Media Application Format Live profile. Both target 2–5 second glass-to-glass latency in production. For sub-second latency you drop to WebRTC.
Codec Support
DASH has been codec-agnostic from day one. H.264, H.265, VP9, AV1, AAC, Opus, FLAC, AC-4 — the manifest declares the codec string and the player decides. HLS started H.264-only because the original iPhone hardware demanded it. Apple has steadily widened support: H.265 over fMP4 since 2017, Dolby Vision and HDR10 since 2018, AV1 since the iPhone 15 generation. Modern HLS isn’t H.264-locked, but the protocol’s codec history has a lag DASH never had.
DRM
Both lean on AES-based segment-level encryption, but the DRM systems on top differ. DASH commonly uses CENC with Widevine and PlayReady — a single encrypted file works with both because the content key is the same; only the license request format differs. HLS historically uses FairPlay Streaming (Apple-only) plus, increasingly, Widevine via CMAF + CBCS. Once your service is on CMAF, the same encrypted segments can serve both manifest types and all three major DRM systems.
Apple/iOS Support
HLS is mandatory on iOS, iPadOS, Safari, and Apple TV. DASH is not natively supported on any Apple platform. This is the single biggest deciding factor in DASH-vs-HLS strategy. DASH playback in Safari is possible only via Media Source Extensions plus a JavaScript shim like shaka-player or dash.js, and even then it doesn’t cover every iOS edge case (AirPlay, lock-screen controls, picture-in-picture). Any service targeting iPhones must ship HLS. DASH-only is a non-starter.
CDN Compatibility and the CMAF Convergence
Both protocols are pure HTTP. Any CDN that serves static files can serve a DASH or HLS stream — CDN cost and configuration are essentially identical. The most important development of the last decade is that DASH and HLS now share segment bytes. CMAF — the Common Media Application Format, ISO/IEC 23000-19 — defines a fragmented-MP4 profile that satisfies both DASH and modern HLS. A streaming service can encode once into CMAF segments and write both an .mpd and an .m3u8 that point at the exact same .m4s files. This is what’s actually happening at YouTube, Netflix, Apple, and most hosted-video providers in 2026.
Who Ships What in 2026
- Netflix — DASH primary on web, Windows, Android, smart TVs, and consoles; HLS fallback for Safari and iOS.
- YouTube — DASH on web and Android with VP9 / AV1; HLS for iOS, Safari, AirPlay, and most TV apps.
- Apple TV+, iTunes Store — HLS only.
- Twitch — HLS only, for live and VOD, since the RTMP-playback retirement in 2014.
- Disney+, Hulu, Max, Amazon Prime Video — DASH or HLS depending on the client, often the same CMAF segments under both manifests.
HLS owns Apple devices and shares the rest of the market with DASH. Most major services support both because the alternative is leaving an audience on the table.
What This Means If You Want to Save a Video
Knowing how DASH works makes the practical download problem concrete. Every issue HLS users hit when trying to save a stream applies to DASH too, often worse:
- The browser’s Save As only gets the
.mpd. That’s the XML manifest. It contains zero video bytes. Opening it in VLC works only while the network session is still valid and the segment URLs haven’t expired. - DASH segments are
.m4sfiles — one init segment plus dozens or hundreds of media segments per Representation. Each is a fragmented-MP4 chunk that’s useless on its own. To get a single playable file you have to fetch the init segment plus every media segment in order and remux them. (If you’re fuzzy on what’s actually inside an.m4s, see container vs codec.) - You’d have to parse XML, walk the SegmentTemplate URLs, and remux. That means writing code that understands
$Number$,$Time$,$RepresentationID$, and$Bandwidth$placeholders, assembling URLs, fetching them in parallel without hammering the CDN, and feeding the bytes throughffmpegormp4box. It’s not a weekend script — it’s real software. - Variant selection matters. Pick the wrong Representation and you’ve downloaded a 480p copy of a 1080p movie. Tokens expire too — many
.mpdand segment URLs are signed and go stale in minutes.
VidMost handles all of this. It parses the .mpd, picks the highest-quality video and audio Representations, downloads every segment in parallel, and remuxes the CMAF fragments into a single clean MP4. For DRM-protected DASH streams (the common Widevine + PlayReady setup), VidMost’s built-in Widevine L3 support works wherever L3 playback is available — the actual quality ceiling is set by the service and DRM level, and premium platforms typically cap L3 streams at 480p–720p. You paste a URL; you get an MP4.
Common Pitfalls and Misconceptions
A handful of DASH-related confusions show up in forum threads constantly. Worth clearing up.
- “MPEG-DASH is a Google thing.” It isn’t. DASH is an MPEG / ISO open standard (ISO/IEC 23009-1), driven by the DASH Industry Forum — a consortium including Adobe, Microsoft, Netflix, and Qualcomm. Google helped develop it and uses it on YouTube, but no single vendor owns the spec.
- “DASH is newer and therefore better.” DASH (2012) is newer than HLS (2009), but “better” depends on your platform mix. If your audience is on iPhone, HLS wins by force. If your audience is on Android and smart TVs with maximum codec flexibility, DASH wins. Most services ship both.
- “The
.mpdis the video.” It isn’t. It’s the manifest. The actual video lives in the.m4ssegments the manifest references. - “If a site uses DASH, my HLS player can’t play it.” True for native players. But most modern web players — shaka-player, dash.js, hls.js, video.js — handle both inside the browser by feeding segments to the video element via Media Source Extensions.
- “DASH always means DRM.” It doesn’t. Plenty of DASH streams ship with no encryption: live event broadcasts, education platforms, and most free YouTube content. DRM is an optional layer declared via
ContentProtectionelements.
Closing Thoughts
DASH is HLS’s parallel-universe twin. Both slice video into short segments, describe them in a manifest, and ship them over plain HTTP. The differences — XML vs plaintext, ISO standard vs Apple specification, codec-agnostic vs codec-history-dependent — matter inside the industry but rarely matter to viewers. What matters is that the streaming services licensing content from every studio in the world have settled on these two protocols, increasingly converging on shared CMAF segments under both manifests. Once you can recognize an .mpd request and understand the Period / AdaptationSet / Representation hierarchy, the strange behavior of modern streaming stops being mysterious — it’s all the same loop: fetch manifest, pick variants, fetch segments, decode, repeat. If you’d rather skip the protocol layer entirely and just save the video, VidMost handles HLS, MPEG-DASH, fMP4, CMAF, and DRM-protected streams.
Related reading
- How Online Video Actually Plays — the big-picture streaming pipeline from camera to your screen.
- What Is HLS and M3U8? — the sibling protocol covered end to end.
- Why Video Quality Changes Mid-Playback — the ABR logic inside every DASH and HLS player.
- Video Containers vs Codecs — what’s actually inside an
.m4ssegment. - What Is DRM-Protected Content? — how Widevine, PlayReady, and FairPlay gate the encrypted variants you can’t just save.