原文地址:https://github.com/kkroening/ffmpeg-python,本文为google翻译+部分人工翻译,希望能对大家有用。
已经有大量的Python FFmpeg包装器,但是它们似乎缺乏复杂的过滤器支持。 ffmpeg-python
适用于简单和复杂的信号图。
水平翻转视频:
import ffmpeg
stream = ffmpeg.inputinput('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()
)
FFmpeg非常强大,但是它的命令行界面却非常复杂,尤其是在处理信号图并执行琐碎的事情时。
以一个信号图为例:(笔者:以下的例子是将一个图片水平翻转并嵌入到视频里面)
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安装获取最新版本:
pip install ffmpeg-python
也可以从本地克隆并安装源:
git clone [email protected]:kkroening / ffmpeg-python.git
pip install -e ./ffmpeg-python
如有疑问,请查看示例以了解是否有与您尝试做的事情接近的代码。
比如以下这些例子:
将视频转换为numpy数组
生成视频缩略图
通过管道读取原始PCM音频
JupyterLab /笔记本流编辑器
有关其他示例,请参见示例自述文件。
没有找到您要的过滤器?虽然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/attribute/etc. error from import ffmpeg
?
确保您是这样安装库的:pip install ffmpeg-python,
而不是pip install ffmpeg
或pip install python-ffmpeg
。
为什么我的音频流被丢弃了?
一些原始的ffmpeg过滤器会丢弃音频流,因此必须注意将音频保留在最终输出中。.audio
和.video
操作可以被用来引用一数据流的音频/视频部分,使得它们可以被单独地处理,然后在后面的管道重新组合。
这种问题是ffmpeg固有的,而ffmpeg-python试图避开这个障碍,而用户可能会参考ffmpeg官方文档以了解为什么某些过滤器会丢弃音频。
像往常一样,看一下示例(尤其是音频/视频管道)。
如何找出使用的命令行参数?
您可以在stream.run()之前
运行stream.get_args(),
检索要传递给的命令行参数ffmpeg
。您还可以运行stream.compile()
该ffmpeg
程序,并将可执行文件作为第一个参数。
我如何做XYZ?
请阅读本自述文件末尾“其他资源”部分中的每个链接。如果您四处张望,找不到所需的内容,并且有与其他用户相关的问题,则可以提出一个问题,询问其操作方法,同时全面说明要执行的操作做以及到目前为止您尝试过的事情。
与ffmpeg-python
其他用户没有直接关系的问题或要求他人为您编写代码的问题或如何为您解决与其他用户无关的复杂信号处理问题的问题将得到解决。
也就是说,我们希望继续改进我们的文档,并为使用ffmpeg-python
凉爽和令人兴奋的事物的人们提供支持社区。
您可以做的最好的事情之一ffmpeg-python
就是在问题跟踪器中回答未解决的问题。回答的问题将被标记并合并到文档,示例和其他学习资源中。
如果您发现在文档或整体开发经验方面可能会更好的事情,请在问题跟踪器中这样说。当然,请随时报告任何错误或提交功能请求。
也欢迎请求请求,但是触摸问题跟踪器中的库或先跳至Matrix聊天频道都不会造成伤害。
修复任何打开的错误或实现所请求的增强功能的人都是英雄,但是更改应包括通过测试。
git clone [email protected]:kkroening/ffmpeg-python.git
cd ffmpeg-python
virtualenv venv
. venv/bin/activate # (OS X / Linux)
venv\bin\activate # (Windows)
pip install -e .[dev]
pytest
下篇:ffmpeg-python库的使用翻译(二)