Python循环调用FFmpeg按起止帧变量裁剪视频报错求助
报错原因
命令字符串中的{ffmpeg_start}、{ffmpeg_end}是Python字符串占位符,但你没有执行变量替换操作,FFmpeg实际接收到的参数就是字面字符串{ffmpeg_start},无法解析为合法时间值,因此抛出格式错误。
现有代码的其他问题
即使修复了占位符替换的问题,现有逻辑还有4处会导致运行结果不符合预期:
-t参数接收的是截取片段的时长长度,不是结束时间点。你当前传入的是结束帧对应的全局时间戳,会导致截取的视频长度远大于预期。如果不想手动计算时长,可以替换为-to参数,直接传入结束时间戳即可。- 所有输入MP4文件都输出到同组
output%03d.mp4命名的文件,后处理的文件会直接覆盖之前生成的裁剪结果。 - 直接拼接字符串生成Shell命令,遇到路径、文件名带空格或特殊符号时会出现命令解析错误,
os.system本身的兼容性和安全性也较差。 - 流复制(
-c copy)模式下如果将-ss放在输入文件参数之后,裁剪位置会自动对齐到最近的关键帧,无法精准落在你指定的帧位置。
修正后代码
import os import subprocess FPS = 29.97 path = '/Users/a/Downloads/Video' # 替换为你实际的起止帧赋值逻辑 start_sample = 0 end_sample = 300 ffmpeg_start = start_sample / FPS ffmpeg_end = end_sample / FPS ffmpeg_duration = ffmpeg_end - ffmpeg_start for filename in os.listdir(path): if not filename.endswith(".mp4"): continue input_path = os.path.join(path, filename) # 为每个源文件的输出增加前缀,避免文件覆盖 output_pattern = os.path.join(path, f"{os.path.splitext(filename)[0]}_clip_%03d.mp4") # 用参数列表传参,避免Shell解析问题 command = [ "ffmpeg", "-fflags", "+discardcorrupt", # -ss放在-i前为快速seek模式,速度快但流复制下裁剪点不精准;要精准裁剪可将-ss移到-i后,同时去掉-c copy改用重编码 "-ss", f"{ffmpeg_start:.3f}", "-i", input_path, "-t", f"{ffmpeg_duration:.3f}", "-c", "copy", "-map", "0", "-f", "segment", "-reset_timestamps", "1", output_pattern ] subprocess.run(command, check=True)
使用说明
- 如果需要裁剪精度精确到单帧,删除
"-c", "copy"配置,替换为"-c:v", "libx264", "-c:a", "aac"进行重编码,同时将-ss参数移动到-i input_path之后即可。 - 如果不需要自动分段生成多个片段,只是单次裁剪单段视频,删除
"-f", "segment", "-reset_timestamps", "1"配置,将输出路径改为单个MP4文件路径即可。
内容的提问来源于stack exchange,提问作者LearningPython
相关产品推荐
相关产品推荐

