当前位置: 首页 > ai >正文

将两个mp4的文件合并在一起形成新的文件

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
视频合并程序
将多个mp4视频文件按照名称顺序合并成一个视频文件
支持两种方法:moviepy 和 ffmpeg
"""import os
import glob
import subprocess
import sys# 尝试导入moviepy,如果失败则使用ffmpeg方法
try:from moviepy.editor import VideoFileClip, concatenate_videoclipsMOVIEPY_AVAILABLE = Trueprint("使用 MoviePy 进行视频合并")
except ImportError:MOVIEPY_AVAILABLE = Falseprint("MoviePy 未安装,将使用 FFmpeg 方法")def check_ffmpeg():"""检查系统是否安装了ffmpeg"""try:result = subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True)return result.returncode == 0except FileNotFoundError:return Falsedef merge_videos_ffmpeg(video_files, output_filename="merged_video.mp4"):"""使用FFmpeg合并视频"""# 创建文件列表list_filename = "video_list.txt"try:with open(list_filename, 'w') as f:for video_file in video_files:f.write(f"file '{video_file}'\n")# 使用ffmpeg合并cmd = ['ffmpeg', '-f', 'concat', '-safe', '0','-i', list_filename, '-c', 'copy', output_filename, '-y']print("正在使用FFmpeg合并视频...")result = subprocess.run(cmd, capture_output=True, text=True)if result.returncode == 0:print(f"✓ 视频合并完成!")print(f"输出文件: {output_filename}")else:print(f"FFmpeg错误: {result.stderr}")return Falseexcept Exception as e:print(f"错误: {str(e)}")return Falsefinally:# 清理临时文件if os.path.exists(list_filename):os.remove(list_filename)return Truedef merge_videos_moviepy(video_files, output_filename="merged_video.mp4"):"""使用MoviePy合并视频"""try:clips = []for i, video_file in enumerate(video_files):print(f"正在加载视频 {i + 1}/{len(video_files)}: {video_file}")clip = VideoFileClip(video_file)clips.append(clip)print("正在合并视频...")final_clip = concatenate_videoclips(clips, method="compose")print(f"正在保存合并后的视频: {output_filename}")final_clip.write_videofile(output_filename,codec='libx264',audio_codec='aac',temp_audiofile='temp-audio.m4a',remove_temp=True)# 清理内存for clip in clips:clip.close()final_clip.close()print(f"✓ 视频合并完成!")print(f"输出文件: {output_filename}")return Trueexcept Exception as e:print(f"错误: 视频合并失败 - {str(e)}")try:for clip in clips:clip.close()except:passreturn Falsedef merge_videos():"""合并视频文件的主函数"""# 定义视频文件列表(按照你提供的文件名顺序)# video_files = [#     "0014_new-a-open2_segment_000_composite.mp4",#     "0014_new-a-open2_segment_001_composite.mp4",#     "0014_new-a-open2_segment_002_composite.mp4",#     "0014_new-a-open2_segment_003_composite.mp4",#     "0014_new-a-open2_segment_004_composite.mp4",#     "0014_new-a-open2_segment_005_composite.mp4",#     "0014_new-a-open2_segment_006_composite.mp4",#     "0014_new-a-open2_segment_007_composite.mp4",#     "0014_new-a-open2_segment_008_composite.mp4",#     "0014_new-a-open2_segment_009_composite.mp4"# ]video_files = ["merged_video_1.mp4","merged_video_2.mp4"]# 检查文件是否存在existing_files = []missing_files = []for video_file in video_files:if os.path.exists(video_file):existing_files.append(video_file)print(f"✓ 找到文件: {video_file}")else:missing_files.append(video_file)print(f"✗ 文件未找到: {video_file}")if missing_files:print(f"\n警告: 有 {len(missing_files)} 个文件未找到")choice = input("是否继续合并已存在的文件? (y/n): ")if choice.lower() != 'y':print("操作已取消")returnif not existing_files:print("错误: 没有找到任何视频文件")returnprint(f"\n开始合并 {len(existing_files)} 个视频文件...")# 选择合并方法if MOVIEPY_AVAILABLE:success = merge_videos_moviepy(existing_files)elif check_ffmpeg():success = merge_videos_ffmpeg(existing_files)else:print("错误: 既没有安装MoviePy也没有安装FFmpeg")print("请安装其中一个:")print("1. 安装MoviePy: pip install moviepy")print("2. 安装FFmpeg: https://ffmpeg.org/download.html")returnif success:print(f"合并了 {len(existing_files)} 个视频文件")def merge_videos_auto_detect():"""自动检测当前目录下的视频文件并按名称排序合并"""# 查找所有mp4文件video_files = glob.glob("0014_new-a-open_segment_*_composite.mp4")if not video_files:print("错误: 在当前目录下没有找到匹配的视频文件")print("请确保视频文件在当前目录下,且文件名格式为: 0014_new-a-open_segment_XXX_composite.mp4")return# 按名称排序video_files.sort()print(f"找到 {len(video_files)} 个视频文件:")for i, file in enumerate(video_files):print(f"{i + 1}. {file}")choice = input("\n是否继续合并这些文件? (y/n): ")if choice.lower() != 'y':print("操作已取消")returnprint("\n开始合并视频...")# 选择合并方法if MOVIEPY_AVAILABLE:success = merge_videos_moviepy(video_files)elif check_ffmpeg():success = merge_videos_ffmpeg(video_files)else:print("错误: 既没有安装MoviePy也没有安装FFmpeg")print("请安装其中一个:")print("1. 安装MoviePy: pip install moviepy")print("2. 安装FFmpeg: https://ffmpeg.org/download.html")returnif success:print(f"合并了 {len(video_files)} 个视频文件")if __name__ == "__main__":print("视频合并程序")print("=" * 50)# 检查可用的工具if MOVIEPY_AVAILABLE:print("✓ MoviePy 可用")else:print("✗ MoviePy 不可用")if check_ffmpeg():print("✓ FFmpeg 可用")else:print("✗ FFmpeg 不可用")if not MOVIEPY_AVAILABLE and not check_ffmpeg():print("\n错误: 没有可用的视频处理工具!")print("请安装以下工具之一:")print("1. MoviePy: pip install moviepy")print("2. FFmpeg: https://ffmpeg.org/download.html")sys.exit(1)print("\n选择合并模式:")print("1. 使用预定义的文件列表合并")print("2. 自动检测当前目录下的视频文件")choice = input("\n请选择模式 (1/2): ")if choice == "1":merge_videos()elif choice == "2":merge_videos_auto_detect()else:print("无效选择,使用默认模式...")merge_videos()
  • 目的:将多个MP4视频文件按顺序合并成一个输出视频文件(默认名为merged_video.mp4)。
  • 支持的方法
    • MoviePy:一个Python库,适合处理视频编辑任务,代码中通过加载视频片段并拼接实现合并。
    • FFmpeg:一个强大的多媒体处理工具,通过命令行调用实现快速合并。
  • 主要特点
    • 自动检测系统中是否安装了MoviePy或FFmpeg,优先使用MoviePy,如果不可用则fallback到FFmpeg。
    • 提供两种合并模式:
      • 预定义文件列表:用户在代码中手动指定要合并的视频文件。
      • 自动检测:扫描当前目录下符合特定命名规则的MP4文件并按名称排序后合并。
    • 检查输入文件是否存在,允许用户选择是否继续合并部分存在的文件。
    • 清理临时文件(如FFmpeg的输入列表文件)以保持目录整洁。

  1. 将两个MP4文件合并的实现方式

代码中已经预定义了一个文件列表,用于合并两个MP4文件:

python

video_files = ["merged_video_1.mp4","merged_video_2.mp4"
]

要合并这两个文件,可以通过以下步骤实现:

步骤 1:准备环境

  • 确保系统中安装了以下任一工具:
    • MoviePy:运行pip install moviepy安装。
    • FFmpeg:从FFmpeg官网下载并配置环境变量,确保命令行能运行ffmpeg -version。
  • 将两个MP4文件(merged_video_1.mp4和merged_video_2.mp4)放在代码运行的同一目录下。

步骤 2:运行代码

  • 运行方式
    • 保存代码为Python文件(例如merge_videos.py)。
    • 在命令行中运行:python merge_videos.py。
  • 选择模式
    • 在程序启动时,选择模式1(使用预定义文件列表合并)。
    • 程序会检查merged_video_1.mp4和merged_video_2.mp4是否存在。
    • 如果文件存在,程序将根据可用工具(MoviePy或FFmpeg)执行合并。

步骤 3:合并逻辑

代码会根据工具执行以下操作:

  1. 使用MoviePy合并(merge_videos_moviepy函数):

    • 加载两个视频文件为VideoFileClip对象。
    • 使用concatenate_videoclips将两个片段拼接。
    • 保存结果到merged_video.mp4,使用libx264视频编码和aac音频编码。
    • 清理内存,关闭所有视频片段。
  2. 使用FFmpeg合并(merge_videos_ffmpeg函数):

    • 创建一个临时文本文件video_list.txt,列出两个视频文件的路径(格式为file ‘filename’)。

    • 运行FFmpeg命令:

      bash

      ffmpeg -f concat -safe 0 -i video_list.txt -c copy merged_video.mp4 -y
      
      • -f concat:使用FFmpeg的concat demuxer合并文件。
      • -safe 0:允许非标准文件路径。
      • -c copy:直接复制视频和音频流,无需重新编码,速度快且无损。
      • -y:自动覆盖输出文件。
    • 删除临时文件video_list.txt。

步骤 4:输出

  • 合并成功后,输出文件为merged_video.mp4,位于当前目录。

  • 程序会打印日志,如:

    ✓ 视频合并完成!
    输出文件: merged_video.mp4
    

  1. 关键代码片段解读

以下是与合并两个MP4文件直接相关的核心部分:

预定义文件列表

python

video_files = ["merged_video_1.mp4","merged_video_2.mp4"
]
  • 定义了两个要合并的文件,程序会按列表顺序拼接(先播放merged_video_1.mp4,再播放merged_video_2.mp4)。

文件存在性检查

python

existing_files = []
missing_files = []
for video_file in video_files:if os.path.exists(video_file):existing_files.append(video_file)print(f"✓ 找到文件: {video_file}")else:missing_files.append(video_file)print(f"✗ 文件未找到: {video_file}")
  • 确保merged_video_1.mp4和merged_video_2.mp4存在。
  • 如果有文件缺失,询问用户是否继续合并已有文件。

MoviePy合并逻辑

python

clips = []
for video_file in video_files:clip = VideoFileClip(video_file)clips.append(clip)
final_clip = concatenate_videoclips(clips, method="compose")
final_clip.write_videofile(output_filename, codec='libx264', audio_codec='aac')
  • 逐个加载视频,拼接后保存。

FFmpeg合并逻辑

python

with open(list_filename, 'w') as f:for video_file in video_files:f.write(f"file '{video_file}'\n")
cmd = ['ffmpeg', '-f', 'concat', '-safe', '0', '-i', list_filename, '-c', 'copy', output_filename, '-y']
subprocess.run(cmd, capture_output=True, text=True)
  • 创建文件列表,调用FFmpeg的无损合并。

  1. 注意事项
  • 文件格式兼容性
    • 两个MP4文件的视频和音频编码格式需一致(如都使用H.264视频和AAC音频),否则FFmpeg的-c copy可能失败。
    • MoviePy会重新编码输出文件,兼容性较高,但速度较慢且可能有质量损失。
  • 性能对比
    • FFmpeg的-c copy方式速度快、无损,适合格式一致的视频。
    • MoviePy适合需要额外编辑(如裁剪、添加效果)的场景,但耗时较长。
  • 错误处理
    • 如果文件缺失,程序会提示用户选择是否继续。
    • 如果工具未安装,程序会引导用户安装MoviePy或FFmpeg。
  • 路径问题
    • 确保merged_video_1.mp4和merged_video_2.mp4在当前工作目录下。
    • 如果路径包含非ASCII字符,FFmpeg的-safe 0参数可避免路径解析错误。

  1. 如何修改代码以只合并两个特定文件

如果只需要合并merged_video_1.mp4和merged_video_2.mp4,可以简化代码,直接调用merge_videos函数:

python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import subprocess
try:from moviepy.editor import VideoFileClip, concatenate_videoclipsMOVIEPY_AVAILABLE = True
except ImportError:MOVIEPY_AVAILABLE = Falsedef check_ffmpeg():try:result = subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True)return result.returncode == 0except FileNotFoundError:return Falsedef merge_videos_ffmpeg(video_files, output_filename="merged_video.mp4"):list_filename = "video_list.txt"with open(list_filename, 'w') as f:for video_file in video_files:f.write(f"file '{video_file}'\n")cmd = ['ffmpeg', '-f', 'concat', '-safe', '0', '-i', list_filename, '-c', 'copy', output_filename, '-y']result = subprocess.run(cmd, capture_output=True, text=True)os.remove(list_filename)return result.returncode == 0def merge_videos_moviepy(video_files, output_filename="merged_video.mp4"):clips = [VideoFileClip(video_file) for video_file in video_files]final_clip = concatenate_videoclips(clips, method="compose")final_clip.write_videofile(output_filename, codec='libx264', audio_codec='aac')for clip in clips:clip.close()final_clip.close()return Trueif __name__ == "__main__":video_files = ["merged_video_1.mp4", "merged_video_2.mp4"]existing_files = [f for f in video_files if os.path.exists(f)]if len(existing_files) != 2:print("错误: 请确保两个视频文件都存在")exit(1)if MOVIEPY_AVAILABLE:merge_videos_moviepy(existing_files)elif check_ffmpeg():merge_videos_ffmpeg(existing_files)else:print("错误: 请安装MoviePy或FFmpeg")exit(1)print("合并完成,输出文件:merged_video.mp4")

  1. 运行示例

假设目录结构如下:

/project
├── merge_videos.py
├── merged_video_1.mp4
├── merged_video_2.mp4

运行命令:

bash

python merge_videos.py
http://www.xdnf.cn/news/14605.html

相关文章:

  • 从0开始学习R语言--Day31--概率图模型
  • 【MV】编排8:基于时间线数据多层分段避免过度拟合特定歌曲
  • 《C++初阶之类和对象》【初始化列表 + 自定义类型转换 + static成员】
  • FunASR搭建语音识别服务和VAD检测
  • 飞算 JavaAI 插件炸场!一小时搭图书管理系统
  • Java并发编程中高效缓存设计的哲学
  • Word2Vec 原理是什么
  • vscode 插件
  • Java底层原理:深入理解JVM内存管理机制
  • C#图书管理系统笔记(残缺版)
  • SQLite3 在嵌入式系统中的应用指南
  • Apache SeaTunnel Spark引擎执行流程源码分析
  • Java SE - 图书管理系统模拟实现
  • 国产麒麟 安装可视化数据库软件DBeaver(图解)
  • 前端开发入门指南:掌握HTML基础
  • 【RK3568 嵌入式linux QT开发笔记】 二维码开源库 libqrencode 交叉静态编译和使用
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DrinkWater(喝水记录组件)
  • DeepSeek中的提示库及其用法示例
  • 用于算法性能预测的 GNN 框架
  • H5新增属性
  • Three.js 中自定义 UV 坐标贴图详解
  • Java数据结构第二十四期:探秘 AVL 树,当二叉搜索树学会 “自我调节”
  • 华为云 Flexus+DeepSeek 征文|增值税发票智能提取小工具:基于大模型的自动化信息解析实践
  • 计算机操作系统(十六)进程同步
  • 安全版V4.5密码加密算法由SM3改为MD5
  • 使用Windows自带的WSL安装Ubuntu Linux系统
  • SQLite FTS4全文搜索实战指南:从入门到优化
  • Java基础(三):逻辑运算符详解
  • 【技术分享】XR技术体系浅析:VR、AR与MR的区别、联系与应用实践
  • 从语言到生态:编程语言在各行业的应用格局与未来演进