使用 FFmpeg 进行无损视频合并是它的高频高效操作之一。无损合并的核心原理是直接复制视频和音频流(Stream Copy),而不进行重新编码(Re-encoding)。这样不仅速度极快(几秒钟就能搞定),而且能保证画质和音质绝对没有损失。
以下是为你整理的 FFmpeg 无损视频合并笔记,你可以直接复制到你的 Markdown 编辑器中。
📝 FFmpeg 无损视频合并指南
在使用 FFmpeg 无损合并视频前,必须确保一个核心前提:
⚠️ 所有待合并的视频片段,其分辨率、帧率(FPS)、视频编码格式(如 H.264/HEVC)以及音频编码格式(如 AAC/MP3)必须完全一致。 如果格式不一致,无损合并后可能会出现音画不同步、视频卡顿或无法播放的情况。
🛠️ 方法一:使用 Concat 协议(最快捷,推荐 MP4/TS)
如果你的视频是 .mp4 或 .ts 格式,且文件名没有特殊字符,最直接的方法是通过命令行传入一个视频列表。
1. 创建视频列表文件
在视频所在文件夹下,创建一个名为 filelist.txt 的文本文件,内容格式如下(每行一个视频,注意使用相对路径):
file 'input1.mp4'
file 'input2.mp4'
file 'input3.mp4'
2. 执行合并命令
打开终端或命令行,定位到该文件夹,运行以下命令:
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
🔍 参数详解:
-f concat:指定使用concat(拼接)分离器。-safe 0:允许使用相对路径和一些特殊字符(如果不加,文件名复杂时可能会报错)。-i filelist.txt:指定输入的内容为刚刚创建的文本文件。-c copy:最关键的参数。表示视频流和音频流都直接“复制”,不进行重新编码,从而实现无损且极速合并。output.mp4:输出的合并文件名。
⚡ 方法二:一行命令搞定(免去手动创建 txt)
如果你不想手动去新建一个 filelist.txt 文本,可以利用系统命令动态生成列表并传递给 FFmpeg。
🍏 macOS / Linux (Terminal)
printf "file '%s'\n" input1.mp4 input2.mp4 > list.txt && ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4 && rm list.txt
🪟 Windows (PowerShell)
Get-ChildItem *.mp4 | ForEach-Object { "file '$($_.Name)'" } | Out-File list.txt -Encoding utf8; ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4; Remove-Item list.txt
(注:Windows 的这条命令会自动把你当前目录下的所有 MP4 文件按名称排序并合并。)
🧩 方法三:使用 Concat 过滤器(应对多格式/分辨率不一致)
💡 补充场景:如果你的视频分辨率或编码不同,但你强行想要合并它们,
-c copy将无法工作,你必须对它们进行有损的重新编码。
运行以下命令,FFmpeg 会自动将不同规格的视频解码、统一缩放并重新编码合并:
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v][0:a][1:v][1:a] concat=n=2:v=1:a=1 [v][a]" -map "[v]" -map "[a]" output.mp4
🔍 参数详解:
-filter_complex:启用复杂滤镜图。[0:v][0:a][1:v][1:a]:分别代表第 1 个视频的视频流/音频流,和第 2 个视频的视频流/音频流。concat=n=2:v=1:a=1:告诉滤镜有n=2个片段,输出v=1个视频流和a=1个音频流。[v][a]:将合并后的音视频流命名为[v]和[a]。-map "[v]" -map "[a]":指定将滤镜输出的流写入最终的output.mp4。- (注意:此命令去掉了
-c copy,因此属于有损转换,速度取决于你的 CPU/GPU 性能。)
❓ 常见问题与排查 (FAQ)
1. 合并后只有第一个片段有声音,后面没声音?
- 原因:这通常是因为两个视频的音频采样率(例如一个 44100Hz,一个 48000Hz)或声道数不一致。
- 解决办法:建议使用方法三进行重编码合并;或者先单独把音频不一致的片段转换一致,再用方法一无损合并。
2. 视频合并处卡顿、掉帧或音画不同步?
- 原因:视频的时间戳(PTS/DTS)在拼接处没有正确衔接,或者两段视频的帧率(FPS)有微小差异(如 29.97fps 和 30fps)。
- 解决办法:可以在方法一的命令中加入
-fflags +genpts参数来尝试重新生成时间戳:
ffmpeg -f concat -safe 0 -fflags +genpts -i filelist.txt -c copy output.mp4