ffmpeg-python: FFmpeg 的 Python 绑定
概述
市面上有大量的 Python FFmpeg 封装库,但它们似乎都缺乏对复杂滤镜的支持。 ffmpeg-python 在处理简单以及复杂的信号图时都能很好地工作。
快速入门
水平翻转视频:
import ffmpeg
stream = ffmpeg.input('input.mp4')
stream = ffmpeg.hflip(stream)
stream = ffmpeg.output(stream, 'output.mp4')
ffmpeg.run(stream)
或者,如果你更喜欢流畅式接口:
import ffmpeg
(
ffmpeg
.input('input.mp4')
.hflip()
.output('output.mp4')
.run()
)
API 参考
复杂滤镜图
FFmpeg 功能极其强大,但其命令行接口很快就会变得非常复杂——尤其是在处理信号图以及执行任何超出简单操作的任务时。
例如,考虑一个看起来像这样的信号图:

对应的命令行参数相当繁琐:
ffmpeg -i input.mp4 -i overlay.png -filter_complex "[0]trim=start_frame=10:end_frame=20[v0];\
[0]trim=start_frame=30:end_frame=40[v1];[v0][v1]concat=n=2[v2];[1]hflip[v3];\
[v2][v3]overlay=eof_action=repeat[v4];[v4]drawbox=50:50:120:120:red:t=5[v5]"\
-map [v5] output.mp4
也许这看起来很棒,但如果你不是 FFmpeg 命令行专家,它可能看起来像外星语。
如果你和我一样,觉得 Python 强大且易读,使用 ffmpeg-python 会更容易:
import ffmpeg
in_file = ffmpeg.input('input.mp4')
overlay_file = ffmpeg.input('overlay.png')
(
ffmpeg
.concat(
in_file.trim(start_frame=10, end_frame=20),
in_file.trim(start_frame=30, end_frame=40),
)
.overlay(overlay_file.hflip())
.drawbox(50, 50, 120, 120, color='red', thickness=5)
.output('out.mp4')
.run()
)
ffmpeg-python 负责使用与上述滤镜图对应的命令行参数来运行 ffmpeg,以熟悉的 Python 术语表达。
现实中的信号图可能会复杂得多,但 ffmpeg-python 可以处理任意大的(有向无环)信号图。
安装
安装 ffmpeg-python
可以通过典型的 pip install 获取 ffmpeg-python 的最新版本:
pip install ffmpeg-python
或者,可以从本地克隆并安装该源:
git clone git@github.com:kkroening/ffmpeg-python.git
pip install -e ./ffmpeg-python
注意:
ffmpeg-python不会尝试下载/安装 FFmpeg,因为ffmpeg-python仅是一个纯 Python 封装 - 而 FFmpeg 的安装依赖于平台/环境,因此是用户的责任,如下所述。
安装 FFmpeg
在使用 ffmpeg-python 之前,必须安装 FFmpeg 并通过 $PATH 环境变量使其可访问。
有多种方式可以安装 FFmpeg,例如使用官方下载链接,或使用您选择的包管理器(例如 Debian/Ubuntu 上的 sudo apt install ffmpeg,OS X 上的 brew install ffmpeg 等)。
无论 FFmpeg 如何安装,您都可以通过在终端中运行 ffmpeg 命令来检查环境路径是否正确设置,在这种情况下,应显示版本信息,如下例所示(为简洁起见已截断):
$ ffmpeg
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
注意:此处显示的实际版本信息可能因系统而异;但如果出现类似
ffmpeg: command not found的消息而非版本信息,则说明 FFmpeg 未正确安装。
示例
如有疑问,请查看 示例,看看是否有接近您想要执行的操作的内容。
以下是一些示例:
请参阅 示例 README 获取更多示例。
自定义滤镜
找不到您需要的滤镜? 虽然 ffmpeg-python 包含一些最常用滤镜(如 concat)的简写表示法,但所有滤镜都可以通过 .filter 运算符引用:
stream = ffmpeg.input('dummy.mp4')
stream = ffmpeg.filter(stream, 'fps', fps=25, round='up')
stream = ffmpeg.output(stream, 'dummy2.mp4')
ffmpeg.run(stream)
或者流畅地:
(
ffmpeg
.input('dummy.mp4')
.filter('fps', fps=25, round='up')
.output('dummy2.mp4')
.run()
)
特殊选项名称:
具有特殊名称的参数,如 -qscale:v(可变比特率)、-b:v(恒定比特率)等,可以按以下方式指定为关键字参数字典:
(
ffmpeg
.input('in.mp4')
.output('out.mp4', **{'qscale:v': 3})
.run()
)
多个输入:
接受多个输入流的滤镜可以通过将输入流作为数组传递给 ffmpeg.filter 来使用:
main = ffmpeg.input('main.mp4')
logo = ffmpeg.input('logo.png')
(
ffmpeg
.filter([main, logo], 'overlay', 10, 10)
.output('out.mp4')
.run()
)
多个输出:
能够产生多个输出的滤镜可以与 .filter_multi_output 一起使用:
split = (
ffmpeg
.input('in.mp4')
.filter_multi_output('split') # or `.split()`
)
(
ffmpeg
.concat(split[0], split[1].reverse())
.output('out.mp4')
.run()
)
(在此特定情况下,.split() 是等效的简写形式,但通用方法也适用于其他多输出滤镜)
字符串表达式:
由 ffmpeg 解释的表达式可以作为字符串参数包含,并引用任何特殊的 ffmpeg 变量名:
(
ffmpeg
.input('in.mp4')
.filter('crop', 'in_w-2*10', 'in_h-2*20')
.input('out.mp4')
)
如有疑问,请参阅现有过滤器、示例和/或官方 ffmpeg 文档。
常见问题
为什么我从 import ffmpeg 收到 import/attribute/等错误?
请确保你运行了 pip install ffmpeg-python,而_不是_ pip install ffmpeg(错误)或 pip install python-ffmpeg(同样错误)。
为什么我的音频流被丢弃了?
某些 ffmpeg 过滤器会丢弃音频流,必须注意在最终输出中保留音频。 可以使用 .audio and .video 运算符来引用流的音频/视频部分,以便单独处理,然后在管道中稍后重新组合。
这种困境是 ffmpeg 固有的,ffmpeg-python 试图不干涉,用户可以参考官方 ffmpeg 文档了解为什么某些过滤器会丢弃音频。
一如既往,请查看示例(特别是音频/视频管道)。
如何查看使用的命令行参数?
你可以在 stream.run() 之前运行 stream.get_args() 以获取将传递给 ffmpeg 的命令行参数。 你还可以运行 stream.compile(),其中也包括将 ffmpeg 可执行文件作为第一个参数。
我如何执行 XYZ?
请查看此 README 末尾附加资源部分中的每个链接。 如果你到处查看都找不到你要找的内容,并且有一个可能与其他用户相关的问题,你可以打开一个 issue 询问如何操作,同时提供关于你试图做什么以及你目前尝试了什么内容的详细解释。
与 ffmpeg-python 无直接关联的问题,或要求他人代写代码、或询问如何替你解决与信号处理相关的复杂问题(且该问题对其他用户不相关)的,将会被关闭。
话虽如此,我们希望继续改进文档,并为使用 ffmpeg-python 进行有趣且激动人心工作的用户提供一个支持社区。
贡献
帮助让 ffmpeg-python 变得更好的最佳方式之一,是回答 issue tracker 中的开放问题。 已回答的问题将被标记并整合到文档、示例及其他学习资源中。
如果你发现文档或整体开发体验中有可以改进的地方,请在 issue tracker 中提出。 当然,也欢迎报告任何 bug 或提交功能请求。
同样欢迎 Pull requests,但最好先在 issue tracker 中沟通或加入 Matrix 聊天频道。
任何修复 开放 bug 或实现 请求的增强功能 的人都是英雄,但更改应包含通过的测试。
运行测试
git clone git@github.com:kkroening/ffmpeg-python.git
cd ffmpeg-python
virtualenv venv
. venv/bin/activate # (OS X / Linux)
venv\bin\activate # (Windows)
pip install -e .[dev]
pytest