返回部落格

MPEG-DASH 解析,以及它與 HLS 的對比

MPEG-DASH 是 Netflix 和 YouTube 背後的 ISO 自適應串流標準。白話文說明 .mpd manifest、fMP4 片段、CMAF,以及 DASH 與 HLS 的對比。

By

如果你曾在 Netflix 或 YouTube 上打開 Chrome 的 DevTools,看到結尾是 .mpd.m4s 的請求,你就看到了 MPEG-DASH 的實際運作。那個 XML 檔是 manifest,.m4s 檔是視訊與音訊的短 fragmented-MP4 片段,你的瀏覽器透過普通 HTTP 即時把它們縫合起來。

DASH 是 HLS 的開放標準堂兄弟。HLS 屬於 Apple,DASH 屬於 MPEG/ISO 標準組織。HLS 使用 .m3u8 文字播放清單,DASH 使用 .mpd XML manifest。HLS 原本堅持 H.264,DASH 從未對編碼器有偏好。這兩個協定從不同起點解決同一個問題,2026 年周到的串流服務兩者都會提供。MPEG-DASH——Dynamic Adaptive Streaming over HTTP——是 ISO/IEC 23009-1 標準,以一連串由 XML manifest(.mpd)描述的短 fMP4 片段,透過普通 HTTP 傳送影片。

本指南將走過 .mpd 實際包含什麼、DASH 的 Period / AdaptationSet / Representation 階層如何運作、DRM 在哪裡接入、DASH 對比 HLS 的支持與反對論點,以及當你試圖儲存這類串流時會發生什麼。

重點摘要 {#key-takeaways}

  • MPEG-DASH 是 ISO 開放標準,用於自適應 HTTP 串流——ISO/IEC 23009-1。HLS 則是 RFC 8216。
  • .mpd manifest 是 XML,不是純文字。它描述 Period、AdaptationSet 和 Representation——一套嚴格的階層,播放器在啟動時與每次切換畫質時走訪。
  • DASH 的設計對編碼器中立。 H.264、H.265、VP9、AV1、AAC、Opus——manifest 宣告編碼器字串,由播放器解碼。
  • 媒體片段是 fragmented MP4.m4s),和現代 HLS 使用的 CMAF 片段相同。一組位元組可以服務兩種協定。
  • DRM 使用 MPEG Common Encryption(CENC),讓單一加密檔依用戶端的解密模組可同時與 Widevine、PlayReady 或 FairPlay 配合。
  • Apple 平台不原生支援 DASH。 iPhone、iPad、Safari 和 Apple TV 要求 HLS——只提供 DASH 是不可行的。
  • Netflix、YouTube、Disney+、Hulu 和 Max 全部同時提供 DASH 和 HLS;Apple TV+、iTunes 和 Twitch 僅提供 HLS。

簡單的解釋

先把縮寫放一邊。一個串流服務無論怎麼做都面臨同樣的問題:把一段長影片送到網路狀況混亂的觀眾手上、讓他們即時拖曳、讓他們在播放中途調整頻寬,並透過商品化的 HTTP 便宜地完成。業界普遍的解決方案是把影片切成短片段、寫一份列出它們的 manifest,並讓播放器依需要依序抓取。HLS 用文字播放清單做這件事;DASH 用 XML manifest 做這件事。工作相同;文件不同。

從播放器的座位來看,DASH 的做法與 HLS 幾乎一模一樣。播放器在啟動時抓取一個小型 manifest、了解有哪些畫質與音訊軌道可用,根據頻寬與視口為每個各挑一個,然後抓取一連串短片段並餵給解碼器。畫質切換發生在片段之間。直播透過 manifest 隨時間增長運作。拖曳即時生效,因為播放器跳到涵蓋目標時間點的片段。

兩個協定使用者看得到的差異很小但真實。HLS 播放清單是純文字;DASH manifest 是 XML。HLS 片段歷史上是 .ts(MPEG-2 Transport Stream),如今通常是 fMP4;DASH 片段一直都是 fMP4,副檔名 .m4s。贊助組織也不同:Apple 發明並管理 HLS,而 DASH 出自 MPEG 與 DASH Industry Forum,作為一個沒有單一廠商主導的開放 ISO 標準。對應的入門文章請見 HLS 詳解,從頭到尾介紹 .m3u8 播放清單長什麼樣。

DASH 實際運作的方式

一條 DASH 串流是一個 XML manifest 加上一堆 fragmented-MP4 片段,全部透過普通 HTTP 提供。 形狀和 HLS 相同,但每一層的格式不同。

.mpd Manifest

DASH 播放器首先抓取的是 Media Presentation Description——即 .mpd。不像 HLS 的純文字播放清單,這是一份有明確結構描述的 XML 文件。以下是經過輕度修剪的範例:

<?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>

每個屬性都有具體意義。type="static" 把這標記為 VOD(直播是 type="dynamic")。mediaPresentationDuration="PT1H30M" 是 ISO 8601 時長。每個 Representation 都帶有編碼器字串與頻寬預算。SegmentTemplate 才是魔法發生的地方:DASH 不像 HLS 那樣列出每個片段 URL,而是讓 manifest 宣告 URL 範本,由播放器即時計算 URL。

Period、AdaptationSet 和 Representation

manifest 內嚴格的階層是 DASH 概念上的核心:

  • Period——時間軸的一段連續切片。多數電影是一個 Period;廣播機構用多個 Period 來插入廣告或章節邊界。
  • AdaptationSet——同一份內容的替代編碼集合,在執行時可互換。典型的電影有一個視訊 AdaptationSet、一或多個音訊 AdaptationSet(每種語言一個)、一或多個字幕 AdaptationSet。
  • Representation——單一具體的編碼。1080p H.264 5 Mbps 是一個 Representation;720p H.264 2.8 Mbps 是另一個;720p VP9 1.5 Mbps 又是一個。播放器為每個 AdaptationSet 挑一個 Representation,並可以在同一個 AdaptationSet 內的任何片段邊界切換到不同 Representation。

這個三層模型比 HLS 的扁平變體加片段做法更有結構,這也是 DASH 在可擴充性上勝出的原因:多音訊軌道、特技播放(trick-play)軌道、縮圖軌道與 Period 級廣告插入都能乾淨地容納,而不必發明新的 manifest 語法。

片段與初始化

一個 Representation 的位元組有兩種樣態。初始化片段是一個小的 fMP4 檔,包含 moov box——編碼器參數、軌道中繼資料與解碼器設定。播放器每個 Representation 抓取一次。媒體片段是實際的音訊與視訊,每段通常 2 到 6 秒,視訊軌道在關鍵影格邊界切開,這樣播放器可以從任一片段開頭開始解碼。

當 manifest 設定 startWithSAP="1",每個片段以一個 Stream Access Point 開始——這是 DASH 中相當於 HLS 的 EXT-X-INDEPENDENT-SEGMENTS 旗標的東西,保證片段可獨立解碼。沒有該保證時,下游片段可能依賴更早的片段,使自適應切換變得不安全。由於 SegmentTemplate URL 是範本驅動的(v1/seg-$Number$.m4s),manifest 可以用幾百個位元組的 XML 描述一部 90 分鐘的電影。SegmentTimeline 則是時長不一致時的替代方案。

Common Encryption(CENC)

DASH 的 DRM 故事透過 MPEG Common Encryption(CENC),ISO/IEC 23001-7 進行。CENC 在內容金鑰下以 AES-128 CTR 模式加密媒體片段本身,然後宣告哪些 DRM 系統可以簽發該金鑰。在 .mpd 中你會看到這樣的 ContentProtection 元素:

<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>

第一個區塊宣告 CENC 下的預設金鑰 ID。第二個是 Widevine 的 UUID;第三個是 PlayReady 的。你瀏覽器的 Content Decryption Module 讀取符合其支援 DRM 的區塊,把嵌入的 PSSH(Protection System Specific Header)資料連同授權請求送到服務的授權伺服器,並拿回解密片段所需的內容金鑰。完整介紹請見 Widevine 和 PlayReady 如何把關高級串流。DASH 中的 FairPlay 支援在歷史上不常見——FairPlay 是為 HLS 設計的——但 CMAF + CBCS 加密讓跨 DRM 的 FairPlay over DASH 在少數平台上在技術上變得可行。

設計上對編碼器中立

HLS 原本偏好 H.264(早期 Apple 裝置無法解碼其他東西),而要新增編碼器需要多年的規格制定過程。DASH 從未挑選編碼器——manifest 只宣告編碼器字串(avc1.640028hev1.1.6.L150.B0vp09.00.50.08av01.0.05M.08),由播放器檢查它的解碼器是否支援。這就是為什麼 YouTube 能在 Apple 提供同等 HLS 支援之前數年就透過 DASH 提供 AV1。由於 DASH 播放器只需理解 manifest 層,VidMost 可以解析 .mpd、走訪 SegmentTemplate URL、抓取每個 fMP4 fragment 並重新封裝結果,而不必在意內部是什麼編碼器。

DASH 對比 HLS:誠實的比較

DASH 和 HLS 以不同的取捨解決同樣的問題。沒有哪個普遍勝出。 以下是在實際重要的維度上,兩者各自的支持論點。

Manifest 格式

DASH 的 .mpd 是有明確結構描述的 XML——可擴充(新功能取得新元素、由 schema 驗證,舊播放器會忽略它不認識的東西)但冗長。HLS 的 .m3u8 是帶有 #EXT-X- 標籤的純文字,一目了然且易於 grep。DASH 在結構與機器驗證上勝出;HLS 在人類可讀性上勝出。

延遲

兩者最初都是數秒到數十秒的延遲。兩者都推出了低延遲擴充:LL-HLS 使用部分片段、阻塞式播放清單重新載入與預載入提示(Apple 以 EXT-X-PRELOAD-HINT 取代了之前的 HTTP/2 push 設計),而 LL-DASH 使用 chunked-transfer-encoded 片段與 Common Media Application Format Live 設定檔。兩者都瞄準量產環境中 2–5 秒的端到端延遲。若需要次秒級延遲,則要降到 WebRTC。

編碼器支援

DASH 從第一天起就對編碼器中立。H.264、H.265、VP9、AV1、AAC、Opus、FLAC、AC-4——manifest 宣告編碼器字串,由播放器決定。HLS 最初只用 H.264,因為原版 iPhone 硬體要求如此。Apple 已穩步擴大支援:自 2017 年起在 fMP4 上支援 H.265、自 2018 年起支援 Dolby Vision 與 HDR10、自 iPhone 15 世代起支援 AV1。現代 HLS 不再被 H.264 鎖死,但該協定的編碼器歷史有 DASH 從未經歷過的延遲。

DRM

兩者都依賴以 AES 為基礎的片段層加密,但其上的 DRM 系統不同。DASH 通常使用 CENC 與 Widevine 和 PlayReady——單一加密檔同時與兩者運作,因為內容金鑰相同,只是授權請求格式不同。HLS 歷史上使用 FairPlay Streaming(僅限 Apple),加上越來越多透過 CMAF + CBCS 的 Widevine。一旦你的服務轉到 CMAF,同樣的加密片段可以同時服務兩種 manifest 類型與三大 DRM 系統。

Apple/iOS 支援

HLS 在 iOS、iPadOS、Safari 和 Apple TV 上是強制的。DASH 在任何 Apple 平台上都不原生支援。 這是 DASH 對 HLS 策略上最大的決定性因素。Safari 上的 DASH 播放只能透過 Media Source Extensions 加上像 shaka-playerdash.js 這樣的 JavaScript 墊片實現,即便如此也無法涵蓋每個 iOS 邊角情況(AirPlay、鎖定畫面控制、子母畫面)。任何瞄準 iPhone 的服務都必須提供 HLS。只提供 DASH 是不可行的。

CDN 相容性與 CMAF 收斂

兩個協定都是純 HTTP。任何能提供靜態檔案的 CDN 都能提供 DASH 或 HLS 串流——CDN 成本與設定基本相同。過去十年最重要的發展是 DASH 與 HLS 現在共享片段位元組。CMAF——Common Media Application Format,ISO/IEC 23000-19——定義了一個能同時滿足 DASH 和現代 HLS 的 fragmented-MP4 設定檔。串流服務可以一次編碼為 CMAF 片段,然後寫出指向同一組 .m4s 檔案的 .mpd.m3u8。這正是 2026 年 YouTube、Netflix、Apple 與大多數託管影片供應商實際在做的事。

2026 年各家服務提供什麼

  • Netflix——網頁、Windows、Android、智慧電視與主機上以 DASH 為主;Safari 與 iOS 以 HLS 作為後備。
  • YouTube——網頁與 Android 上採 DASH 加 VP9 / AV1;iOS、Safari、AirPlay 與多數 TV 應用採 HLS。
  • Apple TV+、iTunes Store——僅使用 HLS。
  • Twitch——自 2014 年退役 RTMP 播放後,直播與 VOD 都僅使用 HLS。
  • Disney+、Hulu、Max、Amazon Prime Video——依用戶端使用 DASH 或 HLS,常用相同 CMAF 片段套兩種 manifest。

HLS 擁有 Apple 裝置,並與 DASH 分享其餘市場。多數主要服務同時支援兩者,因為另一個選擇是放棄一群觀眾。

如果你想儲存影片,這意味著什麼

了解 DASH 的運作後,實際的下載問題就變得具體。HLS 使用者試圖儲存串流時遇到的每一個問題,DASH 都有,而且常常更糟:

  • 瀏覽器的「另存為」只拿到 .mpd 那是 XML manifest。它包含零個影片位元組。在 VLC 中開啟只在網路工作階段仍有效且片段 URL 還沒過期時可行。
  • DASH 片段是 .m4s——每個 Representation 一個初始化片段加上數十至數百個媒體片段。每個都是單獨無用的 fragmented-MP4 區塊。要拿到單一可播放檔,你必須抓取初始化片段加上每個媒體片段(按順序),並重新封裝它們。(若你對 .m4s 內部實際上是什麼還不太清楚,請見容器 vs 編碼器。)
  • 你得解析 XML、走訪 SegmentTemplate URL,並重新封裝。 這意味著要寫懂得 $Number$$Time$$RepresentationID$$Bandwidth$ 佔位符的程式碼、組裝 URL、在不轟炸 CDN 的情況下並行抓取它們,並把位元組餵給 ffmpegmp4box。這不是週末腳本——這是真正的軟體。
  • 變體選擇很重要。 選錯 Representation 就會下載到一部 1080p 電影的 480p 副本。令牌也會過期——許多 .mpd 和片段 URL 都有簽署,幾分鐘就失效。

VidMost 處理這一切。它解析 .mpd、挑選最高畫質的視訊和音訊 Representation、並行下載每個片段,並把 CMAF fragment 重新封裝為單一乾淨的 MP4。對於 DRM 保護的 DASH 串流(常見的 Widevine + PlayReady 設定),VidMost 的內建 Widevine L3 支援會在 L3 播放可行之處生效——實際畫質上限由服務和 DRM 等級決定,而高級平台通常將 L3 串流上限設在 480p–720p。你貼上 URL;你拿到一個 MP4。

常見的陷阱與誤解

關於 DASH 的一些混淆在論壇討論串中經常出現。值得釐清。

  • 「MPEG-DASH 是 Google 的東西。」 不是。DASH 是 MPEG / ISO 開放標準(ISO/IEC 23009-1),由包含 Adobe、Microsoft、Netflix 和 Qualcomm 在內的 DASH Industry Forum 推動。Google 協助開發它並在 YouTube 上使用,但沒有任何單一廠商擁有規格。
  • 「DASH 比較新所以比較好。」 DASH(2012)比 HLS(2009)新,但「比較好」要看你的平台組合。若你的觀眾在 iPhone 上,HLS 因強制力勝出。若你的觀眾在 Android 和需要編碼器最大彈性的智慧電視上,DASH 勝出。多數服務兩者皆提供。
  • .mpd 就是影片。」 不是。它是 manifest。實際影片活在 manifest 所引用的 .m4s 片段中。
  • 「若網站使用 DASH,我的 HLS 播放器就不能播放。」 對原生播放器來說是這樣。但多數現代網頁播放器——shaka-player、dash.js、hls.js、video.js——在瀏覽器內透過 Media Source Extensions 把片段餵給 video 元素,可同時處理兩者。
  • 「DASH 一定代表 DRM。」 不是。許多 DASH 串流不加密:直播事件、教育平台與多數免費 YouTube 內容。DRM 是透過 ContentProtection 元素宣告的可選層。

結語

DASH 是 HLS 的平行宇宙雙胞胎。兩者都把影片切成短片段、在 manifest 中描述它們,並透過普通 HTTP 傳送。差異——XML 對純文字、ISO 標準對 Apple 規格、編碼器中立對受編碼器歷史影響——在業界內很重要,對觀眾卻很少重要。重要的是,向全世界每家製片廠取得授權內容的串流服務都已穩定採用這兩個協定,越來越收斂到兩種 manifest 下共用 CMAF 片段。一旦你能辨識 .mpd 請求並理解 Period / AdaptationSet / Representation 階層,現代串流的奇怪行為就不再神秘——一切都是同一個迴圈:抓 manifest、挑變體、抓片段、解碼、重複。如果你寧可完全跳過協定層、直接儲存影片,VidMost 處理 HLS、MPEG-DASH、fMP4、CMAF 和 DRM 保護的串流。

延伸閱讀

常見問題

什麼是 MPEG-DASH?
MPEG-DASH 是 Dynamic Adaptive Streaming over HTTP 的縮寫。它是 ISO/IEC 23009-1 標準,把影音以一連串短片段透過開放網路傳送,由一個稱為 .mpd 的 XML manifest 描述。DASH 播放器讀取 manifest、挑選它認為連線能維持的畫質等級,再透過普通 HTTPS 抓取片段——條件改變時於片段之間切換到不同畫質。這是 YouTube 和 Netflix 大部分背後的協定。
什麼是 .mpd 檔案?
.mpd 是 DASH 串流的 Media Presentation Description——一份 XML 文件,告訴播放器播放串流所需的一切。它列出 Period(時間切片)、AdaptationSet(每個視訊、音訊語言或字幕軌一個)、Representation(每個畫質等級)、編碼器字串,以及播放器用以抓取每個片段的 URL 範本。它包含零個影片位元組。只儲存 .mpd 拿到的是沒有食材的食譜,和 HLS 中的 .m3u8 一樣。
DASH 和 HLS 哪個比較好?
沒有哪一個普遍比較好——它們服務不同市場。DASH 對編碼器中立、由 ISO 標準化,是 YouTube、Netflix 和多數智慧電視與 Android 裝置的預設。HLS 在 iPhone、iPad、Mac 和 Apple TV 上是強制的;它的文字 manifest 較簡單,CDN 工具更廣。2026 年多數主要串流服務兩者皆提供,常從同一組 CMAF 片段在兩種不同 manifest 下提供。誠實的答案是「你的目標平台要求什麼就用什麼」。
YouTube 為什麼同時使用 DASH 和 HLS?
YouTube 在網頁和 Android 上的主要協定是 MPEG-DASH,這讓它可以高效率地提供 VP9 和 AV1 視訊。但 Apple 平台——iPhone、iPad、Mac Safari、Apple TV、AirPlay——沒有原生 DASH 解碼器,因此 YouTube 對那些用戶端提供 HLS,以觸及 iOS 觀眾。底層的媒體常常是同一組 CMAF 片段,套上兩種 manifest。在 Android 的 Chrome 上打開 YouTube 你會看到 .mpd 請求;在 Safari 上打開則會看到 .m3u8 請求。
iOS 為什麼不原生支援 DASH?
Apple 在 2009 年發明 HLS,之後每個 Apple 平台都把它內建。iOS、iPadOS、Safari 和 tvOS 內建沒有 MPEG-DASH 解碼器——Apple App Store 規範另要求透過行動網路串流的應用必須使用 HLS。Safari 上的 DASH 播放只能透過 Media Source Extensions 加上像 shaka-player 或 dash.js 這樣的 JavaScript 墊片實現,這會增加 CPU 負擔,且不總是像原生 HLS 那麼順。這就是為什麼認真要在 iPhone 上播放的服務都會提供 HLS。
DASH 串流可以下載嗎?
不能靠右鍵下載。儲存 .mpd 拿到的是 XML manifest,不是影片——位元組在 SegmentTemplate URL 所引用的數十至數百個獨立的 .m4s 片段檔中。要拿到單一可播放檔,你必須解析 .mpd、走訪 URL 範本、抓取每個片段,並把它們重新封裝為 MP4 或 MKV。像 VidMost 這類專用工具會自動化整個流程。對於 DRM 保護的 DASH(Widevine、PlayReady),沒有有效授權的話這也不夠。
什麼是 Common Media Application Format(CMAF)?
CMAF 是 ISO/IEC 23000-19,一種標準化的 fragmented-MP4 格式,設計目的是讓同一組媒體片段同時服務 HLS 和 MPEG-DASH 播放器。服務不需編碼兩次——一次給 HLS 用 .ts、一次給 DASH 用 fMP4——而是一次編成 CMAF,並提供兩種 manifest(.m3u8 和 .mpd),它們指向同一組 .m4s 檔案。這能省下一半的儲存與 CDN 成本,如今是 YouTube、Netflix、Apple 與多數主要託管影片供應商的預設。
.mpd 和 .m3u8 是同一回事嗎?
它們做的是同樣的工作——向播放器描述串流的片段——但是不同格式。.m3u8 是 HLS 所用、帶有 #EXT-X- 標籤的 UTF-8 文字播放清單。.mpd 是 MPEG-DASH 所用的 XML 文件。兩者都列出片段 URL、時長與畫質變體,但語法毫無關聯。原生 HLS 播放器無法讀取 .mpd,原生 DASH 播放器無法讀取 .m3u8,雖然像 shaka-player 和 video.js 這類 JavaScript 播放器透過 Media Source Extensions 在瀏覽器內處理兩者。