TS(Transport Stream)文件经常出现在网络视频分片、直播录制以及部分下载任务中。一个完整的视频可能被拆分成多个 .ts 文件,例如 001.ts、002.ts、003.ts 等。单独播放没有问题,但想获得一个完整的视频文件,就需要进行合并。
对于 Mac 用户来说,FFmpeg 是处理这类任务非常实用的工具。它支持 macOS,并且可以通过命令行快速完成 TS 文件合并,同时避免重新编码带来的画质损失。
一、Mac安装FFmpeg
如果 Mac 尚未安装 FFmpeg,可以使用 Homebrew 安装。打开“终端”,执行:
Bashbrew install ffmpeg
安装完成后检查版本:
Bashffmpeg -version
能够看到 FFmpeg 的版本信息,就说明安装成功。
如果系统提示 brew: command not found,说明还没有安装 Homebrew,需要先完成 Homebrew 的安装。
二、准备需要合并的TS文件
假设当前目录中有以下文件:
001.ts 002.ts 003.ts 004.ts
首先进入这些文件所在的目录。例如文件保存在桌面的 video 文件夹:
Bashcd ~/Desktop/video
可以使用 ls 查看当前文件:
Bashls
确认所有 TS 文件都在同一个目录中。
文件顺序非常重要
TS 文件通常具有严格的播放顺序。如果原始视频依次是:
001.ts 002.ts 003.ts 004.ts
那么合并时也必须按照这个顺序处理。
如果文件名称是:
1.ts 2.ts 10.ts 11.ts
直接使用某些通配符命令时,可能得到:
1.ts 10.ts 11.ts 2.ts
这显然不是正确的视频顺序。
因此,建议将文件命名为:
001.ts 002.ts 003.ts ... 010.ts 011.ts
通过补零方式保证文件名具有正确的字典排序。
三、使用FFmpeg直接合并TS文件
对于编码格式一致、分片结构正常的 TS 文件,最简单的方法是使用 concat 协议:
Bashffmpeg -i "concat:001.ts|002.ts|003.ts|004.ts" -c copy output.ts
这里的参数含义如下:
-
-i:指定输入文件。 -
concat::使用 FFmpeg 的 concat 协议连接多个 TS 文件。 -
|:分隔不同的 TS 文件。 -
-c copy:直接复制音视频数据,不进行重新编码。 -
output.ts:合并后的文件名。
这种方式速度通常非常快,因为 FFmpeg 不需要重新压缩视频和音频。
四、TS文件较多时使用文件列表
如果需要合并几十甚至几百个 TS 文件,把所有文件写在命令中会比较麻烦。这种情况下,更推荐使用 concat demuxer。
首先创建一个文本文件:
Bashtouch filelist.txt
然后编辑:
Bashnano filelist.txt
写入:
file '001.ts' file '002.ts' file '003.ts' file '004.ts'
保存后执行:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
这种方法更加适合批量合并。
其中:
Bash-f concat
表示使用 concat demuxer。
Bash-safe 0
允许使用更灵活的文件路径。如果列表中使用绝对路径,通常建议保留这个参数。
Bash-c copy
仍然表示直接复制原始音视频流。
五、自动生成TS文件列表
如果一个目录中存在大量按照顺序命名的 TS 文件,可以利用 Shell 命令自动生成列表。
例如:
Bashfor f in *.ts; do echo "file '$f'"; done > filelist.txt
随后查看:
Bashcat filelist.txt
可能得到:
file '001.ts' file '002.ts' file '003.ts' file '004.ts'
确认顺序正确后执行:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
这种方式特别适合处理大量分片文件。
不过需要注意,*.ts 的排序依赖文件名。对于 1.ts、2.ts、10.ts 这种命名方式,建议先重新命名,或者使用更可靠的排序方式生成列表。
例如:
Bashprintf "%s " *.ts | sort -V | while read f; do echo "file '$f'" done > filelist.txt
生成的列表可以通过:
Bashcat filelist.txt
检查。
六、直接合并并输出MP4
很多情况下,最终目的并不是得到一个 TS 文件,而是获得可以方便播放和分享的 MP4。
如果 TS 文件中的音视频编码格式本身适合 MP4 容器,可以尝试:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
FFmpeg 会将音视频流直接封装到 MP4 容器中,不重新编码。
因此,处理速度通常很快,而且不会因为重新编码造成额外画质损失。
不过需要注意,TS 能够直接复制到 MP4,并不意味着所有 TS 文件都可以无损封装成 MP4。最终是否成功取决于其中的视频、音频编码以及时间戳等信息。
七、为什么推荐使用-c copy
合并视频时,经常会看到两种处理方式。
第一种是直接复制:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
第二种是重新编码:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -c:a aac output.mp4
两者最大的区别就是是否重新编码。
使用:
Bash-c copy
FFmpeg 不会重新压缩视频和音频,因此具有几个明显优势:
-
处理速度快;
-
CPU占用相对较低;
-
不会产生重新编码导致的画质损失;
-
文件合并过程更加适合大量TS分片。
重新编码则需要重新压缩整个视频,耗时会明显增加。
因此,如果 TS 文件本身没有编码兼容性问题,优先使用 -c copy。
八、合并后出现画面或声音异常怎么办
并不是所有 TS 分片都可以简单地通过 -c copy 合并。有些 TS 文件可能来自不同的视频流、直播切片或者经过特殊处理的视频源。
常见问题包括:
-
合并后只有声音没有画面;
-
视频播放到某处出现卡顿;
-
音频逐渐不同步;
-
文件无法正常拖动进度条;
-
MP4 输出失败;
-
合并后视频时长显示错误。
遇到这种情况,可以先检查单个 TS 文件:
Bashffprobe 001.ts
也可以查看更详细的流信息:
Bashffprobe -v error -show_streams 001.ts
重点观察视频编码、音频编码、分辨率、帧率以及时间基等信息。
如果多个分片的编码参数并不一致,那么直接进行流复制可能无法得到正常结果。
九、必要时重新编码
如果确认 TS 分片之间存在兼容性问题,可以尝试重新编码:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -preset medium -crf 18 -c:a aac -b:a 192k output.mp4
其中:
Bash-c:v libx264
表示使用 H.264 编码视频。
Bash-crf 18
用于控制视频质量。CRF 数值越低,通常画质越高,同时文件体积也越大。
Bash-c:a aac
表示使用 AAC 编码音频。
Bash-b:a 192k
设置音频码率为 192 kbps。
重新编码的兼容性通常更好,但处理时间会明显增加,而且属于有损压缩过程。
十、处理时间戳异常
部分 TS 分片来自直播流,可能存在时间戳不连续的问题。这时 FFmpeg 可能输出类似警告:
Non-monotonous DTS
或者:
DTS out of order
如果最终视频可以正常播放,可以先检查实际效果。如果出现明显的音画不同步或播放异常,则需要进一步处理时间戳。
可以尝试:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy -avoid_negative_ts make_zero output.mp4
对于比较复杂的直播切片,还可能需要重新生成时间戳或重新编码。具体参数应根据 ffprobe 检查结果决定,不建议盲目堆叠参数。
十一、使用通配符直接合并是否可行
很多人会尝试:
Bashffmpeg -i "*.ts" -c copy output.ts
这种写法通常并不能按照预期工作。
原因是:
Bash*.ts
是 Shell 文件通配符,而 FFmpeg 的 -i 参数并不会把多个匹配文件自动理解为一个视频序列。
正确方式是先生成 concat 列表:
Bashfor f in *.ts; do echo "file '$f'"; done > filelist.txt
然后:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
这样处理更加稳定,也方便人工检查文件顺序。
十二、使用绝对路径合并TS文件
如果 TS 文件分布在其他目录,也可以在 filelist.txt 中使用绝对路径:
file '/Users/username/Desktop/video/001.ts' file '/Users/username/Desktop/video/002.ts' file '/Users/username/Desktop/video/003.ts'
然后:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
这里使用:
Bash-safe 0
是为了允许 concat demuxer 使用这些路径。
如果路径中包含空格,使用单引号包围路径:
file '/Users/username/Desktop/My Videos/001.ts'
十三、文件名包含特殊字符怎么办
如果 TS 文件名包含空格、单引号等特殊字符,手动创建列表时要格外注意。
例如:
file 'video 001.ts' file 'video 002.ts'
对于大量文件,更建议使用脚本自动生成列表,减少转义错误。
如果文件名称比较复杂,最简单的解决方式通常是先统一重命名,例如:
001.ts 002.ts 003.ts
再进行合并。
十四、合并完成后检查视频
合并完成后,不要只看 FFmpeg 是否执行结束,还应该检查最终文件。
可以使用:
Bashffprobe output.mp4
或者:
Bashffprobe -v error -show_format -show_streams output.mp4
检查:
-
视频是否存在;
-
音频是否存在;
-
视频时长是否正确;
-
编码格式是否符合预期;
-
文件容器是否正常。
也可以直接使用 Mac 上的播放器打开视频,拖动进度条测试开头、中间和结尾部分。
十五、一个完整的实用流程
假设桌面目录:
~/Desktop/ts-video/
里面有:
001.ts 002.ts 003.ts 004.ts 005.ts
首先进入目录:
Bashcd ~/Desktop/ts-video
自动生成列表:
Bashfor f in *.ts; do echo "file '$f'"; done > filelist.txt
查看列表:
Bashcat filelist.txt
确认顺序无误后直接合并:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
如果希望输出 MP4,可以尝试:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
如果 MP4 兼容性不好,再考虑重新编码:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -crf 18 -c:a aac -b:a 192k output.mp4
这套流程基本覆盖了 Mac 上常见的 TS 文件合并需求。
十六、几个容易忽略的问题
1. 不要删除原始TS文件
确认输出视频能够正常播放之前,建议保留所有原始分片。这样即使合并失败,也可以重新调整参数处理。
2. 合并不是重新编码
所谓“合并视频”并不一定需要重新压缩。对于编码一致的 TS 分片,使用:
Bash-c copy
通常是更合理的选择。
3. 文件顺序比命令本身更重要
如果分片顺序错误,即使 FFmpeg 命令执行成功,最终视频也可能出现剧情跳跃、声音错乱或者画面顺序异常。
4. 不要仅凭扩展名判断编码
所有文件都是 .ts,并不代表内部的视频和音频编码完全相同。遇到无法合并的问题时,应使用 ffprobe 检查实际流信息。
5. 输出MP4并非总能直接复制
TS 是一种传输流容器,而 MP4 是另一种媒体容器。两者支持的编码和时间戳机制存在差异,因此 -c copy 输出 MP4 失败并不意味着 TS 文件损坏。
十七、常用命令汇总
直接连接少量 TS 文件:
Bashffmpeg -i "concat:001.ts|002.ts|003.ts" -c copy output.ts
通过列表合并:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.ts
合并并封装为 MP4:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
重新编码为 H.264 + AAC:
Bashffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -crf 18 -c:a aac -b:a 192k output.mp4
检查媒体信息:
Bashffprobe -v error -show_streams output.mp4
自动生成文件列表:
Bashfor f in *.ts; do echo "file '$f'"; done > filelist.txt
对于 Mac 上的 TS 文件合并任务,优先推荐“整理文件顺序 → 生成 filelist.txt → FFmpeg concat → -c copy 无损合并 → 检查输出文件”这条路线。只有在编码不兼容、时间戳异常或输出容器存在兼容性问题时,再考虑重新编码。这样既能提高处理速度,也能尽可能保留原始视频质量。