下面我将为你提供几种不同的方法,从最简单到最灵活,并附上详细的代码示例和解释。

核心概念:合并视频的方式
在 FFmpeg 中,合并视频主要有两种方式,它们对视频文件的要求完全不同:
-
Concat (连接/拼接)
- 原理:将视频文件一个接一个地连接起来,就像把几段胶带粘在一起一样。
- 要求:所有视频文件的编码格式(H.264, H.265等)、分辨率、帧率、音频轨道等参数必须完全相同,如果参数不同,合并后的视频可能会出现花屏、音画不同步等问题。
- 命令:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
-
Concat (Demuxer)
- 原理:不重新编码,而是将视频的“容器”(.mp4, .mkv等)像文件夹一样合并,只将各个文件的索引信息连接起来。
- 要求:比 Concat (Demuxer) 稍微宽松一些,它允许视频有不同的编码格式,但要求它们是“兼容的容器格式”(都是 .mp4 文件),这种方法本质上只是将文件“拼接”在一起,而不是“融合”。
- 命令:
ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4
对于绝大多数情况,尤其是从同一设备或同一来源导出的视频片段,我们推荐使用 concat demuxer,因为它最简单、最高效。

使用 subprocess 模块(最基础、最灵活)
这是最直接的方法,Python 的 subprocess 模块可以让你直接在代码中执行命令行指令。
步骤 1:安装 FFmpeg
你的系统上必须安装了 FFmpeg ffmpeg 命令可以在终端/命令行中直接使用。
- Windows: 从 FFmpeg 官网 下载,并将
bin目录添加到系统环境变量PATH中。 - macOS: 使用 Homebrew 安装:
brew install ffmpeg - Linux (Ubuntu/Debian): 使用 apt 安装:
sudo apt update && sudo apt install ffmpeg
步骤 2:编写 Python 脚本
我们将使用 concat demuxer 方法,因为它通常更方便。
import subprocess
import os
def merge_videos_with_concat_demuxer(video_list, output_filename):
"""
使用 FFmpeg 的 concat demuxer 合并视频。
注意:此方法要求所有视频文件是兼容的容器格式(如 .mp4)。
"""
# 检查输出文件是否已存在,如果存在则删除
if os.path.exists(output_filename):
os.remove(output_filename)
print(f"已删除已存在的输出文件: {output_filename}")
# 构建 concat demuxer 的输入字符串
# 格式为: "concat:file1.mp4|file2.mp4|file3.mp4"
concat_input = "|".join(video_list)
# 构建 FFmpeg 命令
# -i: 输入文件
# -c copy: 直接复制流,不进行重新编码,速度极快且保证质量
# -y: 覆盖输出文件(如果已存在)
command = [
'ffmpeg',
'-y', # 覆盖输出文件
'-i', f'concat:{concat_input}',
'-c', 'copy',
output_filename
]
print(f"正在执行命令: {' '.join(command)}")
try:
# 执行命令
# subprocess.run 会等待命令执行完成
# check=True 会在命令返回非零退出码(即出错)时抛出异常
subprocess.run(command, check=True, capture_output=True, text=True)
print(f"视频合并成功!输出文件: {output_filename}")
except subprocess.CalledProcessError as e:
print(f"视频合并失败!错误信息: {e.stderr}")
except FileNotFoundError:
print("错误:未找到 ffmpeg 命令,请确保 FFmpeg 已安装并添加到系统 PATH 中。")
# --- 使用示例 ---
if __name__ == "__main__":
# 1. 准备要合并的视频文件列表
# 确保这些文件存在于当前目录下
videos_to_merge = [
'part1.mp4',
'part2.mp4',
'part3.mp4'
]
# 2. 指定输出文件的名称
output_video = 'merged_video.mp4'
# 3. 调用函数进行合并
merge_videos_with_concat_demuxer(videos_to_merge, output_video)
如何运行:
- 将上面的代码保存为
merge.py。 - 准备好
part1.mp4,part2.mp4,part3.mp4等视频文件,并与merge.py放在同一个文件夹下。 - 在终端/命令行中运行:
python merge.py
使用 ffmpy 库(更简洁的封装)
ffmpy 是一个简单的 Python 封装库,它让调用 FFmpeg 变得更 Pythonic,无需手动构建命令列表。
步骤 1:安装 ffmpy
pip install ffmpy
步骤 2:编写 Python 脚本
import os
from ffmpy import FFmpeg
def merge_videos_with_ffmpy(video_list, output_filename):
"""
使用 ffmpy 库合并视频。
"""
if os.path.exists(output_filename):
os.remove(output_filename)
print(f"已删除已存在的输出文件: {output_filename}")
# 构建 concat demuxer 的输入字符串
concat_input = "|".join(video_list)
# 创建 FFmpeg 实例
# options 参数对应 FFmpeg 的命令行选项
ff = FFmpeg(
inputs={f'concat:{concat_input}': None}, # 输入文件,None 表示没有额外参数
outputs={output_filename: '-c copy'} # 输出文件及其参数
)
print(f"正在执行命令: ff.command")
try:
# 执行
ff.run()
print(f"视频合并成功!输出文件: {output_filename}")
except Exception as e:
print(f"视频合并失败!错误信息: {e}")
# --- 使用示例 ---
if __name__ == "__main__":
videos_to_merge = [
'part1.mp4',
'part2.mp4',
'part3.mp4'
]
output_video = 'merged_video_ffmpy.mp4'
merge_videos_with_ffmpy(videos_to_merge, output_video)
优点:
- 代码更简洁,易于阅读。
- 自动处理了命令的引号和转义问题。
使用 moviepy 库(更高级的视频编辑)
moviepy 不仅仅是一个 FFmpeg 封装,它是一个功能强大的 Python 视频编辑库,合并视频只是它的一个小功能。
步骤 1:安装 moviepy
pip install moviepy
步骤 2:编写 Python 脚本
注意:moviepy 在合并视频时,默认会进行重新编码,这意味着它对视频的格式要求不那么严格(可以合并不同编码的视频),但处理速度会慢很多,并且可能会有轻微的质量损失。
from moviepy.editor import VideoFileClip, concatenate_videoclips
import os
def merge_videos_with_moviepy(video_list, output_filename):
"""
使用 moviepy 库合并视频。
注意:moviepy 默认会重新编码,速度较慢但兼容性更好。
"""
if os.path.exists(output_filename):
os.remove(output_filename)
print(f"已删除已存在的输出文件: {output_filename}")
clips = []
try:
# 1. 加载所有视频片段
for video_file in video_list:
print(f"正在加载视频: {video_file}")
clip = VideoFileClip(video_file)
clips.append(clip)
# 2. 合并视频片段
# method='compose' 是默认行为,会重新编码
# 如果所有视频参数都一样,可以尝试 method='concat',它可能更快
final_clip = concatenate_videoclips(clips, method="compose")
# 3. 写入输出文件
print(f"正在合并视频并写入到: {output_filename}...")
final_clip.write_videofile(
output_filename,
codec='libx264', # 常见的视频编码器
audio_codec='aac' # 常见的音频编码器
)
print(f"视频合并成功!输出文件: {output_filename}")
except Exception as e:
print(f"视频合并失败!错误信息: {e}")
finally:
# 4. 释放内存,关闭所有视频片段
for clip in clips:
clip.close()
# --- 使用示例 ---
if __name__ == "__main__":
videos_to_merge = [
'part1.mp4',
'part2.mp4',
'part3.mp4'
]
output_video = 'merged_video_moviepy.mp4'
merge_videos_with_moviepy(videos_to_merge, output_video)
优点:
- 兼容性最好,可以处理不同编码、不同分辨率的视频(它会自动调整)。
- 除了合并,还可以进行剪辑、添加文字、叠加视频等复杂操作。
缺点:
- 速度慢,因为涉及重新编码。
- 安装包较大,依赖更多。
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
subprocess |
最灵活,不依赖第三方库,完全控制 FFmpeg 命令 | 需要手动构建命令,稍显繁琐 | 需要使用 FFmpeg 的高级特性,或项目不允许安装额外库时 |
ffmpy |
代码简洁,易于使用,是 FFmpeg 的优秀 Pythonic 封装 | 需要安装一个额外的库 | 推荐首选,当你只是想简单地调用 FFmpeg 功能时 |
moviepy |
功能强大,兼容性好,能处理复杂视频编辑任务 | 速度慢(会重新编码),安装包大 | 需要在合并的同时进行其他视频处理(如裁剪、加字幕等) |
给你的建议:
- 如果你的视频片段来自同一来源(如同一部电影的多个部分),请优先使用
subprocess或ffmpy的concat demuxer方法,这是最快、质量最高的方式。 - 如果你的视频片段参数各不相同(如不同手机录制的视频),并且你不想手动处理,可以考虑使用
moviepy,但要接受它较慢的速度。 - 对于大多数自动化脚本和工具开发,
ffmpy是一个平衡了简洁和功能的绝佳选择。
