Python---批量给视频添加片头片尾
在剪辑视频的时候,如果视频很少的情况可以考虑自己使用软件来拼接一下,但是如果要给几百个视频加片头片尾,那就需要使用软件来加了。
基础代码示例:
from moviepy.editor import VideoFileClip, concatenate_videoclips # 读取三段视频 piantou = VideoFileClip("piantou-10000k-25f.mp4") video = VideoFileClip("video.mp4") pianwei = VideoFileClip("pianwei-10000k-25f.mp4") # 拼接并导出 outvideo = concatenate_videoclips([piantou, video, pianwei]) outvideo.write_videofile("outvideo.mp4")
这种方式可以给一个视频添加片头片尾。
批量给视频视频添加片头片尾:
import os import re import time import subprocess from multiprocessing import Pool from typing import List, Dict # 配置路径 INPUT_VIDEO_DIR = r"E:\python-test\视频处理\原视频" # 原视频文件夹 OUTPUT_VIDEO_DIR = r"E:\python-test\视频处理\带片头片尾视频" # 输出文件夹 OPENING_VIDEO = r"E:\python-test\视频处理\piantou-tongyi.mp4" # 片头视频路径 ENDING_VIDEO = r"E:\python-test\视频处理\pianwei-tongyi.mp4" # 片尾视频路径 # 支持的视频格式(可扩展) SUPPORTED_FORMATS = ('.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv') def check_dependencies() -> bool: """检查ffmpeg是否可用及片头片尾文件是否存在""" # 检查ffmpeg try: subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True) except (subprocess.CalledProcessError, FileNotFoundError): print("错误:未找到ffmpeg!请安装并配置环境变量") return False # 检查片头文件 if not os.path.exists(OPENING_VIDEO): print(f"错误:片头文件不存在 - {OPENING_VIDEO}") return False # 检查片尾文件 if not os.path.exists(ENDING_VIDEO): print(f"错误:片尾文件不存在 - {ENDING_VIDEO}") return False return True def get_video_duration(file_path: str) -> float: """获取视频时长(秒)""" try: result = subprocess.run( ['ffmpeg', '-i', file_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8', errors='ignore' ) # 匹配时长格式(如:Duration: 00:01:23.45) pattern = re.compile(r"Duration:\s*(\d+):(\d+):(\d+\.\d+)") match = pattern.search(result.stdout) if not match: return -1 hours = float(match.group(1)) minutes = float(match.group(2)) seconds = float(match.group(3)) return hours * 3600 + minutes * 60 + seconds except Exception as e: print(f"获取时长失败:{file_path},错误:{str(e)}") return -1 def concat_videos(opening: str, main_video: str, ending: str, output: str) -> bool: """拼接片头、主视频、片尾""" # 确保输出目录存在 os.makedirs(os.path.dirname(output), exist_ok=True) # 创建临时文件列表(ffmpeg拼接需要的文件列表) temp_list = f"{output}.txt" try: with open(temp_list, 'w', encoding='utf-8') as f: f.write(f"file '{opening}'\n") f.write(f"file '{main_video}'\n") f.write(f"file '{ending}'\n") # ffmpeg命令:使用concat协议拼接(快速,无需重新编码) command = [ 'ffmpeg', '-f', 'concat', '-safe', '0', '-i', temp_list, '-c', 'copy', '-y', # -y:覆盖已有文件 output ] result = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf-8', errors='ignore', timeout=600 # 超时时间10分钟 ) if result.returncode != 0: print(f"拼接失败:{main_video},错误:{result.stderr[:500]}") return False print(f"拼接成功:{output}") return True except Exception as e: print(f"拼接异常:{main_video},错误:{str(e)}") return False finally: # 清理临时文件 if os.path.exists(temp_list): try: os.remove(temp_list) except: pass def process_single_video(task: Dict[str, str]) -> None: """处理单个视频的函数(供多进程调用)""" main_video = task['main_video'] output_video = task['output_video'] # 检查原视频是否有效 duration = get_video_duration(main_video) if duration <= 0: print(f"跳过无效视频:{main_video}") return # 执行拼接 concat_videos( opening=OPENING_VIDEO, main_video=main_video, ending=ENDING_VIDEO, output=output_video ) def get_all_videos(folder: str) -> List[str]: """递归获取所有支持的视频文件""" video_files = [] for root, _, files in os.walk(folder): for file in files: if file.lower().endswith(SUPPORTED_FORMATS): video_files.append(os.path.join(root, file)) return video_files if __name__ == "__main__": # 检查依赖 if not check_dependencies(): input("按回车键退出...") exit(1) # 获取所有视频文件 video_files = get_all_videos(INPUT_VIDEO_DIR) if not video_files: print(f"未在 {INPUT_VIDEO_DIR} 找到支持的视频文件(格式:{SUPPORTED_FORMATS})") input("按回车键退出...") exit(0) print(f"共找到 {len(video_files)} 个视频文件,准备添加片头片尾...") # 构建任务列表(保持原文件目录结构) tasks = [] for video in video_files: # 计算输出路径(保持原目录结构) relative_path = os.path.relpath(video, INPUT_VIDEO_DIR) output_path = os.path.join(OUTPUT_VIDEO_DIR, relative_path) tasks.append({ 'main_video': video, 'output_video': output_path }) # 多进程处理 start_time = time.time() print("\n开始处理...") # 进程数设为CPU核心数的一半,避免资源占用过高 with Pool(processes=os.cpu_count() // 2) as pool: pool.map(process_single_video, tasks) # 统计结果 total_time = time.time() - start_time print(f"\n处理完成!共处理 {len(video_files)} 个视频,耗时 {total_time:.2f} 秒") print(f"输出目录:{OUTPUT_VIDEO_DIR}") input("按回车键退出...")
简直了YYDS!
打完收工!

浙公网安备 33010602011771号