用 IDM 嗅探到视频链接,下载完打开文件夹,是几百个 .ts 碎片。用猫抓取网页视频,下来的是 segment-00001.ts 到 segment-00248.ts。用 M3U8 下载器搬了场直播回放,结果也不是 MP4,是一堆切片。

不管用的是哪种下载工具,下载完之后要处理的问题是一样的:把几百个 TS 按正确顺序拼回去。

这篇讲清楚三件事:为什么会这样、合并的正确做法、以及最容易翻车的两个点(排序和加密)。


先说清楚合规边界

这篇文章讲的是视频文件格式的处理技术,适用对象是你自己拥有权利的内容:自己录制的 HLS 流、公司自有平台的课程、你自己服务器上的资源,或者平台明确提供下载的内容。

受版权保护的影视、付费课程等内容的下载与二次分发不在本文讨论范围内,也不建议这么做。这条边界请自己把握。


为什么下载下来是一堆碎片

IDM、猫抓、M3U8 下载器,底层跟的是同一套机制:HLS(HTTP Live Streaming)。

视频站点把一整段视频切成若干小片段(每个几秒到十几秒),每个片段是一个 .ts 文件,再用一个叫 index.m3u8 的播放列表文件记录顺序。播放器按 playlist 顺序逐个拉取播放。

你的下载工具做的是:解析 M3U8 → 逐个下载 TS 分片 → 保存到本地。多数工具到这里就结束了,不会顺便帮你合并。

顺带说明 M3U8 是什么——它是个纯文本文件,用记事本就能打开,里面是一串 TS 文件名(或 URL)和顺序标记。合并顺序搞不清楚的时候,它就是你的对照表。


合并前必须确认的两件事

TS 合并前:排序比点击合并更重要(示意图)

图:以下用 1、2、10、100 四个分片说明两种排序的区别。

这两步跳过的话,后面大概率要返工。

1. 有没有加密

随便挑一个 TS 文件,用本地播放器(VLC 之类)打开试试。能正常播放,说明没加密;出现花屏、只有噪点、或者直接打不开,很可能加密了。

加密的流,M3U8 里会有这么一行:

1
#EXT-X-KEY:METHOD=AES-128,URI="https://.../key.bin"

这种情况下直接合并是合不出东西的,得先把密钥找出来。见后文。

2. 顺序对不对

合并最常出的问题是排序。文件名的字典序和数字序不一样:

1
2
字典序:video(1).ts → video(10).ts → video(100).ts → video(2).ts ...
数字序:video(1).ts → video(2).ts → ... → video(10).ts → ...

如果文件名是补零的(segment_0001.ts、segment_0002.ts),两种排序结果一致,不会出问题;如果是 1.ts、2.ts、…、10.ts,直接用默认排序就会得到一个顺序全乱的视频——画面会跳、声音会断。


方案一:浏览器合并(不需要装东西)

三个 TS 测试分片已加载,显示文件统计、按编号排序与开始合并
展开清晰大图(左右滑动查看)
打开原图

实拍(2026-10-30):已选择 segment_000.ts、segment_001.ts、segment_002.ts,并点击「按编号排序」;确认列表后再点「开始合并」。来源:EZ在线工具网;使用合成测试素材演示,点击图片可放大。

把 TS 分片合成一个完整视频(示意图)

图:先核对来源与播放顺序,再进行合并。

打开 ezwebtools.net/ts-merge,把所有 .ts 拖进去,有密钥文件的话一起拖进去,确认顺序后点合并,下载 MP4。

适合的情况:不想装软件、文件数量在几十到几百、想在手机上直接处理。整个处理过程在浏览器本地完成,文件不上传。

需要注意的是:几百 MB 以上的文件在浏览器里容易碰到内存上限,这时候用方案二更稳。


方案二:FFmpeg 本地合并(大文件、批量)

生成正确排序的文件列表

macOS / Linux

命名是补零的,用 ls 的默认顺序就行:

1
printf "file '%s'\n" *.ts > list.txt

命名没有补零,用版本排序:

1
ls *.ts | sort -V | sed "s/^/file '/; s/$/'/" > list.txt

Windows PowerShell

1
2
3
4
Get-ChildItem *.ts |
Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(10, '0') }) } |
ForEach-Object { "file '$($_.Name)'" } |
Out-File -Encoding utf8 list.txt

这个写法把文件名里的数字左侧补零到 10 位再排序,能正确处理 video(2).ts 和 video(10).ts 的先后。

对于 IDM 那种 video(1).ts 命名(数字在括号里),把上面的 *.ts 换成 video(*).ts,提炼数字的逻辑要改成匹配括号里的数字:

1
2
3
4
Get-ChildItem "video(*).ts" |
Sort-Object { [int]($_.Name -replace '.*\((\d+)\).*', '$1') } |
ForEach-Object { "file '$($_.Name)'" } |
Out-File -Encoding utf8 list.txt

生成完 list.txt 之后,用记事本打开扫一眼,确认第一行是第一个分片。这一步省不得。

浏览器中打开本次实际使用的 list.txt,包含三个 TS 分片路径
展开清晰大图(左右滑动查看)
打开原图

实拍(2026-10-30):浏览器直接打开本次合并使用的原始 list.txt,每行是一个分片,顺序为 000、001、002。这是文件内容截图,不是终端截图。

核对时检查三件事:第一行是不是首个分片、有没有漏片、文件名是否与实际文件一致。可查看本次原始列表,或下载合成测试包自己复现;解压后在该目录执行文中的合并命令。

执行合并

1
ffmpeg -f concat -safe 0 -i list.txt -c copy -bsf:a aac_adtstoasc output.mp4
参数 作用
-f concat 用 concat 解复用器按列表顺序拼接
-safe 0 允许列表里出现绝对路径等特殊写法
-c copy 只换容器不重新编码,画质零损失、速度极快
-bsf:a aac_adtstoasc 将 AAC ADTS 转换为适配 MP4 的 AudioSpecificConfig 并移除 ADTS 头;不是修时间戳

千万不要漏掉 -c copy。 不带它的话 ffmpeg 会重新编码一遍,速度和画质都吃亏。

合并完之后务必检查:

1
ffprobe -hide_banner output.mp4

看 Duration 时长对不对,音视频流是不是都在。

本次实际合并成片的 ffprobe 检测输出,显示约 6.19 秒、H.264 视频和 AAC 音频
展开清晰大图(左右滑动查看)
打开原图

实拍(2026-10-30):三段合成 TS 合并后执行 ffprobe -hide_banner output.mp4,将实际输出保存为文本并在浏览器中打开。截图不是模拟的终端界面;日志仅将临时目录路径省略为文件名。

看 Duration 是否符合预期,再看是否同时出现 Video: h264 与 Audio: aac。本次样例为 640×360、时长约 6.19 秒,输出文件为 643438 字节;这些数值只是本次合成素材的结果,不是所有视频的固定参数。检测到音轨也不代表听感一定正常,仍应播放并抽查分片衔接。可查看原始检测输出和下载测试包。


加密的 TS 怎么处理

用浏览器工具

TS 文件选择区与可选密钥选择区分开显示
展开清晰大图(左右滑动查看)
打开原图

实拍(2026-10-30):TS 分片在上方选择;需要合法密钥时,通过下方独立入口选择,当前提示支持 .key 和 .txt。来源:EZ在线工具网;使用合成测试素材演示,点击图片可放大。

先通过 TS 文件选择区加入分片,再在独立的「上传密钥文件(可选)」区域选择合法取得的密钥。当前界面提示支持 .key 和 .txt;不能据此保证 .bin 可以直接选择。密钥找不到的话,打开 M3U8 找 #EXT-X-KEY 那行的 URI:

  • 指向本地文件名 → 在下载目录里找这个文件
  • 指向网 → 浏览器打开那个地址,把内容另存为本地文件

用 FFmpeg

FFmpeg 能处理标准的 HLS 加密流,前提是它拿得到密钥。做法是把 M3U8 下载到本地,把里面的 TS 路径和密钥 URI 改成本地相对路径,然后:

1
ffmpeg -allowed_extensions ALL -i index.m3u8 -c copy output.mp4

把修改前的 index.m3u8 备份一份,改动只涉及 URI 那一行和 TS 的文件路径部分。

如果你手上只有一个 M3U8 的网址,本地又没有密钥文件,也可以让 ffmpeg 自己去拉取:

1
ffmpeg -i "https://example.com/video/index.m3u8" -allowed_extensions ALL -c copy output.mp4

不过这种方式依赖网络和远端密钥的可访问性,失败的原因会比较难排查。实操上更稳的路子是先用下载器把 TS 落到本地,再走本地合并。


三种下载工具的处理要点

下载工具 常见命名 处理要点
IDM video(1).ts、video(2).ts 括号里的数字需要单独提取后排序
猫抓(CatCatch) segment_00001.ts、原始分片名 文件名多为原始名,注意密钥要单独抓取
M3U8 下载器(yt-dlp 等) 与 M3U8 内名称一致 通常自带 m3u8 和密钥,优先用本地合并

补充说明:IDM 偶尔只会抓到单个 TS 流而不是整个 M3U8 列表。这种情况下你下载到的只是其中一个片段,需要换 M3U8 下载器重新抓。


常见问题

Q:合并出来的视频顺序是乱的,画面跳来跳去?

排序问题,参考上面的”顺序对不对”一节。补零命名用默认排序即可,未补零的必须做自然排序。

Q:合并后播放花屏?

加密。去找 .key / .bin 文件,或者用播放器单独打开一个 TS 试试。

Q:合并后没有声音?

先用 ffprobe 检查源文件和输出是否都有音频流。若是 AAC ADTS 到 MP4 的封装问题,可检查 aac_adtstoasc 的使用;它不修复时间戳。也可能是 M3U8 的音轨和视频分别存储,需要分别取得并合并音轨。参数说明见 FFmpeg 官方文档。

Q:文件名全是乱码,没有数字顺序?

如果下载时保存了 M3U8,按 M3U8 里的顺序手动排列。没有 M3U8 的话,按文件修改时间排序通常可行(下载先后的顺序一般就是正确顺序),但对可以并行下载的工具不一定成立——所以尽量保留 M3U8。

Q:合并后时长不对,少了后面一截?

通常是有分片没下载完整,或者漏了几个。检查一下 TS 文件数量和 M3U8 里记录的数量是否一致。

Q:能不能干脆重新下载成 MP4?

如果 M3U8 还能访问,很多下载器(比如 yt-dlp)支持自动合并输出 MP4,比手动处理省事。能从源头获取合并结果的,就不需要自己拼。


小结

TS 合并的流程就四步:

  1. 判加密 — 播放器打开单个 TS 试试
  2. 定顺序 — 补零命名用默认排序,其余做自然排序,不确定就对照 M3U8
  3. 选工具 — 不想装软件用 ezwebtools.net/ts-merge,大文件或批量用 FFmpeg -c copy
  4. 验结果 — 看时长对不对、音画都在不在

其中最容易踩的两个坑就是排序和加密,处理好了基本一次过。

本文基于 2026 年 9 月的工具版本整理,命令以 FFmpeg 当前版本为准。