M3U8 和 MPD 都有的时候,我为什么优先拿 HLS
现在不少站点同时挂着 .m3u8 和 .mpd。选哪个?
网上的答案大多在比协议优劣:XML 结构更严谨、CENC 加密更统一、苹果生态对 HLS 支持更好。这些都对,但对你手上这个文件几乎没有影响。
我的做法很干脆:两套都完整的话,优先 HLS。
理由不是 HLS 更好,而是它少一步
TS 分片天生把视频和音频复用在同一个流里。fMP4 分片通常只装一路。
这一个差别带来的后果是:
- HLS:下载 → 合并一次 → 得到完整文件
- DASH:下载视频 → 下载音频 → 各自合并 → 再拼一次 → 得到完整文件
多两个环节,就多两种出错的可能(音轨漏了、两路时间轴对不上、init 段只给了一路)。而”两种协议谁更先进”这件事,对你的输出质量没有任何影响。
判断标准就这么简单:能一次干完的,不要分两次。
三个常被当成”技术差异”的误判
误判一:DASH 画质更高
不会。同一个源、同样的编码器、同样的码率,画质就是一样的。
DASH 的 Representation 只是把码率阶梯写得更细(比如 14 档而不是 5 档),那是给弱网环境做平滑切换用的,不代表上限更高。
想验证不用猜,直接看数字:
1 | ffprobe -hide_banner -i "https://example.com/1080p/index.m3u8" |
对比两边 Stream 行里的分辨率和 bitrate。数字一样,画质就是一样。
误判二:DASH 合并必须重新编码
这条坑最深。很多教程一上来就让你 -c:v libx264,凭空损失一代画质、多花十倍时间,而你根本没这个必要。
fMP4 分片里装的本来就是标准的 H.264/AAC 数据,合并只是重封装:
1 | ffmpeg -i "https://example.com/manifest.mpd" -c copy output.mp4 |
-c copy 一个字符都不重编码,画质零损失。前提是你的 FFmpeg 带 DASH 解复用器(它依赖 libxml2,gyan.dev 的 full 构建和 BtbN 的构建都带)。跑 ffmpeg -demuxers,列表里能找到 dash 就行。
误判三:.m4s 可以像 TS 那样直接拼
不行。
.m4s 不含解码配置(SPS/PPS、声道布局这些),它们在 init.mp4 里。少了 init 段,拼出来的文件要么打不开,要么满屏花屏。
正确顺序是 init.mp4 + 1.m4s + 2.m4s + ...,或者干脆让 FFmpeg 读清单自己去拿 init。
音视频分离不是 bug,是设计
“下完发现没声音”是 DASH 最典型的现象,而且几乎每隔一段时间就会有人问一次。
原因不在工具:视频和音频在 MPD 里是两个独立的 AdaptationSet,各走各的分片序列、各有各的 init 段。你只选了视频那一路,自然没有声音。
确认方法很简单,看 MPD 里有没有成对出现:
1 | <AdaptationSet contentType="video" ...> |
两组都有,就得两路都下。合并时:
1 | ffmpeg -i video_only.mp4 -i audio_only.mp4 -c copy -map 0:v:0 -map 1:a:0 output.mp4 |
-map 0:v:0 取第一个文件的视频轨,-map 1:a:0 取第二个文件的音频轨。不加 -map 的话,ffmpeg 会自己挑,结果不一定是你想要的那一路。
什么情况下我反而选 DASH
上面说优先 HLS,是有前提的。下面这几种,HLS 反而更麻烦:
| 需求 | 为什么选 DASH |
|---|---|
| 需要多语言音轨 / 独立字幕 | AdaptationSet 把每条轨都拆成独立资源,取用更明确 |
| 目标内容只有 DASH | 没得选 |
| 需要 4K HDR | 部分平台只在 DASH 侧提供 HDR 变体 |
| 做归档 / 转码,需要精确码率阶梯 | Representation 列表更细,便于选档 |
注意第一条:多音轨是 DASH 的强项,不是 HLS 的。HLS 也能做多音轨(#EXT-X-MEDIA),但实际站点里支持得没有 DASH 普遍。要保多语言,先看 DASH 那边。
快速判断哪套更值得下
打开两个清单,比对三件事,两分钟能决定:
- 分片数量和时间轴是否一致 —— 不一致说明两套不是同一个版本,别混着下
- 音频是不是独立 AdaptationSet —— 决定你要不要合两路
- 分片扩展名 ——
.ts说明音视频已复用,.m4s说明要处理两路
三种结论:
- 两套都完整 → 选 HLS,少一步
- HLS 只有低码率、DASH 有你要的那档 → 选 DASH,接受多一步
- HLS 存在但没有 ENDLIST、DASH 是 static → 选 DASH,完整度优先
一个容易忽略的细节:两套的时长可能不一样
同一部片子,HLS 和 DASH 的时长偶尔会差几百毫秒到几秒。原因通常是切片边界不同,或者其中一套被平台重新处理过。
如果你在做对齐要求高的事(比如把两段素材拼在一起),以 ffprobe 读出来的实际时长为准,不要相信清单里声明的时长。清单里的 #EXTINF 累加和 MPD 的 mediaPresentationDuration 都可能和实际有偏差。
小结
- 两套都在时优先 HLS:理由是少一步合并,不是协议优劣
- 真正的差异只有三条:分片容器、音视频是否复用、DRM 体系
- “DASH 更清晰”和”DASH 必须重编码”都是误判,
-c copy就能无损合并 - 多音轨、HDR、或只有 DASH 时,才切到 DASH
- 没有声音不是 bug,是两路没都下
本文基于 2026 年 11 月的 DASH 标准(ISO/IEC 23009-1)与常见平台实现整理。不同站点的清单写法差异较大,具体以你手上那份为准。