怎么把一个 M3U8 存成完整的 MP4(分步操作)
这件事看起来是”点一下转换”,实际有四道关:选对码率、拿全分片、正确合并、验证结果。
任何一道出错,表现都不是”打不开”,而是”能播但不对”——有声音没画面、播到一半跳画面、时长少一截。这类问题最难排查,因为文件看起来是好的。
下面按顺序走,每步都写了怎么确认它做对了。
开始之前,先确认三件事
1. 你有权保存这段内容。 自己的、已获授权的、平台明确允许下载的。带 DRM 的流不在本文范围内。
2. 清单里没有 DRM。 判断方法在 拿到 M3U8 先看这四行 里,重点看 #EXT-X-KEY 的 METHOD 是不是 SAMPLE-AES。
3. 磁盘够用。 按码率估算:1080p 每分钟约 2245 MB,一小时就是 1.32.7 GB。别笑,见过下到 90% 报磁盘满的。
第 1 步:选码率,不要默认最高
如果清单是主清单(出现 #EXT-X-STREAM-INF),先定要哪一档。
判断依据不是”越高越好”,而是三件事:
- 用途:存档取最高;发群、手机看,1080p 足够
- 源的上限:源本身只有 2 Mbps 时,选 5 Mbps 那档不会更清晰,只会更大
- 体积预算:用
BANDWIDTH ÷ 8 ÷ 1024 × 60估出每分钟 MB 数
一个常见误判:以为选了高码率就能”提升画质”。不可能。你只能保留,不能创造。
第 2 步:下载
方式 A:浏览器工具
打开 FlowPick 的 M3U8 / HLS Downloader,贴清单地址,选清晰度,下载。
适合:文件不大、不想装东西、需要在手机上完成。
边界要说清楚:浏览器受可用内存限制,超过 1 GB 容易中途失败,几个 GB 的量级别硬撑。
方式 B:FFmpeg 直接读清单
1 | ffmpeg -i "https://example.com/index.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4 |
适合:大文件、批量、需要精确控制。
三个要点:
- **必须加
-c copy**。不加的话它会解码重编码,画质掉一档,耗时高一个量级 -bsf:a aac_adtstoasc修 AAC 音频在 MP4 里的头信息,省掉后面音画同步的麻烦- 网络不稳时,在
-i之前加重连参数:
1 | ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 \ |
方式 C:分片已经在本地了
那就直接跳到第 3 步做合并。
第 3 步:合并散片
1 | ffmpeg -f concat -safe 0 -i list.txt -c copy -bsf:a aac_adtstoasc output.mp4 |
这一步唯一容易错的地方是顺序。
- 文件名补零(
segment_0001.ts)→ 默认排序就是对的 - 没补零(
1.ts、2.ts、10.ts)→ 必须自然排序,否则10.ts会排在2.ts前面
生成列表的命令和排序坑,写在 ffmpeg 合并 TS 文件完整教程 里,不再重复。
生成列表后花十秒用记事本看一眼第一行和最后一行。顺序错了,合出来的视频会在中间跳画面、断声音,而且事后很难定位。
第 4 步:验证(最容易被跳过的一步)
1 | ffprobe -hide_banner output.mp4 |
看三样:
① Duration 对不对。 和预期比,差一两秒正常(切片边界),差几十秒说明有分片没下全。
② 有没有两条 Stream。 一条 Video、一条 Audio。只有一条,说明源就是单流的,或者合并时丢了一路。
③ 抽样播放。 开头、正中间、结尾各看 10 秒。中间那段最关键——分片缺失的问题通常在中段暴露。
再补一个动作:跳到视频最后 30 秒,看口型对不对。音画不同步是累积误差,开头几秒往往看不出来,结尾最明显。
失败对照
| 现象 | 大概率原因 | 处理 |
|---|---|---|
| 播放正常但没有声音 | 源是 DASH 分离流,或音频编码 MP4 不支持 | 确认是否只下了一路;音频转 AAC |
| 播到中间跳画面 | 分片顺序错 | 重新生成列表,用自然排序 |
| 时长明显短于预期 | 分片没下全 / 直播滚动窗口 | 核对分片数;直播类重新评估 |
| 花屏、绿块 | 加密流缺密钥,或 fMP4 漏了 init 段 | 找密钥;确认带 #EXT-X-MAP |
| 下载到一半 403 | 签名 URL 过期 | 缩短下载窗口,或分段时间下 |
| 音画越到后面越偏 | 时间戳不连续 | 加 -fflags +genpts 重试 |
加密流:能做的和不做的
METHOD=AES-128,且你手上有密钥 → 可以处理。浏览器工具支持上传密钥文件;命令行需要把清单里的密钥 URI 指向本地文件。METHOD=SAMPLE-AES或 MPD 里有ContentProtection→ DRM。密钥由 CDM 管理,这不是技术难度问题,是授权问题,不在可操作范围。
分清这两者,能省掉很多无效尝试。
小结
四步:选码率 → 下载 → 合并 → 验证。
其中第 1 步和第 4 步最容易被跳过,而它们恰恰决定了结果”对不对”:选错码率白占空间,跳过验证则要等到几天后打开才发现问题。
本文命令基于 2026 年 11 月的 FFmpeg 版本。各平台清单写法不同,具体以你手上那份为准。