什么是 DASH 流媒体?面向非开发者的 MPD 文件解析
你尝试下载一段视频,结果不是 MP4,而是一个 12KB 的 .mpd 文件。用文本编辑器打开——满屏 XML,几百个 <SegmentURL> 标签,指向的文件根本不在你磁盘上。
这就是 MPEG-DASH。下面解释它是什么、平台为什么用它,以及如何真正把视频取出来。
DASH 解决了什么问题
回到 2008 年。YouTube 在传输固定码率的 FLV 文件。网速慢的时候,有人上传了 720p 视频,你只能看着转圈圈。唯一的办法是手动切到 360p。
这对平台来说很尴尬。行业找到的解决方案:不传固定文件,而是传一个描述所有可用画质的清单,让播放器根据实时带宽测量自己决定请求哪个。
苹果的 HLS 和 ISO 标准的 DASH(2012 年)都解决了这个问题。DASH——动态自适应 HTTP 流媒体——成为了国际标准:YouTube、Vimeo、Dailymotion 和大多数企业视频平台都在用。
主流平台使用 DASH 的情况
了解哪些平台在用 DASH,有助于你判断下载时会遇到什么情况:
| 平台 | 流媒体协议 | 备注 |
|---|---|---|
| YouTube | DASH | 主要使用 DASH,部分内容也走 HLS |
| Bilibili | DASH(普通内容)+ HLS(直播) | 音视频分离,需要合并 |
| Vimeo | DASH | 企业版内容也走 DASH |
| Twitch | HLS | 直播走 HLS,VOD 有时走 DASH |
| Coursera / edX | DASH | 课程视频普遍使用 |
| 腾讯视频 / 优酷 / 爱奇艺 | DASH + DRM | 高价值内容叠加 Widevine |
YouTube 是个有意思的案例——它 2011 年就开始部署 DASH,是最早大规模使用的平台之一,现在每天服务数十亿次流媒体请求全靠这套机制。B 站也是 DASH 重度用户,普通视频走 DASH、直播走 HLS,如何下载 Bilibili 视频到本地 里完整走了一遍 B 站的下载流程,是理解 DASH 实战的好案例。
MPD 文件:不是视频,是配方
每个 DASH 流都从一个 MPD 文件开始——媒体展示描述(Media Presentation Description)。它是一个 XML 文档,描述整个流:时长、可用画质、编解码信息,以及找到每个视频和音频分片的路径。
一个真实的简化 MPD:
<?xml version="1.0" encoding="UTF-8"?>
<MPD type="static" mediaPresentationDuration="PT1H23M47S">
<Period>
<AdaptationSet contentType="video" mimeType="video/mp4">
<Representation id="v1080" bandwidth="4500000" width="1920" height="1080">
<SegmentTemplate
initialization="video/1080p/init.mp4"
media="video/1080p/seg-$Number$.m4s"
startNumber="1" />
</Representation>
<Representation id="v720" bandwidth="2000000" width="1280" height="720">
<SegmentTemplate
initialization="video/720p/init.mp4"
media="video/720p/seg-$Number$.m4s"
startNumber="1" />
</Representation>
</AdaptationSet>
<AdaptationSet contentType="audio" mimeType="audio/mp4">
<Representation id="a128" bandwidth="128000">
<SegmentTemplate
initialization="audio/init.mp4"
media="audio/seg-$Number$.m4s"
startNumber="1" />
</Representation>
</AdaptationSet>
</Period>
</MPD>
结构说明:
<AdaptationSet>:等效轨道的组合——所有视频选项,或所有音频选项<Representation>:该组内的一个具体画质/编解码组合<SegmentTemplate>:分片文件的 URL 模板
模板 video/1080p/seg-$Number$.m4s 展开为 seg-1.m4s、seg-2.m4s……可能有几千个文件。
音视频分离:DASH 的核心设计
DASH 最让下载者头疼的地方在于音频和视频是两条独立的流。这不是故意刁难,而是设计使然:
想象你要给一个视频配 5 种语言的音轨。如果音视频合在一起,你需要存 5 份完整视频文件,服务器存储成本翻 5 倍。DASH 的做法是:一份视频轨,5 份音频轨,播放器根据语言设置组合。存储成本大幅降低。
对下载者来说,这意味着:
- 必须同时下载视频轨和音频轨
- 下载完成后必须合并成一个文件
- 只下视频——没声音;只下音频——看不了
FlowPick 会自动检测 MPD 里的所有 AdaptationSet,帮你同时下载并合并。合并这一步听起来简单,实际在浏览器里跑 FFmpeg WASM 有不少坑,详细的拆解看 FlowPick 是怎么在浏览器里把切片合成 MP4 的。

DASH 与 HLS:有什么区别?
如果你已经读过 如何下载 M3U8/HLS 流,就知道 HLS 用 .m3u8 文件和 .ts 分片。DASH 用 .mpd 文件和 .m4s 分片。目标相同——自适应流媒体——但细节有明显差异。
| DASH | HLS | |
|---|---|---|
| 来源 | ISO/IEC 23009,2012 | 苹果,2009 |
| 清单格式 | XML(.mpd) | 纯文本(.m3u8) |
| 分片格式 | fMP4(.m4s)或 MP4 | MPEG-TS(.ts) |
| 音频处理 | 独立轨道 | 与视频合并 |
| 加密方式 | CENC(Widevine/PlayReady) | AES-128(密钥可获取) |
| 谁在用 | YouTube、Vimeo、企业平台 | Twitch、苹果平台 |
关键实际区别:DASH 把音频和视频分开。视频文件没有音频,音频文件没有视频。需要同时下载两者并合并。
另一个重要区别是加密:HLS 常见的 AES-128 加密中,密钥可以通过正常的 HTTP 请求获取(登录状态下);DASH 的 CENC 加密走 Widevine/PlayReady 授权体系,密钥绑定到设备,无法通过浏览器扩展获取。
为什么 DASH 视频正常情况下根本下不了
综合来看,这就是为什么什么方法都不好使:
1. 根本没有视频文件。 MPD 是蓝图。实际内容分散在 CDN 的几百个 .m4s 分片里。
2. 音频和视频是独立轨道。 即使你能下载所有视频分片,文件也没有声音。音频分片是完全独立的下载路径。
3. 分片 URL 通常包含签名令牌。 典型分片 URL 长这样:https://cdn.example.com/video/seg-42.m4s?token=eyJhbGc...&expires=1735689600。这个令牌有时间限制,绑定到你的会话。
4. 初始化分片很重要。 视频和音频轨道都以"初始化分片"(init.mp4)开头,包含编解码参数。没有它,播放器无法解析后续分片。
5. 内容保护(CENC)。 高价值内容在 DASH 上面叠加 Widevine 或 PlayReady DRM,每个分片都被加密,密钥通过独立的授权服务器下发。
FlowPick 如何下载 DASH 流
FlowPick 在浏览器标签页内拦截 MPD 请求。当你登录某个平台,你的会话 Cookie 随请求传递——FlowPick 看到的清单和你的播放器看到的一样。
下载流水线:
- 解析 MPD XML — 提取所有
AdaptationSet和Representation条目 - 展示画质选项 — 显示可用的视频分辨率和音频轨道
- 并行下载 — 视频和音频分片同时下载,线程数由设置决定(默认2个,可调整)
- 先获取初始化分片 — 这些文件小但对合并来说必不可少
- 在内存中拼装 — 按顺序拼接初始化 + 所有分片
- 合并视频与音频 — 用编译为 WebAssembly 的 FFmpeg,完全在浏览器标签页内运行
- 写入磁盘 — 通过 Chrome/Edge 的 File System Access API,或 Firefox 的直接下载 blob
整个流水线在客户端运行,没有上传,分片从不经过第三方服务器。
如果你有独立的 MPD URL,也可以直接粘贴到 DASH 在线下载工具,无需安装任何东西。
在线工具 vs 扩展:该用哪个
对于 DASH 下载,两种方式各有场景:
| 场景 | 推荐方式 |
|---|---|
| 有独立的 MPD URL,公开流 | 在线工具,无需安装 |
| 需要登录才能访问的内容 | 浏览器扩展,携带会话 Cookie |
| 平台用 POST 请求获取清单 | 浏览器扩展,能在网络层拦截 |
| 平台混淆了 MPD URL | 浏览器扩展,自动识别 |
| 分片 URL 有时效限制 | 浏览器扩展,实时获取 |
在线工具受浏览器跨域(CORS)策略限制——如果视频托管服务器没有配置 CORS 头,在线工具直接下载会失败。这时扩展更可靠。
在野外识别 DASH
想知道某个网站是否用 DASH?在视频加载前打开开发者工具:
- F12 → Network 标签
- 过滤框输入
.mpd或manifest - 播放视频
- 找
Content-Type: application/dash+xml的请求
找到了——这就是入口。该请求的 URL 就是粘贴到在线工具的内容,也是 FlowPick 自动拦截的目标。
有些平台混淆 URL 或用 POST 而非 GET 请求清单。这时在线工具不管用,但浏览器扩展可以,因为它在网络拦截层捕获请求,不管用什么方法。
直播流:完全不同的情况
静态 DASH 流(电影、录制课程)有 type="static" 属性和已知的 mediaPresentationDuration。直播流用 type="dynamic":
<MPD type="dynamic"
availabilityStartTime="2026-07-01T09:00:00Z"
minimumUpdatePeriod="PT5S"
timeShiftBufferDepth="PT1H">
MPD 不断更新(本例每 5 秒),只有一个滚动窗口内的分片可用。一旦分片超出 timeShiftBufferDepth,就从 CDN 消失了。
对于直播流,FlowPick 从你开始录制的那一刻起捕获——无法回溯超过当前缓冲区。对于过去的直播内容,找回放/VOD URL,那是一个静态 DASH 或 HLS 流,可以干净下载。
常见问题
下了 MPD 文件,打不开
MPD 不是视频文件,是清单文件。你需要工具解析它并按顺序下载所有分片再合并。直接用视频播放器打开 MPD 通常没用(VLC 是个例外,支持直接播放 DASH URL)。
下载时音频和视频分开了
你只下了视频轨或音频轨其中一个。检查 FlowPick 是否同时下载了两个 AdaptationSet——看弹窗里是否有独立的音频条目被选中。如果两条轨道都下了但没有合并,可能遇到了 FFmpeg WASM 内存限制(文件过大),尝试选择低一档画质。
分片下载成功但合并失败
常见于超大文件(>4GB)场景。FFmpeg WASM 在 32 位地址空间下有内存限制。遇到这种情况,FlowPick 会尝试切换到其他合并策略。建议用 Chrome 最新版,FSA 流式写入对大文件处理最稳定。
推荐阅读
- 如何下载 M3U8/HLS 流:完整入门指南 — DASH 的兄弟协议,方法略有不同
- FlowPick 是怎么在浏览器里把切片合成 MP4 的 — FFmpeg WASM 怎么在浏览器里把音视频轨合到一起
- 如何下载 Bilibili 视频到本地 — B 站是 DASH 重度平台,实战案例
- 嗅探并下载网页音频:播客、BGM、有声书一网打尽 — DASH 独立音轨怎么单独下载
- FlowPick 与 Video DownloadHelper 对比 — 真实对比,不是广告