python调用ffmpeg命令行工具便捷操作视频示例实现过程


Posted in Python onNovember 01, 2021

文 | 李晓飞

来源: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 需要的信息
  • 将裁剪命令写成一个字符串模板,将参数替换到其中
  • subprocessPopen 执行命令,其中参数 shell=True 表示将命令作为一个整体执行
  • p.wait() 很重要,因为裁剪需要一会儿,而且是另起进程执行的,所以需要等执行完成再做后续工作,否则可能找不到裁剪好的文件

这样视频裁剪工作就完成了,然后再看看什么是最重要的。

计算分段

视频裁剪时,需要一些参数,特别是开始时间,如何确定呢?如果这件事做不好,裁剪工作就很麻烦。

所以看看如何计算裁剪分段。

我需要将视频裁剪成一分半的小段,那么将需要知道目标视频文件的时间长度。

获取视频长度

如何获得长度呢?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 Window 版下载: https://www.3water.com/softs/145521.html

以上就是python调用ffmpeg命令行工具便捷操作视频示例实现过程的详细内容,更多关于python调用命令行工具操作视频的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python内置函数之filter map reduce介绍
Nov 30 Python
在Python下进行UDP网络编程的教程
Apr 29 Python
Python中的连接符(+、+=)示例详解
Jan 13 Python
解决.ui文件生成的.py文件运行不出现界面的方法
Jun 19 Python
python程序变成软件的实操方法
Jun 24 Python
Python 脚本实现淘宝准点秒杀功能
Nov 13 Python
使用python快速在局域网内搭建http传输文件服务的方法
Nov 14 Python
Python线程协作threading.Condition实现过程解析
Mar 12 Python
对Keras中predict()方法和predict_classes()方法的区别说明
Jun 09 Python
快速了解Python开发环境Spyder
Jun 29 Python
python生成可执行exe控制Microsip自动填写号码并拨打功能
Jun 21 Python
python实现手机推送 代码也就10行左右
Apr 12 Python
Python字典的基础操作
Nov 01 #Python
Python集合的基础操作
Nov 01 #Python
python基础之类属性和实例属性
python基础之类方法和静态方法
Python Matplotlib绘制条形图的全过程
python基础之模块的导入
python基础之文件操作
You might like
php 生成文字png图片的代码
2011/04/17 PHP
PHP中的strtr函数使用介绍(str_replace)
2011/10/20 PHP
php字符串替换函数substr_replace()用法实例
2015/03/17 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
php四种定界符详解
2017/02/16 PHP
Laravel 6.2 中添加了可调用容器对象的方法
2019/10/22 PHP
PHP实现抽奖功能实例代码
2020/06/30 PHP
javascript dom 基本操作小结
2010/04/11 Javascript
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
JSON传递bool类型数据的处理方式介绍
2013/09/18 Javascript
js+css实现的圆角边框TAB选项卡滑动门代码分享(2款)
2015/08/26 Javascript
微信小程序 POST请求(网络请求)详解及实例代码
2016/11/16 Javascript
原生js更改css样式的两种方式
2017/03/15 Javascript
在bootstrap中实现轮播图实例代码
2017/06/11 Javascript
十个免费的web前端开发工具详细整理
2017/09/18 Javascript
详解vue2.0监听属性的使用心得及搭配计算属性的使用
2018/07/18 Javascript
从零到一详聊创建Vue工程及遇到的常见问题
2019/04/25 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
python基础教程之popen函数操作其它程序的输入和输出示例
2014/02/10 Python
在Python的Flask中使用WTForms表单框架的基础教程
2016/06/07 Python
Python机器学习k-近邻算法(K Nearest Neighbor)实例详解
2018/06/25 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
python 实现兔子生兔子示例
2019/11/21 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
Canvas 像素处理之改变透明度的实现代码
2019/01/08 HTML / CSS
佐卡伊官网:中国知名珠宝品牌
2017/02/05 全球购物
印度首个本地在线平台:nearbuy
2019/03/28 全球购物
关于递归的一道.NET面试题
2013/05/12 面试题
大学生职业规划书的范本
2014/02/18 职场文书
《猴子种果树》教学反思
2014/04/26 职场文书
大学毕业典礼演讲稿
2014/09/09 职场文书
民间借贷协议书范本
2014/10/01 职场文书
违纪检讨书范文
2015/01/27 职场文书
工作证明格式范文
2015/06/15 职场文书
小学信息技术教学反思
2016/02/16 职场文书