Python(十八):第十七章 音视频处理

Python(十八):第十七章 音视频处理
Prorise第十七章 音视频处理
本章节我们将学习如何使用 Python 来调用强大的 FFmpeg 工具包,以处理常见的音视频文件操作。FFmpeg 功能极其丰富,虽然它本身是 C 语言开发的,但通过 Python 调用其命令行工具是实现自动化处理、集成到 Web 后端或脚本中的常用且高效的方法。我们的重点是学习如何“处理”音视频,而不是从零“实现”编解码器。我们将主要使用 ffmpeg-python
这个库来简化调用过程,让代码更符合 Python 的风格。
17.1 FFmpeg 介绍、核心概念、安装与 Python 交互方式
目标:
- 深入理解 FFmpeg 是什么,它的重要性以及核心组成。
- 掌握音视频处理中的基本术语(容器、流、编解码器等)。
- 在你的操作系统上成功安装 FFmpeg 命令行工具并配置好环境变量。
- 了解 Python 与 FFmpeg 交互的几种方式,并安装好我们将主要使用的
ffmpeg-python
库。
17.1.1 FFmpeg:音视频领域的“瑞士军刀”
什么是 FFmpeg?
FFmpeg 不仅仅是一个简单的程序,它是一个完整的、跨平台的、开源的音视频处理解决方案。如果你需要对音频或视频文件进行几乎任何你能想到的操作——包括但不限于:录制、转换格式(转码)、编辑(裁剪、合并、旋转)、提取信息、添加滤镜/特效(水印、调色、降噪)、压缩、以及进行网络流传输(推流/拉流)——FFmpeg 都是这个领域内最强大、最通用、使用最广泛的工具集。从大型视频网站的后台转码系统,到你电脑上的视频播放器、剪辑软件,再到各种流媒体服务,背后都极有可能有 FFmpeg 的身影。
FFmpeg 的重要性:
- 功能全面: 支持海量的音视频格式(容器)和编解码器(算法),无论是常见的 MP4/H.264/AAC,还是较新的 AV1/Opus,甚至很多生僻格式,FFmpeg 大多都能处理。
- 跨平台: 无缝运行在 Windows、macOS、Linux 等主流操作系统上。
- 开源免费: 遵循 LGPL 或 GPL 等开源协议(取决于编译选项),可以自由使用、修改和分发。
- 性能优异: 核心代码使用 C 语言编写,并针对性能进行了深度优化,利用了多核 CPU 和 SIMD 指令集等技术,处理效率高。
- 命令行驱动: 提供了极其灵活和强大的命令行接口,可以通过参数组合实现复杂的操作流程,非常适合编写脚本进行自动化处理或在服务器后端调用。
FFmpeg 的核心组成:
FFmpeg是一整个“庞大”的项目,他其中含有大量的工具,虽然我们最常用的是 ffmpeg
这个命令,但了解其主要组成部分有助于理解它的工作方式:
ffmpeg
(命令行工具)
这是最核心、最常用的工具。它负责读取输入文件/流,根据用户指定的参数进行解码、滤镜处理、编码、封装等一系列操作,最终输出结果文件/流。我们后续的大部分操作都是通过构建不同的 ffmpeg
命令来实现的。
ffprobe
(命令行工具)
这是一个多媒体流分析工具。它可以读取音视频文件或流,提取并显示其中非常详细的元数据和技术信息,例如:
- 文件格式(容器类型)。
- 包含的数据流(视频、音频、字幕等)。
- 每个流的编解码器、比特率、时长、帧率(视频)、分辨率(视频)、采样率(音频)、声道数(音频)等。
- 文件的元数据标签(标题、作者、专辑等)。在进行任何处理之前,使用
ffprobe
了解输入文件的属性往往是必要的第一步,这对于编写健壮的处理脚本至关重要。
ffplay
(命令行工具)
一个基于 FFmpeg 库和 SDL(一个跨平台多媒体库)的简单媒体播放器。它主要用于:
- 快速预览音视频文件。
- 测试 FFmpeg 的解码能力。
- 实时查看应用滤镜的效果。它功能相对简单,不如专门的播放器强大,但在开发调试时非常方便。
核心库 (libav*)
这些是以 libav
开头的 C 语言库,是 FFmpeg 所有功能的基石,也是许多其他播放器、编辑器、转码软件(甚至包括 Chrome 浏览器)使用的底层库:
libavcodec
: 包含了海量的音频/视频编解码器 (CODEC)。libavformat
: 负责处理各种多媒体容器格式 (Format) 的解复用 (Demuxing) 和复用 (Muxing)。libavfilter
: 提供了丰富的音频和视频滤镜 (Filter),用于实现各种特效和处理。libavutil
: 包含了一些基础的通用工具函数(如数学运算、数据结构、日志等)。libswscale
: 用于进行高效的图像缩放 (Scaling) 和色彩空间转换。libswresample
: 用于进行音频重采样 (Resampling)、格式转换和声道布局处理。libavdevice
: 用于访问操作系统提供的多媒体设备(如摄像头、麦克风、屏幕录制)。
17.1.2 音视频基础概念
理解以下术语对于使用 FFmpeg 至关重要:
术语 | 英文 | 比喻 | 作用与解释 | 常见示例 |
---|---|---|---|---|
容器格式 | Container / Format | 文件盒子 | 定义文件结构,规定如何将音视频流、元数据打包存储。决定文件扩展名。 | .mp4 , .mkv , .mov , .avi , .mp3 , .aac |
数据流 | Stream | 文件内容 | 容器内实际的、连续的数据序列,如视频数据、音频数据、字幕数据。 | H.264 视频流, AAC 音频流, SRT 字幕流 |
编解码器 | Codec (Coder/Decoder) | 压缩/解压算法 | 用于压缩(编码)原始音视频数据以减小体积,或解压缩(解码)数据以便播放或编辑。 | H.264, H.265(HEVC), VP9, AV1, AAC, MP3, Opus |
相关处理过程:
- 编码 (Encoding): 将未压缩或已解码的音视频数据,使用特定的编解码器压缩成目标格式的数据流。这是有损或无损压缩的过程。
- 解码 (Decoding): 将已编码的音视频数据流,使用对应的编解码器解压缩成原始的、可播放或可处理的数据(如图像帧序列、音频样本)。
- 转码 (Transcoding): 先将输入文件解码,然后对解码后的数据进行处理(可选,如加滤镜),最后重新编码成目标格式/参数。这是一个解码+编码的过程,通常比较耗时和消耗 CPU 资源。
- 封装转换/重封装 (Remuxing): 不经过解码和重新编码,直接将一个容器中的音视频流原封不动地提取出来,再放入另一个类型的容器中。例如,将 MKV 文件中的 H.264 视频和 AAC 音频直接放入 MP4 文件。这个过程非常快,几乎不损失质量,但前提是目标容器必须支持源文件中的音视频编码格式。
- 复用/封装 (Muxing): 将多个单独的编码后的流(如一个视频流、一个音频流)合并到一个容器文件中。
- 解复用/分离 (Demuxing): 从一个容器文件中提取出单个的流(如只提取音频流)。
17.1.3 安装 FFmpeg 命令行工具 (重要前提!)
ffmpeg-python
库本身不包含 FFmpeg 的可执行程序。你必须首先独立地在你的操作系统中安装 FFmpeg,并确保 ffmpeg
和 ffprobe
命令可以在你的终端或命令行中直接运行。
Windows 安装与配置
- 下载: 访问 FFmpeg 官网下载页面 ([下载链接](Download FFmpeg))。推荐从
gyan.dev
或BtbN
下载预编译的 Windows 版本。建议选择 “release” 版本下的 “full” 构建(如ffmpeg-release-full.zip
),它包含了较全面的编解码器支持。
解压: 将下载的
.zip
文件解压到一个固定且路径不含中文或特殊字符的位置,例如C:\ffmpeg
或D:\tools\ffmpeg\
。解压后你会看到bin
,doc
,licenses
等文件夹。关键的可执行文件在bin
目录中。配置环境变量 (关键步骤):
- 在 Windows 搜索栏搜索“环境变量”并打开“编辑系统环境变量”。
- 在弹出的“系统属性”窗口中,点击“高级”选项卡下的“环境变量…”按钮。
- 在下方的“系统变量”列表中,找到名为
Path
的变量,选中它,点击“编辑…”。 - 在“编辑环境变量”窗口中,点击“新建”,然后将你刚才解压后
ffmpeg
文件夹下bin
目录的完整路径(例如C:\ffmpeg\bin
)粘贴进去。 - 点击“确定”关闭所有打开的设置窗口。
验证: 必须重新打开一个新的 CMD 或 PowerShell 窗口(旧窗口不会加载新的环境变量)。输入以下命令并回车:
1
2ffmpeg -version
ffprobe -version如果能成功显示 FFmpeg 和 ffprobe 的版本信息,则安装和配置成功。如果提示“不是内部或外部命令”,请仔细检查你的 PATH 环境变量设置是否正确,路径是否包含
bin
目录,以及是否重新打开了命令行窗口。有时需要重启电脑才能使环境变量完全生效。
macOS 安装
使用 Homebrew 是最推荐的方式:
1 | brew install ffmpeg |
验证:打开新的终端窗口,输入 ffmpeg -version
。
Linux 安装
- Debian/Ubuntu:
1
sudo apt update && sudo apt install ffmpeg
- CentOS/RHEL/Fedora:
通常需要先启用 EPEL 和 RPM Fusion 仓库(如果尚未启用):验证:输入1
2
3
4
5
6
7
8
9# (根据你的具体发行版和版本,启用仓库的命令可能略有不同)
# 例如 CentOS 7/8:
# sudo yum install epel-release -y
# sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-$(rpm -E %rhel).noarch.rpm -y
# sudo yum install ffmpeg ffmpeg-devel -y
# 例如 Fedora:
# sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm -y
# sudo dnf install ffmpeg --allowerasing -yffmpeg -version
。
17.1.4 Python 交互方式的选择与 ffmpeg-python
安装
在 Python 中与 FFmpeg 交互主要有两种方式:
subprocess
模块 (基础方式)
这是 Python 内置的标准库,可以用来启动和管理子进程,执行任何命令行程序,包括 ffmpeg
。
1 | import subprocess |
优点: 无需额外库,灵活,可以直接执行任何 FFmpeg 命令。
缺点: 当命令参数复杂(尤其是涉及滤镜 -vf
或 -filter_complex
时,包含大量引号、逗号、分号)时,手动构建命令列表非常繁琐且极易出错。需要手动解析 FFmpeg 的 stderr
输出以获取进度或判断具体错误。
ffmpeg-python
库 (推荐)
这是一个非常流行的 Python 库,它封装了调用 FFmpeg 命令行的过程。你使用 Python 的函数和链式调用来定义输入、输出、滤镜等操作,ffmpeg-python
会自动为你生成对应的、复杂的 FFmpeg 命令行参数,并替你调用 subprocess
来执行。
需要注意的是,下载需要下载的是这个库,而不是单pip install ffmpeg
!
1 | pip install ffmpeg-python |
1 | import ffmpeg # 使用 python-ffmpeg 库 |
优点:
- 代码更 Pythonic、更易读: 使用函数调用和链式操作构建流程,比拼接字符串或列表清晰。
- 简化复杂命令: 特别是对于包含多个滤镜、输入、输出的复杂操作,能大大简化命令构建过程。
- 减少引用/转义错误: 库会自动处理参数的引用和转义问题。
缺点:
- 仍然依赖外部 FFmpeg: 它只是一个包装器,不是 FFmpeg 的 Python 重新实现,所以一定要保证自己的环境变量存在ffmpeg!
- 可能无法覆盖所有参数: 对于 FFmpeg 非常规或最新的参数,库可能没有直接对应的函数或关键字参数(但通常提供传递原生参数的方式)。
- 错误调试: 虽然它捕获了
stderr
,但有时理解错误原因仍需结合 FFmpeg 本身的知识。
17.2 FFmpeg 命令行结构
目标:
- 深入理解 FFmpeg 命令行的组成、选项类型、作用顺序和流指定符。
- 了解如何使用
ffprobe
获取媒体文件的详细信息。 - 全面掌握
ffmpeg-python
库的核心语法,包括如何定义输入、输出、滤镜,以及如何执行处理和获取信息。 - 建立 FFmpeg 命令行参数与
ffmpeg-python
函数/参数之间的对应关系。
17.2.1 FFmpeg 命令行结构详解
要精确控制 FFmpeg,理解其命令行结构至关重要。其基本模式为:
1 | ffmpeg [全局选项] [输入选项] -i 输入文件1 ... [输出选项] 输出文件1 ... |
选项的作用域与顺序
理解选项的作用域和顺序是正确使用 FFmpeg 的关键。选项通常会影响紧随其后的文件或操作。
全局选项 (Global Options)
这些选项位于 ffmpeg
命令之后、第一个 -i
输入文件之前,它们控制整个 FFmpeg 进程的行为。
-y
: 自动覆盖同名输出文件,无需确认。-n
: 如果输出文件已存在则不执行,防止覆盖。-stats
: (通常默认开启) 显示处理进度统计信息。-v <level>
或-loglevel <level>
: 设置日志记录的详细程度。常用的<level>
包括:quiet
: 静默,几乎不输出。panic
,fatal
,error
: 只输出严重错误。warning
: 输出警告和错误。info
: 输出标准信息(默认)。verbose
,debug
,trace
: 输出更详细的调试信息。
-hide_banner
: 隐藏 FFmpeg 启动时打印的版本号、库信息和编译配置等横幅。
1 | # 示例 1: 覆盖输出文件并隐藏版本信息 |
输入选项 (Input Options)
这些选项放在特定的 -i
之前,并且只对紧随其后的那个输入文件生效。
-f <格式>
: 强制 FFmpeg 以指定的容器格式来解析输入文件(通常 FFmpeg 能自动检测,但在处理原始数据流或特殊格式时需要)。-r <帧率>
: 强制指定输入视频的帧率(例如,用于帧率信息丢失的原始视频流或图像序列)。-s <宽x高>
: 强制指定输入视频的分辨率(例如640x480
,主要用于原始视频流)。-ss <时间>
: 放在-i
之前,表示输入定位 (Input Seeking)。FFmpeg 会尝试快速跳转到接近指定时间点(可以使用秒15.5
或HH:MM:SS.ms
00:01:05.500
格式)的关键帧开始处理。优点是速度快,缺点是定位可能不完全精确到帧。-stream_loop <次数>
: 设置输入流循环次数。-1
表示无限循环(常用于将单张图片或短 GIF 做成循环背景视频)。0
表示不循环(默认)。-re
: 要求 FFmpeg 以源文件固有的帧率读取输入。如果不加此参数,FFmpeg 会尽可能快地读取文件。该选项主要用于模拟直播推流或处理实时输入设备,以匹配源的自然速率。
1 | # 示例 1:提取视频的前五秒转换为图片序列 |
代码实现与最佳实践如下:
1.使用函数封装命令、定义形参以便后续调整值
2.使用列表构造命令,防止注入攻击
当你用
subprocess.run()
运行一个外部命令(比如ffmpeg
)时,如果不特别指定stdout
和stderr
参数,那么这个外部命令(子进程)的标准输出和标准错误会直接连接到你的 Python 脚本(父进程)的标准输出和标准错误。简单来说,就是ffmpeg
打印的任何信息(无论是正常信息还是错误信息)都会直接显示在你的 Python 脚本运行的那个终端窗口里。当你给
subprocess.run()
传递stdout=subprocess.PIPE
这个参数时,你是在告诉 Python: “请不要让子进程 (ffmpeg
) 的标准输出直接打印到终端。而是,创建一个管道,把子进程的标准输出重定向到这个管道里。这样一来,我这个父进程(Python 脚本)后续就可以从这个管道里读取子进程的输出了。”在 Python 3.7 及更高版本中,
subprocess.run()
提供了一个更方便的参数capture_output=True
。设置capture_output=True
等同于同时设置stdout=subprocess.PIPE
和stderr=subprocess.PIPE
,这也是我们第一个示例使用的值
1 | import subprocess |
输出选项 (Output Options)
这些选项位于某个输出文件名之前,并且只对紧随其后的那个输出文件生效。这是控制输出文件特性最关键、最丰富的一类选项。
视频编码器选择 (-c:v
或 -vcodec
)
选择合适的视频编码器是平衡画质、文件大小、编码速度和兼容性的关键。
编码器 (值) | 常用库名 (FFmpeg) | 类型 | 压缩效率 | 编码速度 | 兼容性 | 主要用途/备注 |
---|---|---|---|---|---|---|
H.264 / AVC | libx264 | 有损 | 良好 | 快-中等 | 极好 | 最通用,Web、移动端、流媒体广泛支持。质量和效率良好。 |
H.265 / HEVC | libx265 | 有损 | 优异 | 中等-慢 | 好 | 压缩率比 H.264 高约 30-50%,但编码更耗时,部分旧设备不支持。 |
VP9 | libvpx-vp9 | 有损 | 优异 | 中等-慢 | 好 | Google 开发,开源免费,WebM 容器常用,YouTube 使用。效率类似 H.265。 |
AV1 | libaom-av1 | 有损 | 顶尖 | 极慢 | 增长中 | 最新一代开放标准,压缩率最高,但编码非常非常慢,解码要求也高。 |
MPEG-4 Visual | mpeg4 | 有损 | 一般 | 快 | 较好 | 较旧的标准,兼容性尚可,效率不如 H.264。 |
copy | copy | 无损(复制) | N/A | 极快 | 取决于容器 | 特殊值: 不重新编码,直接复制原始视频流。仅用于改变容器或截取。 |
… 其他特定编码器 | … | … | … | … | … | 如 prores , dnxhd (编辑用), h264_nvenc (Nvidia 硬编) 等。 |
选择建议:
- 追求兼容性/通用性: 首选
libx264
(H.264)。 - 追求最高压缩率 (不计时间): 选
libaom-av1
(AV1),其次libx265
(H.265) 或libvpx-vp9
(VP9)。 - 仅改变容器或截取: 优先尝试
copy
以获得最快速度和无损质量。 - 硬件加速: 如果你的硬件支持且 FFmpeg 编译时包含支持(如 Nvidia GPU 的
h264_nvenc
,hevc_nvenc
),可以尝试使用,通常能大幅提高编码速度,但质量控制方式和效果可能与软编码略有不同。
音频编码器选择 (-c:a
或 -acodec
)
编码器 (值) | 常用库名 (FFmpeg) | 类型 | 压缩效率 | 兼容性 | 主要用途/备注 |
---|---|---|---|---|---|
AAC | aac | 有损 | 良好 | 极好 | 最通用,MP4/MOV/流媒体常用,是 Apple 平台标准。质量良好。 |
Opus | libopus | 有损 | 优异 | 好 | 开放免费,特别适合语音和网络传输(低延迟、低码率下表现好),WebRTC 标准。 |
MP3 | libmp3lame | 有损 | 一般 | 极好 | 历史悠久,兼容性最好,但同等码率下效率不如 AAC/Opus。 |
Vorbis | libvorbis | 有损 | 良好 | 好 | 开放免费,常用于 Ogg, WebM 容器。 |
FLAC | flac | 无损 | 较高 | 较好 | 无损压缩,保留原始音频质量,文件较大。适合存档或对音质要求极高。 |
copy | copy | 无损 (复制) | N/A | 取决于容器 | 特殊值: 直接复制原始音频流。 |
… 其他 | … | … | … | … | 如 pcm_s16le (未压缩 PCM), alac (Apple 无损) 等。 |
选择建议:
- 通用、兼容性好: 首选
aac
。 - 网络传输、语音、低码率高质量: 首选
libopus
。 - 需要无损压缩: 选
flac
。 - 仅改变容器或截取: 尝试
copy
。
字幕编码器选择 (-c:s
或 -scodec
)
字幕相对简单,常用选项:
srt
: 输出为 SubRip (.srt) 格式(通常作为单独文件,或封装在 MKV 中)。mov_text
: 输出为 MP4/MOV 兼容的内嵌文本字幕。copy
: 直接复制原始字幕流(如果目标容器支持)。
质量与比特率控制
这是影响输出文件大小和视觉/听觉感受的关键。主要有两种策略:
比特率就是每秒钟用多少数据来记录或传输声音和图像,这个数值直接决定了音视频的清晰程度和文件的大小。
控制方式 | 对应参数 (常用) | 描述 | 优点 | 缺点 |
---|---|---|---|---|
恒定质量 | -crf <值> (视频) | 推荐用于视频。 让编码器根据画面复杂度动态调整比特率以维持感知质量恒定。值越低,质量越好,文件越大。对 x264 常用 18(高)-28(低);x265 类似,但相同值压缩率更高。 | 文件大小更可控,质量相对稳定。 | 最终比特率和文件大小不固定。 |
平均比特率 | -b:v <值> (视频) -b:a <值> (音频) | 推荐用于音频,也可用于视频。 指定输出文件的目标平均比特率(如 ‘2M’, ‘128k’)。编码器会尽量使最终平均速率接近此值。 | 文件大小更容易预测和控制。 | 简单画面可能浪费码率,复杂画面可能码率不足导致质量下降。 |
最大/最小比特率 | -maxrate <值> -minrate <值> -bufsize <值> | 通常与 -b:v 配合,限制比特率波动范围,用于流媒体兼容性。-bufsize 定义解码器缓冲区大小。 | 兼容性好,码率波动可控。 | 配置复杂,可能影响质量。 |
选择建议:
- 视频: 优先使用
-crf
控制质量,选择一个你能接受的质量和文件大小平衡点 (如 22-24)。只有在对输出文件大小有严格限制时才使用-b:v
。 - 音频: 通常使用
-b:a
指定目标比特率 (如128k
,192k
,256k
for AAC/Opus)。
编码速度 (-preset
)
编码器通常提供预设参数集,用于在编码速度和压缩效率(同等质量下文件大小)之间做权衡。
Preset 值 | 速度 | 压缩效率/质量 | CPU 消耗 |
---|---|---|---|
ultrafast | 最快 | 最低 | 最低 |
superfast | 很快 | 较低 | 较低 |
veryfast | 较快 | 较低 | 较低 |
faster | 稍快 | 一般 | 一般 |
fast | 快 | 较好 | 较高 |
medium | 默认值 | 好 | 中等 |
slow | 慢 | 更好 | 高 |
slower | 较慢 | 优异 | 较高 |
veryslow | 最慢 | 最佳 | 最高 |
placebo | (极慢) | (几乎无提升) | (极高) |
选择建议: 从 medium
或 fast
开始尝试。如果追求极致压缩率且不介意时间,可选 slow
或 slower
。如果速度是首要考虑,可选 veryfast
或 ultrafast
,但文件会大很多。
时间控制 (-ss
, -t
, -to
)
选项 | 位置 | 作用 | 精度 | 速度 |
---|---|---|---|---|
-ss <时间> | 输入前 | 输入定位 (Seeking): 从输入源的指定时间点开始读取。 | 不精确 | 快 |
-ss <时间> | 输出前 | 输出定位 (Seeking): 解码到指定时间点才开始输出。 | 精确 | 慢 |
-t <时长> | 输出前 | 限制输出的总时长。 | N/A | N/A |
-to <时间> | 输出前 | 指定输出的结束时间点 (相对于输入开始时间)。 | N/A | N/A |
选择建议:
- 快速截取大致片段:
-ss
放在-i
前。 - 精确截取片段:
-ss
放在输出文件前(会解码前面所有内容),或者先用-ss
(输入前) 定位到大概位置,再用-t
或-to
(输出前) 精确控制结束点。 - 只截取开头部分: 只用
-t
或-to
。
场景 1: 快速截取大致片段
目标: 快速从视频大约 1 分钟(60 秒)处开始,截取 15 秒长度的片段。优先考虑速度,不强求帧级别的精确。
方法: 将 -ss
放在 -i
输入文件之前(输入定位),并使用 -t
指定输出时长。可以尝试使用 -c copy
以获得最快速度。
1 | ffmpeg -ss 60 -i input.mp4 -t 15 -c copy output_fast_cut.mp4 |
场景 2: 精确截取片段
目标: 精确地从视频的第 1 分 05 秒 (00:01:05
) 开始,截取到第 1 分 15 秒 (00:01:15
) 结束(总时长 10 秒)。
将 -ss
放在输出文件之前,并配合 -to
或 -t
。FFmpeg 会解码 -ss
之前的所有内容。通常不能使用 -c copy
。
1 | ffmpeg -i input.mp4 -ss 00:01:05 -to 00:01:15 -c:v libx264 -c:a aac output.mp4 |
注意: 这种方式非常精确,但因为需要解码前面的内容,所以速度很慢,尤其当
-ss
的时间点靠后时。
若我们一个视频很长的情况下,而我们需要截取的片段而又在非常的末尾,这时候选择这种精确片段的语法就不好了,所以我们换一种思路:
先用 -ss
(输入前) 快速定位到大概位置,再用 -t
精确控制截取时长。
1 | ffmpeg -ss 00:01:00 -i input.mp4 -t 10 -c:v libx264 -c:a aac output.mp4 |
场景 3: 只截取开头部分
目标: 只保留视频的前 20 秒。
1 | # 使用 -t 指定时长 |
复杂滤镜(-filter_complex)
-filter_complex
在我们接下来需要介绍的滤镜篇十分重要!他是实现复杂的滤镜效果的核心关键点
为什么需要 -filter_complex
?
我们用的 -vf
(视频滤镜) 和 -af
(音频滤镜) 适用于简单的、线性的处理流程:一个输入流 -> 经过一个或多个滤镜(用逗号分隔) -> 一个输出流。
但如果你需要做更复杂的操作,比如:
- 处理多个输入流: 例如,把一个 logo 图片叠加到视频上(视频是输入1,logo 是输入2)。
- 一个滤镜产生多个输出: 例如,
split
滤镜可以把一个视频流复制成两份,分别进行不同处理。 - 合并多个流: 例如,把两个视频左右拼接 (
hstack
),或者把处理过的视频流和处理过的音频流合并输出。
这些情况就需要用到 -filter_complex
来定义一个滤镜图 (filtergraph)。
-filter_complex
的基本语法结构:
可以把它想象成用文字描述一个“数据流管道系统”:
1 | -filter_complex "[输入流标签1][输入流标签2]... 滤镜1=参数[输出流标签A]; [输入流标签C]滤镜2=参数[输出流标签B]; [标签A][标签B]滤镜3[最终输出标签]" |
核心组成部分解释:
[...]
(方括号 - 流标签 / Stream Labels):这就像是给在滤镜图内部流动的临时数据流(视频流、音频流)起名字。
引用输入文件流:
通常用
1
[文件索引:流标识符]
的形式。例如:
[0:v]
指的是第一个输入文件 (-i
后面第一个) 的视频流 (通常是第一个视频流)。[0:a]
指的是第一个输入文件的第一个音频流。[1:v]
指的是第二个输入文件的视频流。
自定义标签: 你可以给一个滤镜处理后的输出流起一个自定义的名字,比如
[scaled_video]
,[watermarked]
,[outv]
。这个名字可以被后续的滤镜或最后的-map
指令引用。
-map
的配合:
因为 -filter_complex
处理后的输出流是带有自定义标签的(比如上面例子中的 [outv]
),FFmpeg 不会自动将它映射到最终的输出文件。你需要使用 -map
选项来明确告诉 FFmpeg 使用哪个标签的流作为输出文件的视频流、哪个作为音频流等。
-map "[outv]"
: 将标签为outv
的流映射为输出文件的第一个视频流(通常是这样)。-map "[outa]"
: 将标签为outa
的流映射为输出文件的第一个音频流。- 你仍然可以用
-map 0:a?
这样的方式来映射未经滤镜图处理的原始输入流(比如直接复制原始音频)。
简单示例:叠加 Logo (回顾)
我们再看一下这个例子,体会一下标签和分号的作用:
1 | ffmpeg -i input.mp4 -i logo.png \ |
-filter_complex
内:[0:v]
和[1:v]
是输入标签,分别代表input.mp4
的视频流和logo.png
的视频流。overlay=10:10
是作用于这两个输入流的滤镜。[outv]
是overlay
滤镜处理完成后的输出标签。- 这里只有一个滤镜链,所以没有用到分号
;
。
-map "[outv]"
: 将带有outv
标签的视频流(叠加结果)指定为输出视频。-map 0:a?
: 将原始视频的音频(如果存在)也指定到输出。
17.2.2 **常用滤镜 (-vf
, -af
) **
FFmpeg 的滤镜系统是其最强大的功能之一,它允许你对音视频流进行各种精密的修改和处理。你可以将滤镜想象成一个个处理单元,音视频数据流过这些单元时会被修改,像 Photoshop (PS), Premiere Pro, DaVinci Resolve 这些图形界面工具非常强大,对于单张图片或单个视频的精细、创意性编辑,它们通常更直观、效率更高,因为你可以实时看到效果并进行微调。
但假设思考这么一些场景你就能够理解FFmpeg的强大之处:
网站后台自动处理用户上传的图片(统一尺寸、加水印)、视频网站自动生成不同清晰度的版本等。
用户上传视频到你的网站,后端服务器自动调用 FFmpeg 进行转码、截图、添加片头片尾等。
一个监控系统,当检测到特定事件时,自动调用 FFmpeg 截取相关录像片段并进行压缩或格式转换。
- 作用: 修改或分析音视频流的内容。常见的操作包括:调整尺寸/裁剪、旋转/翻转、叠加图像/文字、调色、降噪、改变速度、调整音量、混音等等。
- 分类:
- 视频滤镜 (
-vf
): 处理视频帧数据。 - 音频滤镜 (
-af
): 处理音频采样数据。
- 视频滤镜 (
- 数量庞大: FFmpeg 内置了数百种滤镜,覆盖了绝大部分常见的处理需求。你可以通过
ffmpeg -filters
命令查看所有支持的滤镜。
在进行滤镜处理之前,我们给出三张好看的原图作为参考



(1) 模糊 (boxblur
)
参数: boxblur
。用于实现均匀模糊效果。
命令行示例:
1 | ## ./ffmpeg -i 1.jpg -vf boxblur=2 blur1.jpg |
(注:示例命令中的 ./ffmpeg
通常在 Linux/macOS 下表示当前目录的可执行文件,Windows 下或配置好 PATH 后直接用 ffmpeg
即可。以下示例统一使用 ffmpeg
。)
说明: 值越大越模糊。以下是值分别为 2、4、8 的效果:



(2) 变色
FFmpeg 提供了多种变色方法。
(a) colorbalance
通过调整 RGB 三个颜色通道在不同亮度区域(阴影、中间调、高光)的权重来实现色彩平衡调整。
参数说明:
选项有三组,分别对应阴影(shadows/s
)、中间调(midtones/m
)、高光(highlights/h
):
rs
,gs
,bs
: 调整阴影部分的红/绿/蓝。rm
,gm
,bm
: 调整中间调的红/绿/蓝。rh
,gh
,bh
: 调整高光的红/绿/蓝。
每个选项的值范围为 [-1, 1]
。正数表示增强该颜色在该区域的影响力(偏向该色),负数表示减弱(远离该色)。
命令行示例:
1 | ## 增强阴影中的红色 |
效果图:




(b) colorchannelmixer
通过一个 3x4 (或 4x4) 矩阵对 RGBA 四个通道进行线性组合,重新计算每个输出通道的值。可以实现灰度、各种色调(如棕褐色)等复杂效果。
参数说明:
需要提供 12 个(用于 RGB 输出)或 16 个(用于 RGBA 输出)用冒号 :
分隔的权重值。顺序为:rr:rg:rb:ra:gr:gg:gb:ga:br:bg:bb:ba[:ar:ag:ab:aa]
。计算公式为(以红色输出为例):R_out = R_in*rr + G_in*rg + B_in*rb + A_in*ra
(Gout, Bout, Aout 同理)权重值通常在 [0, 1]
范围内。
命令行示例:
1 | ## 灰度效果 (一种近似计算) |
效果图:


调整图像的色相 (Hue) 和 饱和度 (Saturation)。
参数说明:
h=<角度>
: 色相角度 (单位:度),在色轮上旋转颜色。范围[0, 360]
循环,默认 0。s=<数值>
: 饱和度。范围[-10, 10]
,默认 1。大于 1 增强饱和度,小于 1 降低,0 为灰度,负数为补色效果。H=<弧度>
: 同h
,但单位是弧度。b=<数值>
: 亮度。范围[-10, 10]
,默认 0。
有关色相、饱和度、亮度请详见色彩三要素
命令行示例:
1 | ## 改变色相到 180 度,饱和度不变 |


(d) lutyuv
/ lutrgb
这两个滤镜应用查找表 (LUT) 的概念来进行颜色转换,但它们的主要工作方式是基于你提供的数学表达式来计算每个颜色分量的输出值。
lutyuv
: 在 YUV 颜色空间操作(Y: 亮度, U/V: 色度)。lutrgb
: 在 RGB 颜色空间操作(R: 红, G: 绿, B: 蓝)。
Y = 亮度 (有多亮)
U = 蓝色色度差 (颜色有多偏蓝/黄)
V = 红色色度差 (颜色有多偏红/青)
视频压缩和传输常常使用 YUV (或类似的 YCbCr) 而不是我们屏幕显示常用的 RGB(红绿蓝),主要是符合人眼特性、与压缩效率高两个优点
它们的核心是通过表达式,根据输入像素各分量的当前值 (val
) 来计算输出像素各分量的新值。
参数说明
你需要为想要修改的颜色分量指定一个计算表达式。例如,对于 lutyuv
,你可以指定 y='<表达式>'
, u='<表达式>'
, v='<表达式>'
。
表达式中可用的常用变量包括:
变量名 | 含义 | 示例用法 |
---|---|---|
val | 当前正在处理的颜色分量的输入值。 | y=2*val (亮度翻倍) |
negval | 输入值的反转值,等于 maxval + minval - val 。 | y=negval (亮度反转) |
clipval | 同 val ,但其值会被自动限制在对应分量的有效范围内。 | |
minval | 当前颜色分量允许的最小值 (例如 YUV 中的 16 或 RGB 中的 0)。 | y=maxval+minval-val |
maxval | 当前颜色分量允许的最大值 (例如 YUV 中的 235/240 或 RGB 中的 255)。 | y=maxval-val |
w , h | 图像/视频的宽度和高度 (像素)。 | x/w (归一化坐标) |
x , y | 当前正在处理的像素的坐标 (从 0 开始)。 | y=val+x/10 |
t | 当前帧的时间戳 (秒)。 | y=val*sin(t) |
表达式支持常见的数学运算符 (+
, -
, *
, /
, ^
) 和函数 (sin
, cos
, max
, min
, clip
, if
等)。
命令行示例 (lutyuv
)
1 | # 底片效果 (反转 Y, U, V 三个分量) |
效果图




重要说明:基于表达式的 LUT vs 加载 LUT 预设文件
常识来说LUT 被描述为一种可以保存和加载的“滤镜效果文件”(通常是 .cube
, .3dl
, .look
等格式)。这种用法在视频编辑和调色领域非常普遍。
这两种关于 LUT 的描述都是正确的,但指向的是不同的概念和 FFmpeg 功能:
LUT 预设文件 (
.cube
等):- 存储了一个预先计算好的、庞大的颜色映射表,定义了各种输入颜色如何精确地转换为输出颜色。
- 常用于应用复杂的色彩风格(如电影感、复古色调)或进行色彩空间转换(如 Log 转 Rec.709)。
- 在 FFmpeg 中,加载和应用这类文件 主要使用
lut3d
滤镜 (对于 3D LUTs,如.cube
) 或lut1d
滤镜 (对于 1D LUTs)。
FFmpeg 的
lutyuv
/lutrgb
/lut
滤镜 (基于表达式):- 如上所述,这些滤镜允许你使用数学表达式来实时定义颜色转换规则。
- 它们非常灵活,适合进行程序化的、基于像素值或坐标的颜色调整(例如上面示例中的反相、去色、亮度调整)。
- 但它们不直接加载
.cube
等外部预设文件。
如何使用 FFmpeg 加载常见的 .cube
LUT 文件?
你需要使用 lut3d
滤镜:
1 | # 示例:将 "my_film_look.cube" 这个 LUT 文件应用到视频上 |
-vf lut3d="<你的LUT文件路径>"
: 这里的参数就是你的.cube
(或其他支持的 LUT 格式) 文件的路径。
(3) 裁剪 (crop
)
从视频或图像中裁剪出指定尺寸和位置的矩形区域(基于图片大小)
参数说明: crop=width:height:x:y
或 crop=w=W:h=H:x=X:y=Y
w
,h
: 输出宽度和高度。可用iw
,ih
(输入宽高)。x
,y
: 裁剪区域左上角坐标。默认居中。
命令行示例:
1 | ## 从 (100, 100) 裁剪 200x300 |


(4) 去 Logo (delogo
)
在指定矩形区域内应用像素插值或模糊,尝试去除静态 Logo。效果有限,如下图,此图片携带b站的水印
参数说明: delogo=x=X:y=Y:w=W:h=H[:band=B][:show=S]
x,y,w,h
: Logo 区域。show
: 设为1
时显示处理区域的绿色边框(用于调试),对于调试来说,建议使用在线图片坐标拾取工具 - UU在线工具
左上角: x = 534
, y = 22
右下角 : x = 763
, y = 76
我们可以计算出 delogo
滤镜需要的宽度 (w
) 和高度 (h
):
宽度 w
= 右下角 x - 左上角 x = 763 - 534
= 229
高度 h
= 右下角 y - 左上角 y = 76 - 22
= 54
命令行示例:
1 | ffmpeg -i 4.png -vf "delogo=x=534:y=22:w=229:h=54" output_delogo.jpg |
效果图如下:请注意: delogo
的实际效果取决于水印周围的背景复杂度,它主要是基于边缘像素进行插值填充,可能不会完美去除或产生理想的模糊效果,有时看起来会有些“涂抹”感。
(5) 加边框 (drawbox
)
在图像或视频上绘制矩形边框。
参数说明: drawbox=x=X:y=Y:w=W:h=H:color=C[@A][:t=T]
x,y,w,h
: 边框位置和尺寸。默认x=0, y=0, w=iw, h=ih
(整个画面)。color
或c
: 边框颜色,可以是颜色名 (red
,blue
) 或十六进制 (0xFF0000
),可以用@透明度
指定透明度 (如red@0.5
)。默认黑色。thickness
或t
: 边框线宽(像素)。fill
表示填充整个矩形。默认 3。
命令行示例:
1 | ## 绘制默认黑色实心边框 (充满边界) |
效果图



(6) 画网格 (drawgrid
)
在视频上绘制网格线。
参数说明: drawgrid=width=W:height=H:thickness=T:color=C[@A]
width
或w
: 网格单元的宽度。可用iw
(输入宽)。height
或h
: 网格单元的高度。可用ih
(输入高)。thickness
或t
: 网格线的厚度。color
或c
: 网格线颜色和透明度。
命令行示例:
1 | ## 绘制 3x3 九宫格 (单元宽高为输入宽/高除以3),白色半透明,线宽 2 |
效果图:


(7) 添加字幕 (subtitles
或 drawtext
)
对于视频在线转SRT字幕,推荐离线语音转文字WhisperDesktop1.7魔改版,自带100种语言,安装包4G
subtitles
滤镜: 用于烧录(硬编码)ASS 或 SRT 等格式的字幕文件到视频帧上。1
2
3
4# 烧录 SRT 字幕,使用默认样式
ffmpeg -i input.mp4 -vf subtitles=subtitle.srt output_hardsub.mp4
# 烧录 ASS 字幕,并强制使用 ASS 文件内定义的样式
ffmpeg -i input.mp4 -vf "subtitles=subtitle.ass:force_style='PrimaryColour=&H00FFFFFF&,Fontsize=24'" output_hardsub_styled.mp4drawtext
滤镜: 用于在视频上绘制动态或静态文本,可以设置字体、大小、颜色、位置、滚动等,非常灵活,但配置复杂。1
2# 在左上角显示时间码
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='%{pts\:hms}':x=10:y=10:fontsize=24:fontcolor=yellow" output_timecode.mp4
(8) 画边缘 (edgedetect
)
作用:
此滤idge]用于检测并绘制图像或视频中的边缘(即像素亮度/颜色发生剧烈变化的地方)。它通常基于 Canny 边缘检测算法。
参数说明:edgedetect=low=L:high=H[:mode=M]
low
,high
: Canny 算法的低阈值和高阈值,范围[0, 1]
,且low <= high
。这两个阈值共同决定了哪些变化被识别为边缘。阈值越高,检测到的边缘越少,只有非常明显的边缘才会被保留;阈值越低,检测到的边缘越多,可能会包含一些噪音或不重要的细节。需要根据具体图像和需求调整。mode
: 控制输出的模式,常用的有:wires
(默认): 输出一个黑色背景、白色线条表示边缘的图像。这就是你看到的“线稿”效果。colormix
: 将检测到的边缘(通常为白色)与原始图像的颜色进行混合,产生一种带有彩色边缘描边的效果。canny
: 输出 Canny 算法中间过程产生的灰度边缘强度图。
edgedetect
的实际用途:
你可能会问,只是得到一个“线稿”有什么用?实际上,边缘检测是许多更复杂任务的基础或辅助步骤:
- 计算机视觉预处理: 在进行目标识别、特征提取、图像分割等高级计算机视觉任务前,边缘检测可以提取图像的关键结构信息,减少需要处理的数据量,并突出对象的轮廓。
- 艺术/风格化效果: 可以故意使用
wires
模式来创造素描、卡通、技术绘图等艺术风格。结合其他滤镜(如与原图叠加、调整颜色等)可以产生更多样的视觉效果。
命令行示例 (不同模式):
示例 1:
wires
模式 (默认 - 线稿效果)
使用不同的阈值组合,观察边缘检测的敏感度变化。1
2
3
4
5# 较低阈值,检测更多边缘细节
ffmpeg -i 1.png -vf edgedetect=low=0.1:high=0.2 edge_py_1_01_02.jpg
# 较高阈值,只保留较强边缘
ffmpeg -i 1.png -vf edgedetect=low=0.5:high=0.8 edge_py_2_05_08.jpg效果图:
示例 2:
colormix
模式 (彩色边缘描边)
将边缘信息(白色)与原图颜色混合。1
ffmpeg -i 1.png -vf edgedetect=low=0.1:high=0.4:mode=colormix edge_py_2_colormix.jpg
这个命令会生成一个保留了原图大概颜色,但在边缘处有明显白色(或受原色影响的亮色)描边的图像,视觉效果与
wires
完全不同。
(9) EQ 效果 (eq
)
调整视频的亮度 (Brightness)、对比度 (Contrast)、饱和度 (Saturation) 和 Gamma。
参数说明:
brightness
: 亮度,范围[-1.0, 1.0]
,默认 0。contrast
: 对比度,范围[-2.0, 2.0]
,默认 1。saturation
: 饱和度,范围[0.0, 3.0]
,默认 1。gamma
: Gamma 值 (整体亮度调整),范围[0.1, 10.0]
,默认 1。gamma_r
,gamma_g
,gamma_b
: 分别调整红绿蓝通道的 Gamma。gamma_weight
: Gamma 应用的权重。
命令行示例:
1 | # 增加亮度 (增加 0.3) |
效果图:
增加亮度 (brightness=0.3)

降低亮度 (brightness=-0.2)

增加对比度 (contrast=1.5)

降低对比度 (contrast=0.7)

增加饱和度 (saturation=1.8)

降低饱和度 (saturation=0.3)

增加Gamma (gamma=1.6)

降低红色通道 (gamma_r=0.5)

增加蓝色通道 (gamma_b=1.5)

(10) 缩放 (scale
)
调整视频或图像的分辨率(尺寸)。
参数说明: scale=width:height[:flags=F]
width
,height
: 目标宽度和高度。可以使用iw
,ih
(输入宽高) 进行计算,-1
或-2
表示按比例自动计算(-2
保证结果为偶数)。flags
: 缩放算法(如bilinear
,bicubic
,lanczos
等),影响速度和质量。
命令行示例:
1 | ## 缩放到固定 200x200 (可能变形) |
效果图:


(11) 等比放大 (hqx
)
使用 hqx 算法进行高质量的整数倍放大(2x, 3x, 4x)。
参数说明: hqx=n=N
n
: 放大倍数,必须是 2, 3 或 4。
命令行示例:
1 | ## 放大 4 倍 |
(12) 横向倒置 (hflip
)
水平翻转图像或视频(镜像效果)。
参数说明: 无。
命令行示例:
1 | ffmpeg -i 3.png -vf hflip hflip.jpg |
效果图:
(13) 纵向倒置 (vflip
)
垂直翻转图像或视频。
参数说明: 无。
命令行示例:
1 | ffmpeg -i 3.png -vf vflip vflip.jpg |
效果图:
(14) 加噪音 (noise
)
为视频添加不同类型的噪音。
其中Y/U/V/S分别指的是☞ Y(亮度)、U(蓝色度差)、V(红色度差)、A(透明度)分量的噪音强度,一般会使用alls或allf,指全部色彩
参数说明: noise=alls=S[:allf=F]
或指定分量 ys
, us
, vs
, as
和 yf
, uf
, vf
, af
。
alls
(或ys
,us
…): 噪音强度,范围[0, 100]
,默认 0。allf
(或yf
,uf
…): 噪音标志/类型,可以是:t
(temporal): 随时间变化的噪音。u
(uniform): 空间上均匀但不随时间变化的噪音。p
(pattern): 随时间重复的图案噪音。a
(averaged): 时间上平滑(平均)的图案噪音。- 可以组合,如
t+u
。
命令行示例:
1 | ## 添加强度为 100 的临时+统一噪音 |
效果图:



(15) 加水印 (overlay
)
作用:
overlay
滤镜是 FFmpeg 中非常常用的一个功能,它的作用是将一个视频流(或图片流,图片会被当作单帧视频)叠加到另一个视频流的上方,就像给视频添加“图层”一样。这常用于添加 logo、水印、画中画 (PiP) 等效果。
核心概念:
- 至少需要两个输入: 一个是主视频流 (背景),另一个是要叠加的视频/图片流 (前景/水印)。
- 复杂滤镜 (
-filter_complex
): 因为涉及多个输入流,overlay
通常在-filter_complex
中使用。 - 坐标定位: 你可以精确控制叠加层(水印)在背景视频上的位置。
- 时间控制: 可以控制叠加层何时出现、何时消失。
主要参数 (overlay=...
):
参数名 (命令行) | 描述 | 常用值/表达式示例 |
---|---|---|
x=<表达式> | 叠加层左上角的 水平 (X) 坐标。 | 10 (左边距 10), main_w-overlay_w-10 (右边距 10), (main_w-overlay_w)/2 (水平居中) |
y=<表达式> | 叠加层左上角的 垂直 (Y) 坐标。 | 10 (上边距 10), main_h-overlay_h-10 (下边距 10), (main_h-overlay_h)/2 (垂直居中) |
eof_action | 当较短的那个输入流结束时,如何处理? | repeat (默认, 对静态图片水印常用,会保持最后一帧), endall (结束整个处理), pass (移除叠加层,保留主视频流) |
shortest | (布尔值 0 或1 ) 注意: 这个通常作为输出选项 (-shortest ) 使用。 | -shortest (命令行) |
format | 指定内部处理时使用的像素格式,影响是否支持透明度。 | rgb , rgba , yuv420 , yuva420p 等 |
表达式中可用的变量:
main_w
,W
: 主视频流(背景)的宽度。main_h
,H
: 主视频流(背景)的高度。overlay_w
,w
: 叠加层(水印)的宽度。overlay_h
,h
: 叠加层(水印)的高度。t
: 当前时间戳 (秒)。
命令行示例:
示例 1: 添加静态 PNG 图片水印 (带透明度) 到右下角
假设 input.mp4
是主视频,logo.png
是带透明背景的水印图片。
1 | ffmpeg -i input.mp4 -i logo.png \ |
-i input.mp4 -i logo.png
: 指定两个输入文件。-filter_complex "[0:v][1:v]overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10[outv]"
:[0:v]
代表第一个输入(视频)的视频流。[1:v]
代表第二个输入(logo)的视频流(图片被当作单帧视频)。overlay=...
: 应用 overlay 滤镜。x=main_w-overlay_w-10
: 设置 x 坐标为 主视频宽度 - logo宽度 - 10像素(右边距10)。y=main_h-overlay_h-10
: 设置 y 坐标为 主视频高度 - logo高度 - 10像素(下边距10)。[outv]
: 将处理后的视频流标记为outv
。
-map "[outv]"
: 将标记为outv
的视频流映射到输出。-map 0:a?
: 将第一个输入文件中的音频流(如果存在?
)映射到输出。-c:v libx264 -preset fast
: 对视频进行 H.264 重新编码(烧录水印需要重编码),使用较快的预设。-c:a copy
: 直接复制原始音频流。output_watermarked.mp4
: 输出文件名。
示例 2: 添加动态 GIF 水印 (循环播放) 到左上角
假设 input.mp4
是主视频,animated_logo.gif
是动态水印。
1 | # 注意:GIF 作为输入时,需要特殊的输入选项来控制循环 |
-ignore_loop 0
: 输入选项 (针对 GIF),告诉 FFmpeg 不要忽略 GIF 文件内部定义的循环次数(如果 GIF 本身只循环几次,这个选项会让它按原样播放)。如果 GIF 本身是无限循环的,此选项影响不大。-stream_loop -1
: 输入选项 (针对 GIF),告诉 FFmpeg 在 GIF 播放完一次后,无限循环地重新读取 GIF 输入流。这确保了即使 GIF 本身时长很短,它也会在整个视频时长内持续显示。如果想让 GIF 只播放一次然后消失,可以将eof_action
设为pass
并且不使用-stream_loop -1
(或者结合-shortest
输出选项)。-filter_complex "[0:v][1:v]overlay=x=10:y=10:eof_action=repeat[outv]"
:x=10:y=10
: 将 GIF 放在左上角(边距 10)。eof_action=repeat
: 当 GIF 流结束时(如果-stream_loop
不是-1
),保持其最后一帧。由于我们用了-stream_loop -1
,这个参数在这里影响不大。
- 其他
-map
,-c:v
,-c:a
参数同上。 -shortest
:这个选项告诉 FFmpeg:“当所有输入流中,最短的那个流结束时,就结束整个输出文件。” 在你的例子中,input.mp4
是有限时长的(比如 1 分多钟),而无限循环的 GIF 被视为无限时长,所以-shortest
会让输出在input.mp4
播放完毕时自动停止。
示例三:添加固定尺寸 (64x64) 且位置随机飘动的动态水印
1 | ffmpeg -i input.mp4 -ignore_loop 0 -stream_loop -1 -i animated_logo.gif -filter_complex "[1:v]scale=h=64:w=-2[scaled_logo];[0:v][scaled_logo]overlay=x='if(eq(mod(trunc(t*50/(main_w-overlay_w))\,2)\,0)\,mod(t*50\,main_w-overlay_w)\,main_w-overlay_w-mod(t*50\,main_w-overlay_w))':y='if(eq(mod(trunc(t*50/(main_h-overlay_h))\,2)\,0)\,mod(t*50\,main_h-overlay_h)\,main_h-overlay_h-mod(t*50\,main_h-overlay_h))'[outv]" -map "[outv]" -map 0:a? -c:v libx264 -preset fast -c:a copy - |
(16) 加底板/画布扩展 (pad
)
扩展视频或图像的画布尺寸,并可以用指定颜色填充新增区域。常用于需要固定输出尺寸或添加边框背景的场景。
参数说明: pad=width=W:height=H[:x=X][:y=Y][:color=C]
width
,height
: 输出画布的总宽度和总高度。必须大于等于输入尺寸。x
,y
: 输入图像在输出画布上的左上角坐标。默认居中(ow-iw)/2:(oh-ih)/2
。color
: 填充扩展区域的颜色,默认黑色。
命令行示例:
1 | ## 将 2.jpg 放到一个 800x800 的紫色底板上,原图放在 (40, 40) 的位置 |
效果图:
(17) 旋转 (rotate
)
按指定角度旋转视频(围绕中心点)。
参数说明: rotate=angle=A[:out_w=OW][:out_h=OH][:bilinear=B]
angle
或a
: 旋转角度。注意:单位是弧度 (Radians)。可以使用PI
常量和数学表达式。顺时针为负,逆时针为正。例如PI/6
(30度),-PI/2
(-90度)。要使用角度需转换:angle=45*PI/180
。out_w
,out_h
: (可选) 输出的宽度和高度,默认与输入相同。旋转后图像可能会超出原边界,可以用ow='hypot(iw,ih)'
来设置足够大的画布。bilinear
: 是否使用双线性插值 (0 或 1),默认 1 (使用)。
命令行示例:
1 | ## 逆时针旋转 PI/6 弧度 (30度) |
效果图:


(18) 光晕/晕影 (vignette
)
在图像或视频边缘添加暗角(或亮角)效果。
参数说明: vignette=angle=A[:x0=X][:y0=Y][:mode=M][:eval=E]
angle
或a
: 控制光晕形状的角度表达式(单位:弧度)。常用PI/4
(圆形) 或PI/5
。x0
,y0
: 光晕中心的相对坐标(0 到 1),默认 0.5 (中心)。mode
: 模式 (backward
,forward
)。eval
: 评估模式 (init
,frame
)。
命令行示例:
1 | ## 添加一个圆形暗角 |
效果图:
(19) 淡入淡出 (fade
, afade
)
作用:
为视频 (fade) 或音频 (afade) 添加淡入 (Fade In) 或淡出 (Fade Out) 效果。这在视频开头、结尾或者场景切换时非常常用。
主要参数:
type或 t: 指定淡入淡出类型。
in
: 淡入效果。out
: 淡出效果。
start_time
或st
: 效果开始的时间点(单位:秒)。对于淡入,通常是0
;对于淡出,需要计算好(视频总时长 - 淡出时长)。duration
或d
: 效果持续的时长(单位:秒)。color
或c
(仅fade
): 指定淡入/淡出的目标颜色,默认是黑色。例如color=white
可以实现淡入自白色或淡出至白色。alpha
: 值为1
时,只对 alpha 透明通道应用淡入淡出,可用于实现透明度的渐变。默认0
。
命令行示例:
1 | # 示例 1: 视频前 2 秒从黑色淡入,最后 3 秒淡出到黑色 (假设视频总长 35 秒) |
(20) 旋转 90/180/270 度 (transpose
)
作用:
对视频进行精确的 90 度倍数旋转或翻转。相比于 rotate 滤镜(它允许任意角度旋转但可能涉及复杂的插值和画布调整),transpose 对于标准的 90 度旋转更简单、更常用,且通常效率更高。
主要参数:
1 | transpose=<方向值> |
0
: 逆时针旋转 90 度并垂直翻转。1
或clock
: 顺时针旋转 90 度。 (常用)2
或cclock
: 逆时针旋转 90 度。 (常用)3
或clock_flip
: 顺时针旋转 90 度并垂直翻转。- (还有
cclock_flip
等)
命令行示例:
1 | # 将视频顺时针旋转 90 度 (例如,竖屏拍的视频转成横屏) |
(21) 改变播放速度 (setpts
, atempo
)
作用:
改变视频 (setpts) 或音频 (atempo) 的播放速度,实现快放或慢放效果。
setpts=<表达式>
(视频): 通过修改视频帧的显示时间戳 (Presentation Timestamp) 来改变速度。atempo=<倍数>
(音频): 调整音频的播放速度,同时尽量保持音高不变(这是它与简单地改变采样率或asetpts
的主要区别)。
主要参数/表达式:
setpts
表达式:PTS/N
: 将播放速度提高 N 倍 (例如PTS/2
是 2 倍速)。PTS*N
: 将播放速度减慢 N 倍 (例如PTS*2
是 0.5 倍速)。PTS-STARTPTS
: 让时间戳从 0 开始(有时用于修复时间码问题)。
atempo
倍数:1.0
是原速。2.0
是 2 倍速。0.5
是 0.5 倍速 (慢放)。- 注意:
atempo
滤镜接受的倍数范围有限制 (通常在 0.5 到 100.0 之间)。对于超出范围的速度调整,可以链式调用多个atempo
滤镜 (例如atempo=2.0,atempo=2.0
实现 4 倍速)。
重要: 改变视频速度时,通常需要同时改变音频速度以保持音画同步。因此 setpts
和 atempo
常常在 -filter_complex
中配合使用。
命令行示例:
1 | # 示例 1: 将视频和音频都加速到 1.5 倍速 |
(22) 绘制文本 (drawtext
) 详解
作用:
在视频帧上绘制静态或动态文本,功能非常强大,可以控制字体、大小、颜色、位置、背景框、滚动、时间显示等。
主要参数 (非常多,仅列举常用):
fontfile=<字体文件路径>
: 必需 (除非系统配置了默认字体且 FFmpeg 能找到),指定 TrueType (.ttf) 或 OpenType (.otf) 字体文件的路径。路径中若有特殊字符或空格,需要恰当引用或转义。text=<文本内容>
: 要绘制的文本字符串。可以包含变量(如时间码、帧号、元数据)和表达式。例如text='Frame %{frame_num}'
或text='%{pts\:hms}'
(显示 HH:MM:SS.ms 格式时间码)。特殊字符需要转义。x=<表达式>
: 文本左上角的水平 (X) 坐标。可以使用w
,h
(视频宽高),tw
,th
(文本宽高),line_h
(行高) 等变量。例如(w-tw)/2
(水平居中)。y=<表达式>
: 文本左上角的垂直 (Y) 坐标。例如h-th-10
(下边距 10)。fontsize=<大小>
: 字体大小(像素)。fontcolor=<颜色>
: 字体颜色 (颜色名如white
,yellow
, 或十六进制0xFF0000
, 或表达式)。box=<1或0>
: 是否绘制背景框,1
表示绘制,0
(默认) 不绘制。boxcolor=<颜色>[@透明度]
: 背景框颜色和可选透明度 (如black@0.5
)。boxborderw=<宽度>
: 背景框边框的宽度。shadowx
,shadowy
: 文字阴影的 X, Y 偏移。shadowcolor
: 阴影颜色。enable='<表达式>'
: 条件渲染!只有当表达式求值为非零时,才绘制文本。例如enable='between(t,5,10)'
表示只在视频时间 5 到 10 秒之间显示文本。
命令行示例 (来自你的笔记):
1 | # 示例 1: 左右滚动的字幕 (需要根据你的字体路径修改 fontfile) |
(23) 视频堆叠 (hstack
, vstack
, xstack
)
作用:
将多个视频输入水平 (hstack)、垂直 (vstack) 或按自定义网格 (xstack) 布局拼接在一起,形成一个更大的视频画面。这在制作对比视频、画中画(另一种方式)或多画面监控展示时非常有用。这需要使用 -filter_complex。
主要参数:
hstack
,vstack
:inputs=<N>
: 指定要堆叠的视频输入流的数量。必需。shortest=<0|1>
: 设为1
时,输出时长以最短的那个输入流为准。默认0
。
xstack
:(更复杂,用于网格布局)
inputs=<N>
: 输入流数量。layout=<布局字符串>
: 定义网格布局,例如0_0|w0_0|0_h0|w0_h0
表示 2x2 网格。shortest=<0|1>
: 同上。fill=<颜色>
: 当布局尺寸大于输入流总尺寸时,用指定颜色填充空白区域。
注意:
- 默认情况下,
hstack
/vstack
要求所有输入视频具有相同的高度(对于hstack
)或相同的宽度(对于vstack
)。如果尺寸不同,你需要先用scale
滤镜统一尺寸。 xstack
则会自动将所有输入缩放到网格单元允许的最大尺寸。
命令行示例:
1 | # 示例 1: 水平并排拼接两个视频 (左右排列) |
(24) 锐化 (unsharp
, smartblur
)
作用:
提高图像或视频的清晰度,突出细节。有多种锐化滤镜,unsharp (反锐化掩模) 是其中常用的一种,效果比较自然。smartblur 则可以在模糊的同时保留边缘(也可用于轻微锐化)。
主要参数 (unsharp
):
luma_msize_x
或lx
: Luma (亮度) 矩阵的水平大小 (奇数, 3-63, 默认 5)。luma_msize_y
或ly
: Luma 矩阵的垂直大小 (奇数, 3-63, 默认 5)。luma_amount
或la
: Luma 锐化/模糊的强度。正值锐化,负值模糊。范围[-1.5, 1.5]
,默认1.0
(轻微锐化)。值越大锐化越强。chroma_msize_x
/cx
,chroma_msize_y
/cy
,chroma_amount
/ca
: 对应 Chroma (色度) 通道的参数,用法同 Luma。通常调整 Luma 即可。
命令行示例:
1 | # 示例 1: 应用中等强度的锐化 (使用 5x5 矩阵,亮度强度 0.8) |
- 注意: 过度锐化会导致图像出现噪点、光晕(halos)和不自然的边缘,需要适度调整参数。
17.2.3 流标识符 (Stream Specifiers) 详解
为了精确地对多媒体文件中的特定流进行操作,需要使用流标识符。
标识符 | 含义 | 示例用法 | ffmpeg-python 对应 (概念) |
---|---|---|---|
v | 文件中所有的视频流 | -vn (禁用视频), -map v | in_node['v'] (通常指第一个) |
a | 文件中所有的音频流 | -an (禁用音频), -map a | in_node['a'] (通常指第一个) |
s | 文件中所有的字幕流 | -sn (禁用字幕), -map s? | in_node['s'] (通常指第一个) |
N (数字) | 文件中绝对索引为 N 的流 (从 0 开始) | -map 0:1 (映射文件 0 的流 1) | in_node[1] |
v:N | 文件中第 N+1 个视频流 (索引从 0 开始) | -c:v:0 libx264 (设置第 1 个视频流编码) | in_node['v:0'] 或 in_node.video |
a:N | 文件中第 N+1 个音频流 (索引从 0 开始) | -b:a:1 192k (设置第 2 个音频流码率) | in_node['a:1'] |
s:N | 文件中第 N+1 个字幕流 (索引从 0 开始) | -map 0:s:0 (映射文件 0 的第 1 个字幕) | in_node['s:0'] |
i:STREAM_ID | (较新版本) 根据流的唯一 ID 选择 | -map i:137 | (需手动过滤) |
p:PROGRAM_ID[:STREAM_SPEC] | (较新版本) 根据节目 ID 选择 (用于 TS 流等) | -map p:101 或 -map p:101:v | (需手动过滤) |
m:key[:value] | 根据流的元数据选择 | -map m:language:eng | (需手动过滤) |
在 ffmpeg-python
中,我们主要通过字典访问方式(如 in_node['a:1']
)来选择流。
想象一下,一个多媒体文件(比如一个 .mkv
或 .mp4
文件)就像一个大包裹。这个包裹里可能装了很多东西,这些东西就是流 (Stream):
- 可能有一段视频画面 (Video Stream)
- 可能不止一段音频:比如一条是电影原声普通话 (Audio Stream 0),一条是粤语配音 (Audio Stream 1),还有一条是导演评论音轨 (Audio Stream 2)。
- 可能还有几条字幕:一条是中文字幕 (Subtitle Stream 0),一条是英文字幕 (Subtitle Stream 1)。
FFmpeg 的默认行为 (没有流标识符时):
如果你只给 FFmpeg 一个简单的命令,比如 ffmpeg -i input.mkv output.mp4
,它会尝试自己做决定,从 input.mkv
里选一些流放到 output.mp4
里。它通常会:
- 选一个它认为“最好”的视频流(比如分辨率最高的那个)。
- 选一个它认为“最好”的音频流(比如声道数最多的那个)。
- 可能还会选一个字幕流(比如第一个)。
问题来了:
- 如果
input.mkv
里有国语和粤语两条音轨,但 FFmpeg 默认选了粤语,而你其实想要国语的,怎么办? - 如果你想把国语和粤语两条音轨都保留在输出文件
output.mp4
里,怎么办? - 如果你只想提取视频,完全不要任何音频和字幕,怎么办?
- 如果你有两个输入文件,想用第一个文件的视频配上第二个文件的音频,怎么办?
流标识符的作用:精确的“指名道姓”
这时候,流标识符就派上用场了!它就像给包裹里的每一样东西(每个流)都编上号或者打上标签,让你能够精确地告诉 FFmpeg 你要对哪个具体的东西进行操作。
它最常用的地方是配合 -map
输出选项:
-map
的作用: 这个选项用来手动指定哪些流应该被包含在输出文件中。一旦你使用了-map
,FFmpeg 就不再使用默认规则去猜了,只有你明确-map
指定的流才会被输出。配合流标识符:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mp4
- `-map 0:v`: 选择第一个输入的所有视频流。 - `-map 0:a`: 选择第一个输入的所有音频流。 - 结果 `output_va.mkv` 会包含原文件所有的视频和音频流。1
2
3
4
5
6
7
8
- `-map 0:v:0`: 告诉 FFmpeg,选择第一个输入文件 (`0`) 的第一个视频流 (`v:0`)。
- `-map 0:a:1`: 告诉 FFmpeg,选择第一个输入文件 (`0`) 的第二个音频流 (`a:1`)(假设这是粤语音轨)。
- `-c copy`: 直接复制选中的流。
- 结果 `output.mp4` 就只包含指定的那个视频流和粤语音轨。
- ```bash
ffmpeg -i input.mkv -map 0:v -map 0:a -c copy output_va.mkvffmpeg -i video.mp4 -i audio.mp3 -map 0:v -map 1:a -c copy output_merged.mp4
- `-map 0`: 先选择第一个输入的所有流。 - `-map -0:s`: 然后**取消选择**第一个输入的所有字幕流 (`-` 号表示取消)。 - 结果 `output_no_subs.mkv` 包含原视频和音频,但不含字幕。1
2
3
4
5
6
7
- `-map 0:v`: 选择第一个输入 (`video.mp4`) 的视频流。
- `-map 1:a`: 选择第二个输入 (`audio.mp3`) 的音频流。
- 结果 `output_merged.mp4` 就是用第一个视频配上第二个音频。
- ```bash
ffmpeg -i input.mkv -map 0 -map -0:s -c copy output_no_subs.mkv
流标识符的其他用途:
除了配合 -map
,流标识符还可以用来给特定的流指定选项:
-c:a:0 aac -b:a:0 128k
: 对第一个音频流 (a:0
) 使用 AAC 编码,比特率为 128k。-c:a:1 libopus
: 对第二个音频流 (a:1
) 使用 Opus 编码。-metadata:s:a:0 language=eng
: 为第一个音频流 (a:0
) 设置语言元数据为英语。- 在
-filter_complex
中,像[0:v]
这样的标签实际上也是基于流标识符来引用特定的输入流。
ffmpeg-python
中的对应:
使用ffmpeg-python
库时,选择流的方式更 Pythonic:
input_node['v']
或input_node.video
通常选择第一个视频流。input_node['a:1']
选择第二个音频流。input_node[0]
选择第一个流(不区分类型)。 库在底层会将这些选择转换成合适的 FFmpeg 命令行-map
参数或滤镜图标签。
17.2.4 FFmpeg 自身能力查询命令
为何要查询 FFmpeg 的能力?
在你编写任何调用 FFmpeg 的脚本或程序之前,了解你所使用的 FFmpeg 版本究竟能做什么至关重要。FFmpeg 功能极其强大,但并非所有安装版本都包含全部功能。例如,某些编解码器(特别是需要额外授权或有专利问题的)可能在默认编译中未被包含;或者你可能需要确认是否支持特定的网络协议或滤镜。
因此,执行信息查询命令的主要作用和价值在于:
- 避免运行时错误: 提前确认 FFmpeg 支持你将要使用的编码器、格式、滤镜或协议,可以避免在脚本执行到一半时才发现功能缺失而导致失败。例如,你想编码为
libfdk_aac
,但查询ffmpeg -encoders
后发现它不在列表中,你就需要换用 FFmpeg 内置的aac
编码器。 - 确保兼容性与选择最佳方案: 查看支持列表可以帮助你选择最适合你需求的、且当前环境支持的最佳工具。比如,检查是否有硬件加速编码器(如
h264_nvenc
)可用,或者对比几种可选的音频编码器。 - 辅助调试: 特别是当你自行编译 FFmpeg 或遇到奇怪问题时,检查编译时链接的库和启用的功能(可以通过
-version
或查询相关组件)可以帮助诊断问题根源。 - 发现新功能: 浏览支持列表也是学习 FFmpeg 强大功能、寻找特定处理方案的途径。
常用查询命令详解:
查看编解码器 (-encoders
, -decoders
)
命令 ffmpeg -encoders
会列出所有当前 FFmpeg 版本编译支持的编码器。编码器用于将原始音视频数据压缩。输出会标明编码器名称(如 libx264
)、类型(V=视频, A=音频, S=字幕)和简短描述。类似地,ffmpeg -decoders
列出所有支持的解码器,用于解压缩。了解这些列表可以让你确定:
- 输出兼容性: 你能否使用
-c:v libx265
或-c:a libopus
来编码你的输出文件? - 输入兼容性: 当你拿到一个不常见的视频文件时,FFmpeg 是否内置了对应的解码器来读取它?
- 硬件加速: 列表中是否包含如
h264_nvenc
,hevc_qsv
等硬件加速编解码器?
查看协议 (-protocols
)
命令 ffmpeg -protocols
显示 FFmpeg 支持的输入和输出协议。这决定了 FFmpeg 能从哪些来源读取数据以及能将数据发送到哪些目的地。常见的协议包括 file
(本地文件), http
, https
, ftp
, tcp
, udp
, 以及流媒体常用的 rtmp
, rtsp
, hls
, pipe
(管道) 等。在你需要处理网络流(如拉取 RTSP 流进行处理,或将处理结果推送到 RTMP 服务器)或与其他进程通过管道交互时,确认协议支持是前提。
查看格式 (-formats
)
命令 ffmpeg -formats
列出 FFmpeg 支持的所有容器格式 (Muxers/Demuxers)。容器格式定义了音视频流如何打包存储。输出中 D
列表示支持解复用(Demuxing,读取这种格式的文件),E
列表示支持复用(Muxing,写入这种格式的文件)。常见的格式如 mp4
, mov
, mkv
, webm
, avi
, flv
, mpegts
, mp3
, aac
, wav
, ogg
, image2
(用于图像序列) 等。在你需要进行格式转换,或者使用 -f
参数强制指定格式时,需要确保目标格式是被支持的(有 E
标记)。
查看和学习滤镜 (-filters
, -h filter=<滤镜名>
)
命令 ffmpeg -filters
会打印出当前版本支持的所有滤镜的列表,这个列表通常非常长!它对于快速浏览有哪些可用的处理功能很有帮助。但更实用的是 ffmpeg -h filter=<滤镜名>
命令。例如,你想了解如何精确地缩放视频,可以运行 ffmpeg -h filter=scale
。这个命令会输出 scale
滤镜的详细文档,包括它接受的所有参数(如 width
, height
, flags
, interl
等)、每个参数的含义、可接受的值范围、默认值,甚至可能有使用示例。在你使用任何不熟悉的滤镜之前,通过 -h filter=
来查阅其用法是避免参数错误的关键步骤。
获取完整帮助 (-h full
)
命令 ffmpeg -h full
会输出 FFmpeg 所有可用的命令行选项的极其详尽的帮助信息。内容非常多,适合在需要查找非常规或底层参数时作为最终参考。
17.2.5 ffprobe
获取文件信息详解 (深度解读)
为何要探测文件信息?
ffprobe
是 FFmpeg 套件中的媒体文件侦探。在你对音视频文件进行任何修改或处理之前,使用 ffprobe
深入了解它的“底细”至关重要,其作用和价值体现在:
制定处理策略:
获取文件的精确属性(如分辨率、帧率、时长、编码格式、比特率、音频声道数、采样率、像素格式等)是决定后续操作的基础。例如:
- 只有当视频分辨率大于 1920x1080 时,才执行缩小操作。
- 只有当音频编码不是 AAC 时,才进行音频转码。
- 根据获取的视频时长来计算截取片段的起止时间或判断是否需要处理。
- 根据帧率来设置输出帧率或进行帧率转换。
- 检查像素格式以确保后续滤镜或编码器兼容。
- 检测是否有音频流来决定是否需要处理或复制音频。
- 读取旋转 (Rotation) 元数据,以便在必要时进行反向旋转校正。
动态参数计算: 在脚本中,你可以用
ffprobe
获取的值来动态计算 FFmpeg 命令的参数。例如,使用探测到的宽度iw
和高度ih
来计算缩放或裁剪的目标尺寸,或者使用探测到的时长duration
来设置滤镜效果的时间参数。错误预检查与调试: 可以用来检查输入文件是否有效、是否损坏、是否包含预期的流类型。如果一个文件处理失败,
ffprobe
的输出可以帮助判断问题是出在文件本身还是处理命令上。内容分析与质量评估: 查看文件的编码器、Profile/Level、比特率等信息,可以大致评估源文件的质量,并据此选择合适的处理参数。
推荐的 ffprobe
命令及其详解:
对于脚本化处理,获取 JSON 格式的输出是最方便的:
Bash
1 | ffprobe -v quiet -print_format json -show_format -show_streams your_video.mp4 |
-v quiet
: 设置日志级别为quiet
,这样ffprobe
在执行时不会打印版本信息、库信息等额外的日志,只输出纯净的 JSON 数据(或错误信息),便于程序解析。-print_format json
: 明确指定输出格式为 JSON。JSON 是一种结构化的数据格式,Python 的json
模块可以轻松地将其解析为字典和列表。-show_format
: 指示ffprobe
在输出中包含关于容器格式 (Format) 的信息。这部分信息描述了整个文件的属性。-show_streams
: 指示ffprobe
在输出中包含文件中每一个数据流 (Stream) 的详细信息(包括视频、音频、字幕等)。
深入理解 JSON 输出结构:
ffprobe
输出的 JSON 是一个 Python 字典,其中最重要的两个键是 "format"
和 "streams"
。
"format"
对象 (容器/文件级别信息)
这个字典包含了文件的整体信息:
filename
: 文件的完整路径。nb_streams
: 文件中包含的流的总数。format_name
: 容器格式的名称(通常是逗号分隔的列表,如 ‘mov,mp4,m4a,3gp,3g2,mj2’)。format_long_name
: 容器格式的更详细名称。start_time
: 文件播放的起始时间戳(通常是 “0.000000”)。duration
: 文件的总时长(单位:秒,字符串形式)。极其常用!size
: 文件总大小(单位:字节,字符串形式)。bit_rate
: 文件的平均总比特率(单位:bps,字符串形式)。probe_score
: FFmpeg 对探测到的格式的置信度(通常不用太关心)。tags
: 一个字典,包含了容器级别的元数据标签,例如major_brand
,minor_version
,compatible_brands
,title
,artist
,album
,encoder
(编码这个文件的软件信息),comment
等。
"streams"
列表 (流级别信息)
这是一个列表,列表中的每个元素都是一个字典,详细描述了文件中的一个流。你需要遍历这个列表,并通过 codec_type
来判断是视频流、音频流还是其他类型的流。
- 通用关键字段:
index
: 流的索引号(从 0 开始)。codec_type
: 流类型,值为 ‘video’, ‘audio’, ‘subtitle’, ‘data’ 等。用于区分不同流。codec_name
: 编解码器的短名称(如 ‘h264’, ‘aac’, ‘vp9’)。codec_long_name
: 编解码器的完整名称。profile
: 编码时使用的配置文件(如 H.264 的 ‘High’, ‘Main’)。time_base
: 时间戳的基本单位(分数形式,如 “1/16000”,表示时间戳的单位是 1/16000 秒)。start_time
: 此流的起始时间(秒)。duration
: 此流的持续时间(秒,可能与format
中的总时长略有不同)。bit_rate
: 此流的平均比特率(bps)。nb_frames
: 此流的总帧数(对某些编码可能是估计值)。disposition
: 一个字典,包含布尔标志,指示流的用途,如default
(是否为默认流),dub
(是否为配音),original
,comment
,forced
(强制字幕)等。tags
: 此流特有的元数据,如language
(‘eng’, ‘chi’),handler_name
,rotate
(视频旋转角度)等。
- 视频流 (
codec_type == 'video'
) 特有关键字段:width
,height
: 视频解码后的宽度和高度(像素)。coded_width
,coded_height
: 视频编码时的宽度和高度(可能因编码要求而与width
/height
不同)。pix_fmt
: 像素格式(如 ‘yuv420p’, ‘rgb24’)。level
: 编码级别(如 H.264 的 41 代表 Level 4.1)。color_range
,color_space
,color_transfer
,color_primaries
: 详细的色彩空间信息。sample_aspect_ratio
(SAR),display_aspect_ratio
(DAR): 像素宽高比和显示宽高比。r_frame_rate
: 容器中标称的基础帧率(分数,如 “25/1”)。avg_frame_rate
: 平均帧率(分数,如 “30000/1001” 表示 29.97fps)。常用!
- 音频流 (
codec_type == 'audio'
) 特有关键字段:sample_fmt
: 音频采样格式(如 ‘fltp’ - 浮点平面)。sample_rate
: 采样率(Hz,如 ‘44100’, ‘48000’)。常用!channels
: 声道数(如 1, 2, 6)。常用!channel_layout
: 声道布局描述(如 ‘mono’, ‘stereo’, ‘5.1(side)’)。常用!bits_per_sample
: 每个采样点的位数(对于某些格式可能为 0)。
Python 解析 ffprobe
JSON 示例 (增强版)
1 | import subprocess |
详细信息流如下:
1 | --- 文件 'input.mp4' 的详细信息 --- |
17.3 ffmpeg-python
核心 API
ffmpeg-python
的核心思想与其他 Python 库直接绑定 FFmpeg 的 C API 不同。它并不直接执行编解码或滤镜操作,而是提供了一套 Pythonic 的接口,让你像用 Python 代码描述流程一样来构建一个媒体处理的有向无环图 (DAG - Directed Acyclic Graph)。
在这个图中:
- 节点 (Node): 代表一个处理单元,比如一个输入文件、一个滤镜操作、或者一个输出文件。
- 边 (Edge / Stream): 代表在节点之间流动的媒体流 (Stream),可以是视频流、音频流等。
你通过调用 ffmpeg-python
的函数(如 ffmpeg.input
, ffmpeg.filter
, ffmpeg.output
)来创建节点,并通过链式调用或将流作为参数传递来连接这些节点,形成处理图。这个图仅仅是一个处理流程的描述。
只有当你调用最终输出节点的 .run()
或 .run_async()
方法时,ffmpeg-python
才会将这个图编译 (compile) 成一个等效的、可能非常复杂的 FFmpeg 命令行参数列表,然后调用你系统上安装的 ffmpeg
可执行程序(通过 Python 的 subprocess
模块)来实际执行这个命令。
这种方式的主要优点是代码可读性高、符合 Python 习惯、并且能优雅地处理复杂的滤镜链和多输入多输出场景,避免了手动拼接命令行字符串的痛苦和易错性。
17.3.1 API: ffmpeg.probe()
- 探测媒体文件信息
作用:
调用系统中的 ffprobe
命令行工具,分析指定的媒体文件,并将其详细信息解析为一个结构化的 Python 字典返回。这是在进行任何处理之前了解文件属性的关键步骤。
语法:
1 | ffmpeg.probe(filename, cmd='ffprobe', **kwargs) |
参数详解:
filename
(字符串, 必需): 要分析的媒体文件的路径或 URL。建议使用pathlib
处理路径,并传入str(path_obj)
。cmd
(字符串, 可选): 指定ffprobe
可执行文件的路径。如果ffprobe
已经在系统 PATH 环境变量中,则保持默认值'ffprobe'
即可。**kwargs
(可选关键字参数): 对应传递给ffprobe
命令行的额外选项(需要去掉选项前的-
)。例如:select_streams='v'
: 对应-select_streams v
,表示只探测视频流的信息。show_entries='stream=codec_name,duration:format=bit_rate'
: 对应-show_entries stream=codec_name,duration:format=bit_rate
,表示只在输出中包含指定的条目,减少输出量。count_frames=None
: 对应-count_frames
标志,用于计算流的总帧数(可能较慢)。
代码示例:
1 | import ffmpeg |
返回值:
- 成功时: 返回一个 Python 字典 (dict),包含了从
ffprobe
获取并解析的媒体信息。 - 失败时: 抛出
ffmpeg.Error
或其他异常。
知识点表格: ffmpeg.probe()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
ffmpeg.probe() | Function | 调用 ffprobe 分析媒体文件并返回信息字典。 | 是进行处理前获取属性的关键。 |
filename | str | (必需) 文件路径。 | |
cmd | str | (可选) ffprobe 可执行文件路径。 | 默认 'ffprobe' 。 |
**kwargs | dict | (可选) 传递给 ffprobe 的额外选项。 | 如 select_streams , show_entries 。 |
返回值 | dict | 媒体信息字典 (format , streams )。 | |
异常 | ffmpeg.Error | ffprobe 执行失败时抛出。 | 可通过 .stderr 获取原始错误信息。 |
17.3.2 输入节点 (ffmpeg.input
)
作用:
在 ffmpeg-python
构建的处理图中创建输入节点,代表一个媒体文件、设备或网络流来源。这是所有处理流程的起点。
语法:
1 | import ffmpeg |
参数详解:
filename
(字符串, 必需): 输入来源的标识符。可以是:- 本地文件路径:
'input.mp4'
,'images/logo.png'
,str(Path('video.mkv'))
- URL:
'http://server/stream.m3u8'
,'rtmp://server/live'
- 设备名称 (依赖 FFmpeg 编译和系统支持): 例如 Linux 上的
/dev/video0
(需要-f v4l2
) 或 Windows 上的'video=Integrated Camera'
(需要-f dshow
)。 - 图像序列模式:
'img%04d.png'
(匹配 img0001.png, img0002.png…) - Lavfi 滤镜源:
'color=c=black:s=1280x720:d=10'
(创建一个 10 秒的黑色视频源)
- 本地文件路径:
**kwargs
(可选关键字参数): 对应 FFmpeg 命令行中放在-i
之前的输入选项。键名通常与命令行选项相同(去掉-
)。常用输入选项 (
kwargs
):ss=<time>
: 输入定位。从指定时间点开始读取输入。time
可以是秒数或HH:MM:SS.ms
格式。比输出定位-ss
快,但不精确到帧。t=<duration>
: 从输入源最多读取指定duration
时长的数据。to=<time>
: 从输入源读取数据,直到达到指定的时间点time
。f=<format>
: 强制使用指定的输入格式/解复用器 (Demuxer)。例如,读取摄像头时可能需要f='v4l2'
(Linux) 或f='dshow'
(Windows);读取图像序列时用f='image2'
;读取 Lavfi 源时用f='lavfi'
。framerate=<rate>
: 强制指定输入的帧率。主要用于本身没有帧率信息的输入,如图形序列。s='<WxH>'
: 强制指定输入的分辨率。主要用于本身没有分辨率信息的原始视频流。pix_fmt=<format>
: 强制指定输入的像素格式。主要用于原始视频流。loop=1
: (用于image2
demuxer) 无限循环单个输入图像。通常和-t
配合生成持续时间的视频。stream_loop=<count>
: (用于视频/GIF等) 循环读取整个输入流指定的次数。-1
表示无限循环。
代码示例:
1 | import ffmpeg |
返回值:ffmpeg.input()
函数返回一个代表输入源的节点对象 (Node)。这个对象包含了关于输入流的信息,并且可以用流选择器来获取具体的 Stream
对象用于后续处理。
知识点表格: ffmpeg.input()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
ffmpeg.input() | Function | 在处理图中创建输入节点。 | 处理流程的起点。 |
filename | str | (必需) 输入源路径、URL 或标识符。 | |
**kwargs | dict | (可选) 对应 FFmpeg 的输入选项。 | 如 ss , t , f , framerate 等。 |
返回值 | Node | 代表输入源的节点对象。 | 可用于选择流 node['v'] 等。 |
17.3.3 流 (Stream) 的概念与选择
作用:
一个媒体文件(如 MKV, MP4)通常包含多个数据流 (Stream),例如一个视频流、一个或多个音频流(不同语言)、一个或多个字幕流等。ffmpeg.input()
函数返回的是一个代表整个输入源的节点 (Node) 对象。为了对特定的数据流(比如只对视频进行缩放,或只选择英语音轨)进行操作,你需要从输入节点中精确地选择出你想要的那个流。
选择流会得到一个 Stream
对象,这个 Stream
对象是后续应用滤镜 (.filter()
) 的主体。
语法:
主要使用类似字典的方括号访问方式:
1 | stream = input_node[stream_specifier] |
或者使用便捷属性(只适用于第一个默认流):
1 | video_stream = input_node.video # 等同于 input_node['v'] 或 input_node['v:0'] |
参数详解 (stream_specifier
):
stream_specifier
是一个字符串,其格式与 FFmpeg 命令行中的流标识符非常相似,用于指定要选择哪个流。
ffmpeg-python specifier | FFmpeg CLI 等效 | 含义 |
---|---|---|
'v' 或 'v:0' | v 或 v:0 | 第一个视频流 |
'a' 或 'a:0' | a 或 a:0 | 第一个音频流 |
's' 或 's:0' | s 或 s:0 | 第一个字幕流 |
N (整数) | N | 第 N+1 个流(绝对索引,从 0 开始,不区分类型) |
'v:N' | v:N | 第 N+1 个视频流 (索引从 0 开始) |
'a:N' | a:N | 第 N+1 个音频流 (索引从 0 开始) |
's:N' | s:N | 第 N+1 个字幕流 (索引从 0 开始) |
其他 | 其他标识符 | ffmpeg-python 对更复杂的标识符 (如 i:ID , p:ID , m:key:value ) 的直接支持可能有限,通常通过先 probe 获取信息再按 index 选择更可靠。 |
代码示例: 选择不同的流
1 | import ffmpeg |
返回值:
成功选择流会返回一个 ffmpeg.Stream 对象。这个对象代表了处理图中的一个特定数据流,可以对其调用 .filter() 方法或将其传递给 ffmpeg.output()。如果指定的流不存在(例如,文件只有一个音频流,但你尝试选择 a:1),通常会在后续构建图或执行时(取决于库的实现细节)引发错误。
知识点: 流选择
语法/属性 | 作用 | 返回值 | 备注 |
---|---|---|---|
node[specifier] | 主要方式: 使用流标识符选择流。 | ffmpeg.Stream | specifier 如 'v' , 'a:1' , 0 等。 |
node.video | 便捷属性,选择第一个视频流。 | ffmpeg.Stream | 等同于 node['v'] 或 node['v:0'] 。 |
node.audio | 便捷属性,选择第一个音频流。 | ffmpeg.Stream | 等同于 node['a'] 或 node['a:0'] 。 |
node.subtitle | 便捷属性,选择第一个字幕流。 | ffmpeg.Stream | 等同于 node['s'] 或 node['s:0'] 。 |
17.3.4 应用滤镜 (Stream.filter
)
作用:
在 ffmpeg-python
中,获取到一个代表特定流的 Stream
对象后(例如通过 input_node['v']
或 input_node['a']
),你可以对这个流应用一个或多个 FFmpeg 滤镜来进行处理。这是修改音视频内容的核心步骤,比如调整大小、裁剪、调色、调整音量等。
每次调用 .filter()
都会在处理图中添加一个滤镜节点,并返回一个代表滤镜处理后输出的新 Stream
对象。
语法:
1 | filtered_stream = stream_object.filter(filter_name, *args, **kwargs) |
参数详解:
filter_name
(字符串, 必需): 你想要应用的 FFmpeg 滤镜的名称。例如'scale'
,'crop'
,'volume'
,'hflip'
,'drawtext'
等。你可以通过ffmpeg -filters
查看所有可用滤镜。*args
(可选位置参数): 传递给滤镜的位置参数。某些简单的滤镜可以直接按顺序接收参数值。例如,scale
滤镜可以接受宽度和高度作为前两个位置参数:filter('scale', 640, 360)
。**kwargs
(可选关键字参数): (推荐使用) 使用键=值
的形式传递滤镜的选项。键名通常与 FFmpeg 滤镜文档中定义的选项名一致。使用关键字参数通常更清晰易读,不易出错。例如:filter('scale', width=640, height=-2)
。- 注意: 如果 FFmpeg 滤镜选项名包含特殊字符或与 Python 关键字冲突(虽然不常见),你可能需要用字典解包的方式传递:
filter('filter_name', **{'option-with-hyphen': 'value'})
。
- 注意: 如果 FFmpeg 滤镜选项名包含特殊字符或与 Python 关键字冲突(虽然不常见),你可能需要用字典解包的方式传递:
链式调用 (Chaining):
由于 .filter()
返回一个新的 Stream
对象,你可以方便地进行链式调用,将多个滤镜按顺序应用到同一个流上,形成一个简单的滤镜链 (filterchain)(对应命令行中用逗号分隔多个滤镜)。
代码示例 1: 缩放视频流
1 | import ffmpeg |
代码示例 2: 链式调用 - 调整音量并改变速度
1 | import ffmpeg |
返回值:.filter()
方法返回一个新的 ffmpeg.Stream
对象,代表应用了该滤镜之后的输出流。你可以继续对这个新的 Stream
对象调用 .filter()
或将它传递给 ffmpeg.output()
。
知识点表格: Stream.filter()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
.filter() | Method on Stream obj | 对当前流应用一个 FFmpeg 滤镜。 | 返回一个新的 Stream 对象,允许链式调用。 |
filter_name | str | (必需) FFmpeg 滤镜名称。 | 如 'scale' , 'volume' 。 |
*args | (可选) 滤镜的位置参数。 | 顺序必须与 FFmpeg 文档一致。 | |
**kwargs | dict | (可选/推荐) 滤镜的关键字参数。 | 键名通常同 FFmpeg 选项名。 |
返回值 | ffmpeg.Stream | 代表应用滤镜后的输出流。 |
17.3.5 输出节点 (ffmpeg.output
) 与输出选项详解 (表格优化版)
作用:
ffmpeg.output()
函数用于在处理图中定义一个输出节点。它指定了处理流程的终点(即生成的输出文件),并且包含了将输入流编码、封装到这个输出文件时所需的所有配置,如使用的编码器、比特率、格式、时长限制等。
语法:
1 | output_node = ffmpeg.output(*streams_and_filename, **kwargs) |
参数详解:
*streams_and_filename
(位置参数):*streams
(必需): 一个或多个ffmpeg.Stream
对象,代表要包含在输出文件中的数据流。filename
(字符串, 必需): 最后一个位置参数,指定输出文件的路径和名称。扩展名(如.mp4
)有助于 FFmpeg 推断默认格式。
**kwargs
(可选关键字参数): (核心) 这些参数是控制输出文件属性的关键,它们直接映射到 FFmpeg 命令中放在输出文件名前的输出选项。下面表格列出了最常用的kwargs
:常用
ffmpeg.output()
关键字参数 (kwargs
)ffmpeg-python
kwargFFmpeg CLI Option 描述 示例值 ( ''
内为字符串)f
-f <format>
强制指定输出文件的容器格式 (Muxer)。 'mp4'
,'flv'
,'hls'
,'mp3'
vcodec
或c:v
-c:v <codec>
指定视频编码器。 'libx264'
,'copy'
,'h264_nvenc'
acodec
或c:a
-c:a <codec>
指定音频编码器。 'aac'
,'libopus'
,'copy'
scodec
或c:s
-c:s <codec>
指定字幕编码器。 'srt'
,'mov_text'
,'copy'
video_bitrate
或b:v
-b:v <rate>
设置视频平均比特率。与 crf
通常不同时使用。'2M'
,'1500k'
audio_bitrate
或b:a
-b:a <rate>
设置音频平均比特率。 '128k'
,'192k'
crf
-crf <value>
恒定速率因子 (用于 x264/x265 等),控制视频质量。值越低质量越好。推荐使用。 23
,28
preset
-preset <value>
编码器预设,平衡速度与压缩率。 'fast'
,'medium'
,'slow'
pix_fmt
-pix_fmt <format>
指定输出视频的像素格式,影响颜色和兼容性。 'yuv420p'
(常用)vf
-vf <filter_string>
应用简单的视频滤镜链 (字符串形式)。注意:推荐使用 .filter()
方法构建。'scale=640:-1,hflip'
af
-af <filter_string>
应用简单的音频滤镜链 (字符串形式)。注意:推荐使用 .filter()
方法构建。'volume=0.8,atempo=1.1'
t
-t <duration>
限制输出文件的持续时长(秒)。 60
,'00:01:30.5'
to
-to <time>
指定输出文件的结束时间点(相对于输入开始时间)。 120
,'00:02:00.0'
movflags
-movflags <flags>
(主要用于 MP4) 设置 MP4 的标志。 '+faststart'
强烈推荐用于网络播放。'+faststart'
shortest
-shortest
(布尔值 True
) 当有多个输入流时长不同时,使输出时长等于最短的输入流。True
map
-map <specifier>
(字符串列表) 手动指定流映射。注意:通常直接传递 Stream 对象给 output()
更 Pythonic,一般无需此参数。['0:v:0', '1:a']
**{'option': value}
-option value
传递 ffmpeg-python
没有直接关键字参数对应的原生 FFmpeg 选项。**{'q:v': 2}
代码示例 :
1 | import ffmpeg |
返回值:ffmpeg.output()
函数返回一个代表输出操作的 OutputNode
对象。你需要调用这个对象的 .run()
或 .run_async()
方法来最终执行整个处理流程。
知识点表格: ffmpeg.output()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
ffmpeg.output() | Function | 创建输出节点,定义输出文件和编码/格式选项。 | 处理流程的终点。 |
*streams | ffmpeg.Stream | (必需) 一个或多个要写入的流对象。 | 来自 input 或 filter 的结果。 |
filename | str | (必需) 输出文件的路径和名称。 | 扩展名用于推断格式。 |
**kwargs | dict | (可选) 对应 FFmpeg 的输出选项。 | 控制编码、质量、格式、时长等。 |
返回值 | OutputNode | 代表输出操作的节点对象。 | 可以调用 .run() , .compile() 等。 |
17.3.6 全局选项与调试工具 (.compile
, .view
, global_args
)
当你构建的 FFmpeg 处理流程变得复杂,或者执行结果不符合预期时,ffmpeg-python
提供了一些工具来帮助你理解和调试发生了什么。
API: Node.compile()
- 查看生成的命令
作用:
这个方法不会执行任何 FFmpeg 命令。它的唯一作用是将你通过 ffmpeg-python
构建的处理图(从输入到输出)编译成最终将要传递给 ffmpeg
可执行程序的命令行参数列表。这对于以下情况极其有用:
- 调试: 当
.run()
报错时,你可以先.compile()
看看生成的具体命令是什么,然后将这个命令手动复制到你的终端里执行,这样可以更直接地看到 FFmpeg 的原始输出和错误信息,更容易定位问题。 - 学习: 通过观察
ffmpeg-python
代码如何转换为命令行参数,可以加深对 FFmpeg 命令和ffmpeg-python
库本身的理解。 - 集成: 在某些特殊情况下,你可能只想用
ffmpeg-python
来构建命令参数列表,然后用自己定制的subprocess
调用或其他方式来执行它。
语法:
1 | arguments_list = output_node.compile(cmd='ffmpeg') |
参数详解:
cmd
(字符串, 可选): 指定ffmpeg
可执行文件的路径。这应该与你传递给.run()
的cmd
参数保持一致。默认是'ffmpeg'
。
代码示例:
1 | import ffmpeg |
运行上述代码(假设输入文件存在),你将在控制台看到一个 Python 列表,其中包含了 ffmpeg-python
为你生成的所有命令行参数,例如 ['-i', 'input.mp4', '-i', 'logo.png', '-filter_complex', '[1:v]...[outv]', '-map', '[outv]', ...]
。你可以把这个列表(去掉 Python 的方括号和引号,加上开头的 ffmpeg
)组合成一个完整的命令行字符串,在终端里运行来验证。
返回值:compile()
方法返回一个字符串列表 (list[str]
),代表将要传递给 ffmpeg
可执行程序的参数。
知识点表格: Node.compile()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
.compile() | Method on Node | 将处理图编译为 FFmpeg 命令行参数列表,不执行。 | 主要用于调试和学习。 |
cmd | str | (可选) ffmpeg 可执行文件路径(通常不需要指定)。 | |
返回值 | list[str] | 代表命令行参数的字符串列表。 |
API: Node.view()
- 可视化处理图
作用:
对于非常复杂的滤镜图,文本描述可能不够直观。.view()
方法可以利用 Graphviz 工具自动生成处理图的可视化流程图(通常是 PNG, PDF 或 SVG 格式),并尝试用系统默认程序打开它。这有助于你理解数据流是如何在不同的滤镜节点之间传递和连接的。
重要前提:
要使用 .view()
,你必须:
- 安装
graphviz
Python 库:pip install graphviz
- 安装 Graphviz 软件本身: 这是一个独立的开源图形可视化软件。你需要根据你的操作系统进行安装,并确保其
dot
命令可以在系统的 PATH 环境变量中被找到。- Windows: 从 Graphviz 官网 (https://graphviz.org/download/) 下载 msi 安装包并安装,务必在安装过程中勾选 “Add Graphviz to the system PATH for all users” 或类似选项。
- macOS:
brew install graphviz
- Linux (Debian/Ubuntu):
sudo apt install graphviz
- Linux (Fedora/CentOS):
sudo yum install graphviz
或sudo dnf install graphviz
语法:
1 | output_node.view(filename='graph', format='png') |
参数详解:
filename
(字符串, 可选): 生成的图形文件的基本名称(不含扩展名),默认为'graph'
。format
(字符串, 可选): 输出图形的文件格式,默认为'png'
。可以是 Graphvizdot
命令支持的任何格式,如'pdf'
,'svg'
。
代码示例:
1 | import ffmpeg |
返回值:.view()
方法通常返回 None
,它的主要作用是产生副作用(生成文件和尝试打开查看器)。
知识点表格: Node.view()
API / 参数 | 类型 | 作用 | 备注 |
---|---|---|---|
.view() | Method on Node | 使用 Graphviz 生成处理流程图的可视化文件。 | 依赖 Graphviz 软件和 Python 库。 |
filename | str | (可选) 输出图形文件的基本名称。 | 默认 'graph' 。 |
format | str | (可选) 输出图形的文件格式。 | 默认 'png' 。支持 ‘pdf’, ‘svg’ 等。 |
返回值 | None | - | 主要产生副作用(生成文件/打开查看器)。 |
API: 全局选项 (global_args
in .run()
/ .run_async()
)
作用:
有时候你需要传递 FFmpeg 的全局选项(即放在 ffmpeg
命令之后、第一个 -i
之前的选项),例如 -progress
来输出进度信息,或者 -report
生成详细日志文件,或者 -v
覆盖默认日志级别。ffmpeg-python
允许你在执行 .run()
或 .run_async()
时通过 global_args
参数来传递这些选项。
语法:
1 | output_node.run(..., global_args=['-option1', 'value1', '-option2', ...]) |
参数详解:
global_args
(列表list[str]
, 可选): 一个包含全局选项及其值的字符串列表。每个选项和它的值(如果需要值的话)应该作为列表中的独立元素。
代码示例:
1 | import ffmpeg |
知识点表格: global_args
(用于 .run()
/ .run_async()
)
参数名 | 类型 | 作用 | 备注 |
---|---|---|---|
global_args | list[str] | (可选) 传递给 FFmpeg 的全局选项列表。 | 每个选项及其值是列表中的独立字符串元素。 |