Python调用FFmpeg实现视频自动裁剪与分段处理教程
本文介绍如何使用Python调用FFmpeg命令行工具,实现将长视频自动拆分为指定时长的小段。通过封装subprocess模块执行ffmpeg和ffprobe命令,获取视频时长并计算分段数,最终完成批量视频的自动裁剪与保存。
文 | 李晓飞
来源:Python 技术「ID: pythonall」
近期接到一项任务,需将赛事视频拆分为时长在两分钟以内的小段,以便发布至短视频平台。
起初以为这只是临时性工作,但面对海量且时长不一的赛事视频数据,手工处理显然不可行,于是Python再次派上用场。
无需多言,直接开始实施。
核心策略
处理任何任务前,首要步骤是分析核心重点,集中资源攻克关键难点,随后再处理次要事项。
尽管本项目规模不大,但仍需从最关键环节入手,步步为营,最终解决整个问题。
整体流程包括:从指定目录读取视频文件,对每个文件进行裁剪处理,最后保存处理后的文件。
在此过程中,视频裁剪是核心环节。若无法便捷地裁剪视频,其他工作均无意义。
视频裁剪实现
当前短视频编辑软件功能繁多,但我们需要的是可编程调用的裁剪功能,FFmpeg[1]是最合适的选择。
FFmpeg是一款功能强大的命令行工具,支持通过编程方式调用。
从FFmpeg官网下载对应操作系统的版本,此处以Windows版[2]为例。
下载后解压至指定目录,将该目录下的bin文件夹路径添加到系统环境变量中。打开命令行窗口,输入以下命令:
> ffmpeg -version
ffmpeg version 2021-10-07-git-b6aeee2d8b-full_build- ...
执行后若能显示版本信息,说明配置成功。
查阅文档可知,拆分视频文件的命令格式如下:
ffmpeg -i [filename] -ss [starttime] -t [length] -c copy [newfilename]
]
i 代表待裁剪的源文件路径
ss 代表裁剪开始的时间点
t 代表裁剪结束时间或持续时间长度
c 代表裁剪后文件的保存路径
接下来,使用Python编写调用代码:
import subprocess as sp
def cut_video(filename, outfile, start, length=90):
cmd = "ffmpeg -i %s -ss %d -t %d -c copy %s" % (filename, start, length, outfile)
p = sp.Popen(cmd, shell=True)
p.wait()
return
- 定义一个函数,通过参数传入
ffmpeg所需的各项信息 - 将裁剪命令构建为字符串模板,并将参数替换至对应位置
- 利用
subprocess模块中的Popen函数执行命令,其中参数shell=True表示将命令作为整体字符串执行 p.wait()至关重要,因为裁剪操作耗时且为独立进程,必须等待执行完成后再进行后续工作,否则可能无法找到生成的文件
至此,视频裁剪功能实现,接下来分析其他关键环节。
分段计算逻辑
视频裁剪需要确定参数,特别是开始时间。若此步处理不当,裁剪工作将变得复杂。
因此,需明确如何计算裁剪分段。
目标是将视频裁剪为1分半钟的小段,为此需获取目标视频文件的总时长。
获取视频时长
如何获取时长?FFmpeg提供了另一个命令——ffprobe。
经查找,可组合命令以获取所需信息:
> ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i a.flv
920.667
该命令较为复杂,暂可忽略其他参数,只需传入待分析的视频文件即可。命令执行结果将显示一行视频时长数据。
据此编写函数:
import subprocess as sp
def get_video_duration(filename):
cmd = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i %s" % filename
p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
p.wait()
strout, strerr = p.communicate() # 去掉最后的回车
ret = strout.decode("utf-8").split("\n")[0]
return ret
- 该函数仅接收一个参数,即视频文件路径
- 组合命令语句,并将视频文件路径替换入命令中
- 使用
subprocess模块执行命令,注意需设置命令执行后的输出捕获 - 通过
wait等待命令执行完成 - 利用
communicate提取输出结果 - 从结果中提取视频时长数据并返回
分段计算
获取视频总时长并确定每个分段的长度后,即可计算所需分段数量。
代码如下:
import math
duration = math.floor(float(get_video_duration(filename)))
part = math.ceil(duration / length)
注意,计算分段时需进行向上取整,使用ceil函数,以包含最后不足一个分段长度的剩余部分。
获得分段数后,通过循环即可计算出每一段的起始时间。
文件获取
由于处理文件数量众多,需自动获取待处理文件列表。
方法简单且常用,通常可使用os.walk递归获取文件,也可根据实际需求自行编写。
for fname in os.listdir(dir):
fname = os.path.join(dir, os.path.join(dir, fname))
basenames = os.path.basename(fname).split('.')
mainname = basenames[0].split("_")[0]
...
提供视频文件所在目录,通过os.listdir获取目录中的文件列表,随后合成文件的绝对路径,因为调用裁剪命令时使用绝对路径更为便捷。
获取文件名的目的是为了后续对裁剪好的文件进行命名。
代码集成
各部分功能均已实现,现将代码集成:
def main(dir):
outdir = os.path.join(dir, "output")
if not os.path.exists(outdir):
os.mkdir(outdir)
for fname in os.listdir(dir):
fname = os.path.join(dir, os.path.join(dir, fname))
if os.path.isfile(fname):
split_video(fname, outdir)
main方法为集成后的主函数- 首先创建裁剪文件的存储目录,置于视频文件目录下的output子目录中
- 通过
listdir获取文件列表后,遍历处理每个文件,其中判断是否为普通文件 - 调用
split_video方法开始对单个视频文件进行裁剪处理
总结
总体而言,这是一个简单应用,核心功能仅涉及调用FFmpeg命令。
相比技术细节,更重要的是如何分析和分解项目,以及确定切入点。
本文采用的方法是从不断寻找最重要事项入手,以关键线索推进,最终以自下而上的方式解决整个问题。
希望本文能对您有所启发,谢谢。
参考资料
[1]
FFmpeg官网: http://ffmpeg.org/
[2]
FFmpeg Windows版下载: https://www.jb51.net/softs/145521.html
以上是Python调用FFmpeg命令行工具便捷操作视频示例实现过程的详细内容,更多关于Python调用命令行工具操作视频的资料请关注本站其他相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









