这个系列文章我们来介绍一位海外工程师如何探索 FFmpeg Basics 音视频技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,这是第 1 篇:FFmpeg 基本介绍。
—— 来自公众号“关键帧Keyframe”的分享
1、FFmpeg 介绍
FFmpeg 是根据 GNU 通用公共许可证获得许可的多媒体处理自由软件项目的名称。该项目最受欢迎的部分是用于视频和音频编码 / 解码的 ffmpeg 命令行工具,其主要特点是速度快、输出质量高和文件大小比较小。FFmpeg 中的 “FF” 表示媒体播放器上的 “快进” 控制按钮,“mpeg” 是 Moving Pictures Experts Group 的缩写。FFmpeg 标志包含 Z 字形图案,这是图片中以 8×8 块图示的熵编码方案的特征。

知道 FFmpeg 图标的意思了吧。
1.1、FFmpeg 命令行工具
ffmpeg | 快速音频和视频编码器 / 解码器 |
---|---|
ffplay | 媒体播放器 |
ffprobe | 显示媒体文件的特点 |
ffserver | 使用 HTTP 和 RTSP 协议进行多媒体流的广播服务器 |
1.2、FFmpeg 软件库
libavcodec | 各种多媒体编解码器的软件库 |
---|---|
libavdevice | 软件库的设备 |
libavfilter | 软件库包含过滤器 |
libavformat | 媒体格式的软件库 |
libavutil | 包含各种实用程序的软件库 |
libpostproc | 用于后期处理的软件库 |
libswresample | 用于音频重采样的软件库 |
libswscale | 用于媒体扩展的软件库 |
所有组件的编程语言是 C 语言,源代码可以在 Linux/Unix、Windows、Mac OS X 等系统上编译。
本书是使用官方二进制版本在 Microsoft Windows 上创建的,但几乎所有的指令和示例都应该在其他操作系统上无任何更改的情况下运行。有关启用的选项的详细信息,请参阅词汇表中的 FFmpeg 配置条目。
2、FFmpeg 开发者
该项目由 Fabrice Bellard 于 2000 年开始,Fabrice Bellard 是 QEMU 和 Tiny C Compiler 的创建者,也是一位出色的程序员。现在该项目由 FFmpeg 团队维护,开发人员来自许多国家,主要的开发人员可以参与合同工作:
姓名 | 地址 | 专长 |
---|---|---|
Baptiste Coudurier | 美国. 洛杉矶 | 他在广播 codecs (ProRes, DNxHD, IMX/D-10, AVC-Intra),格式 (MXF, GXF, MOV) 和用法 (Avid, FCP, Interlacing, Time Code, Metadata) 中有专门的专业知识 |
Benjamin Larsson | 斯德哥尔摩, 瑞典 | 他的专业领域是音频编解码器 |
Diego Biurrun | 德国亚琛 | 他在许可证法规遵循工程和构建系统方面具有特殊的专长 |
Jason Garrett-Glaser | 洛杉矶. 美国 | 他是 x264 的主要开发人员,在 H.264 和其他现代有损视频格式以及 x86 SIMD 装配优化方面具有特殊的专业知识 |
Luca Barbato | 意大利都灵 | 他在流媒体协议方面有特殊专长 |
Michael Niedermayer | 奥地利的维也纳 | 他是视频编码和 x86 汇编领域的专家 |
Stefano Sabatini | 卡利亚里. 意大利 | 他在 libavfilter, ff 工具的使用和可用性问题上有特别的专长 |
3、参与 FFmpeg 开发
任何人都可以通过在网页上加入特定的邮件列表来参与 FFmpeg 的开发和更新:http://www.ffmpeg.org/contact.html
表中列出了可用的邮件列表:
FFmpeg 邮件列表
ffmpeg-user | 对于常见的用户问题,如编译问题、命令行问题和类似的问题 |
---|---|
ffserver-user | 对于 ffserver 用户的问题,比如配置和流媒体问题 |
libav-user | 对于应用程序开发人员有关使用 FFmpeg 库开发的问题 |
ffmpeg-devel | 对于 FFmpeg 本身的开发,不是为了开发使用 FFmpeg 库的软件,也不是为了 bug 报告 |
ffmpeg-cvslog | 对于 FFmpeg 源 / 主要 git 存储库的所有更改 |
ffmpeg-trac | 对于 FFmpeg Trac 的所有修改 |
4、FFmpeg 下载
主要下载来源位于如下网页:http://ffmpeg.org/download.html
Windows 的用户可以从如下网页下载二进制文件(推荐使用静态构建):http://ffmpeg.zeranoe.com/builds
许多 Linux 发行版已经安装了 FFmpeg 工具,否则它们可以被编译,这在 OS X 上也是可能的,或者 OS X 二进制文件可以从 web 页面下载:http://www.evermeet.cx/ffmpeg 或 http://ffmpegmac.net
5、命令行语法
ffmpeg 命令行工具的语法相对简单,重要的是在正确的位置键入所需的参数,而不是在各种输入和输出之间混合选项。ffmpeg 命令的一般结构如下,需要注意的是全局选项影响所有输入和输出:
ffmpeg [global options] [input file options] -i input_file [output file options] output_file

FFmpeg 语法,大家能看懂不?看不懂的话看看 Example,哪一部分是全局的设置选项,哪一部分是第一个视频的设置选项,所有的结构都是这种模式,看多了就可以了。
6、Windows 命令提示符及其替代方法
Windows 上的 ffmpeg 命令行工具是通过命令提示符来管理的,可以通过 Windows -> 所有程序 -> 附件 -> 命令提示。它也可以从一个快捷方式 Win+R 开始,然后键入 cmd,然后输入。

Windows 命令提示符在关闭时不会保存所使用的命令的历史,因为有一些具有额外特性的免费应用程序,如文件管理、编辑、宏、FTP 客户端等,建议选择高级的 FFmpeg 工具程序。下一个表描述了几种免费的替代方案。
Windows 命令提示符选择
名称 | 下载 | 描述 |
---|---|---|
FAR Manager | farmanager.com | – 文件管理器与 shell,编辑器,ftp 客户端 – 命令行完成,快捷键,宏,插件 – 两个窗口,可定制的界面 |
PyCmd | sourceforge.net/projects/pycmd | – 选项卡完成,持续的历史…… |
Console | sourceforge.net/projects/console | – 多个标签,可配置 |
Gregs DOS Shell | gammadyne.com/cmdline.htm#gs | – 改进编辑,命令历史,支持 Aero Glass 等 |
TCC/LE | jpsoft.com/all- downloads/downloads.html | – 包括 111 个内部命令,103 个内部变量,140 个变量函数 |
接下来的行描述了最好的替代 FAR 管理器,在 Linux 上它可以用一个类似的应用程序 Midnight Commander 替代,如果安装了它,它将从控制台的 mc 命令启动。
FAR Manager 是一个受欢迎的文件管理器、编辑器和 FTP 客户端,它支持宏、插件和其他高级特性。用户界面是高度可定制的,并被翻译成多种语言。下一幅图展示了它的命令历史窗口,它在输入新命令时显示,因此用户可以轻松地选择之前使用的命令并最终编辑它。

对于其高级文件编辑器,在创建 ffmpeg 批处理时,FAR Manager 会很有用,这在 批处理文件 章节中有介绍。 还需要文件编辑器来将媒体文件包含在网页中 – “网络视频” 章节的主题。 界面的自定义开始于 F9 键并支持选择选项选项卡。
7、路径设置
将下载的 FFmpeg 命令行实用程序(ffmpeg.exe,ffplay.exe,ffprobe.exe)复制到环境变量 Path 部分中包含的目录是可以实现的,因此可以从任何目录调用它们而无需编写他们完整的路径。
或者,您可以将 FFmpeg 程序复制到其他目录,例如 C:\ media,然后通过控制面板 – >系统和安全 – >系统 – >高级系统设置将此文件夹添加到系统路径。 请点击环境变量按钮,向下滚动系统变量的滚动条,点击路径,然后点击编辑按钮。 在弹出的窗口中单击编辑系统变量变量值字段,将光标移动到行尾,添加文本
点击 OK 按钮。分号分隔特定的目录,别复制。

对于命令提示符的当前会话,可以使用命令设置路径:
set path=%path%;C:\path_to_ffmpeg.exe
例如,如果文件 ffmpeg.exe 被复制到目录 C:\media,命令是:
8、重命名为缩写形式(懒人专区)
命令名称 ffmpeg 有 6 个字符,如果每次用的话都输入 “ffmpeg” 这六个字符就太麻烦了,想个简单的办法,建议将文件 ffmpeg.exe 重命名为 f.exe(ffplay.exe 至 fp.exe 等)或类似的简写形式以节省时间并防止被误认。 在命令提示符中,你可以使用以下命令:
为了清晰起见,本书总是使用完整的命令形式 ffmpeg。
9、显示输出预览
在各种视频测试中,我们可以通过直接在屏幕上显示命令输出来节省大量时间,而不是将其保存到文件中,也不是在媒体播放器中预览。
10、FFplay 媒体播放器预览
使用简化的命令,而不是使用 ffmpeg 工具生成一个新文件。
ffmpeg -i input_file ... test_options ... output_file
我们可以使用将显示与 ffmpeg 完全相同的 ffplay,使用该命令保存到文件中
ffplay -i input_file ... test_options
11、使用 SDL 输出设备预览。
此预览由表中描述的 SDL(简单的 DirectMedia 层)输出设备生成:
输出设备:SDL
描述 | 在 SDL 窗口中显示视频流,需要安装 libsdl 库 |
---|---|
语法 | [-icon_title i_title] [-window_size w_size] [-window_title w_title] -f sdl output |
描述设备的选择
icon_title | 名称为 iconified SDL 窗口,默认值为 window_title 值 |
---|---|
window_size | SDL 窗口大小,widthxheight 或缩写,默认是输入视频的大小 |
window_title | 窗口标题,默认为输出设备指定的文件名 |
请注意,SDL 设备只能显示具有 yuv420p 像素格式的输出,并且使用其他输入类型的选项 -pix_fmt 具有一个值 yuv420p 必须被预先处理,否则会显示一个错误,例如:
ffmpeg -f lavfi -i rgbtestsrc -pix_fmt yuv420p -f sdl Example

12、可以在 FFmpeg 中使用的 SI 前缀
当指定数值各种 ffmpeg 选项如比特率或最大文件大小可以使用常见的 SI 后缀:K:千(10^3),M 为百万(10^6),G 十亿(10^9)等。下一个示例指定一个新的比特率 1.5 mbps 的输出文件,所有命令给相同的结果:
ffmpeg -i input.avi -b:v 1500000 output.mp4
ffmpeg -i input.avi -b:v 1500K output.mp4
ffmpeg -i input.avi -b:v 1.5M output.mp4
ffmpeg -i input.avi -b:v 0.0015G output.mp4
请注意,在 FFmpeg 文档中,SI 前缀被称为后缀,因为它们必须在数值之后立即输入。
后缀 B(字节)可以在 ffmpeg 选项中使用数值,并将数值乘以 8。它可以与其他前缀相结合,以表示千字节(KB)、兆字节(MB)等。例如,为输出文件设置 10 兆字节的最大文件大小,可以使用下一个命令:
ffmpeg -i input.mpg -fs 10MB output.mp4

13、FFmpeg 的代码转换
ffmpeg 程序读入内存中指定的任意数量的输入的内容,根据输入的参数或程序的默认值对其进行处理,并将结果写入任意数量的输出。输入和输出可以是计算机文件、管道、网络流、抓取设备等。
在代码转换过程中,ffmpeg 在 libavformat 库中调用 demuxers 来读取输入,并从数据包中获取编码数据。如果有更多的输入,ffmpeg 可以通过跟踪任何活动输入流的最低时间戳来保持它们的同步。然后解码器从编码的数据包中生成未压缩的帧,在可选的过滤后,帧被发送到编码器。编码器产生新的编码包,它被发送到 muxer 并写入到输出。
FFmpeg 工具的重要部分是过滤器,它可以被组织成过滤链和 filtergraphs。Filtergraphs 可以是简单的或复杂的。在解码源和编码输出之间实现滤波处理。转码过程在下一个图中说明。

14、Filters, filterchains,filtergraphs
在多媒体处理中,术语过滤器是指在编码到输出之前修改输入的软件工具。过滤器分为音频和视频过滤器(请参阅词汇表中的过滤器)。FFmpeg 内置了许多多媒体过滤器,可以通过多种方式组合它们。具有复杂语法的命令根据指定的参数从一个过滤器到另一个过滤器。这简化了媒体处理,因为有有损压缩的媒体流的多译码和编码会降低整体质量。FFmpeg 的过滤 API(应用程序编程接口)是 libavfilter 软件库,它允许过滤器有多个输入和输出。过滤器包括在输入和输出之间使用 -vf 选项的视频过滤器和 -af 选项音频过滤器。例如,下一个命令生成一个测试模式顺时针旋转 90° 使用转置过滤器:
ffplay -f lavfi -i testsrc -vf transpose=1
下一个示例使用 atempo 音频过滤器将输入音频的速度降低到 80%:
ffmpeg -i input.mp3 -af atempo=0.8 output.mp3

过滤器通常用于 filterchains(逗号分隔的过滤器序列)和 filtergraphs(分号分隔的 filterchains 序列)。如果使用了任何空格,那么 filterchain 必须用引号括起来。在 filtergraphs 中,可以使用表示所选 filterchain 输出的链接标签,并可以在以下的 filtergraphs 中使用。例如,我们希望将输入视频与 hqdn3d 过滤器输出的输出进行比较。如果没有 filtergraphs,我们必须至少使用两个命令:
ffmpeg -i input.mpg -vf hqdn3d,pad=2*iw output.mp4
ffmpeg -i output.mp4 -i input.mpg -filter_complex overlay=w compare.mp4
使用带有链接标签的 filtergraph,就只有一个命令:
ffplay -i i.mpg -vf split[a][b];[a]pad=2*iw[A];[b]hqdn3d[B];[A][B]overlay=w
分割过滤器将输入分为 2 个输出标签 [a] 和 [b],然后将 [a] 链接用作第二个 filterchain 的输入,它为标记 [a] 的比较创建了一个 pad。[b] 链接被用作第三个 filterchain 的输入,它创建一个标记为 [b] 的输出。最后一个 filterchain 使用 [A] 和 [B] 标签作为覆盖过滤器的输入,从而产生最终的比较。另一个例子是在下一个图中。

15、选择的媒体流
一些媒体容器如 AVI、Matroska、MP4 等可以包含多种类型的流,FFmpeg 可以识别 5 种流类型:音频(a)、附件(t)、数据(d)、字幕(s)和视频(v)。
使用 -map 选项选择流,然后使用流说明符和语法:
file_number:stream_type[:stream_number]
File_number 和 stream_number 也表示为 file_index 和 stream_index,从 0 开始计数,这意味着第一个是 0,第二个是 1,等等。
- -map 0 选择所有类型的所有流。
- -map i:v 从文件中选择所有的视频流,用 i (index),-map i:a 选择所有的音频流,-map i:s 选择所有字幕流,等等。
- 特殊选项 -vn, -sn 分别排除所有音频、视频或字幕流。
如果输入文件包含更多相同类型的流,而 -map 选项不被使用,那么选择的是每种类型的 1 个流。例如,如果文件包含 2 个视频流,选择的是具有较高分辨率的,对于音频选择的流有更多的通道,等等,细节如下图所示:

除了特定的 -map 选项,流指定符还与许多其他选项一起使用:
流的形式说明符
说明符形式 | 描述 |
---|---|
stream_index | 选择该索引的流(编号) |
stream_type[:stream_index] | stream_type 为字母 a(音频)、d(数据)、s(字幕)、t(附件)或 v(视频);如果添加了 stream_index,它将选择该类型的流并使用给定的索引,否则它将选择该类型的所有流 |
p:program_id[:stream_index] | 如果添加了 stream_index,那么使用给定的 program_id 在程序中选择带有 stream_index 的流,否则将选择该程序中的所有流 |
stream_id | 按格式指定的 ID 选择流 |
例如,为了设置音频和视频的使用 -b 选项的比特率,我们可以使用以下命令:
ffmpeg -i input.mpg -b:a 128k -b:v 1500k output.mp4
16、Lavfi 虚拟设备
在前面的部分中,我们使用了一个带有 lavfi 值的 -f 选项,其中 lavfi 是在表中描述的 libavfilter 虚拟输入设备的名称:
输入设备:lavfi | |
---|---|
描述 | 从 filtergraph 的打开的输出 pad 中处理数据,对于每个输出垫创建一个对应的流,映射到编码。filtergraph 由一个 -graph 选项指定,目前只支持视频输出垫 |
语法 | -f lavfi [-graph [-graph_file]] |
lavfi 选项的描述 | |
-graph | 作为输入的 filtergraph,每个视频的开放输出必须用一个 “outN” 形式的唯一字符串标记,其中 N 是一个数字,从 0 开始,对应于设备生成的映射的输入流。第一个未标记的输出将自动分配给 “out0” 标签,但是其他所有的输出都需要显式指定。如果没有指定,则默认为输入设备指定的文件名 |
-graph_file | filtergraph 的文件名被读取并发送到其他过滤器,filtergraph 的语法与选项 -graph 指定的语法相同 |
Lavfi 通常用于显示测试模式,例如带有命令的 SMPTE 条:
ffplay -f lavfi -i smptebars
其他经常使用的源是可以用命令显示的颜色源:
ffplay -f lavfi -i color=c=blue
17、颜色名称
一些视频过滤器和源有一个颜色参数,需要指定需要的颜色,并且有 4 种颜色规范的方法(默认值为黑色):
- 颜色被指定为 W3C(万维网联盟)标准名称,以其十六进制值按字母顺序排列的标准名称的列表如下图所示。请注意,这里有几个同义词:aqua = cyan, fuchsia = magenta 和 gray = grey。
- 颜色被指定为十六进制数的形式 0xrrggbb@AA,RR 红色通道,GG 是绿色通道和 BB 是蓝色通道,例如 0x0000ff 是蓝色的,0xffff00 是黄色的,等等。(@AA)是一个可选的 alpha 通道,指定有多少不透明的颜色,颜色在通道与一个 @ 符号字符。Alpha 通道值要么是从 0x00 到 0xff 的十六进制数字,要么是介于 0.0 和 1.0 之间的十进制数,其中 0.0(0x00)是完全透明的,1.0(0xff)是完全不透明的。例如,半透明度的绿色是 0x00ff00@0.5。
- 和之前的方法一样,但表示十六进制数字系统使用 # 符号而不是 0x 前缀,一样在 HTML 代码中,例如 #ff0000 是红色的,#ffffff 是白色的,等等。请注意,# 前缀不能使用 alpha 通道,这意味着 #0000ff@0x34 是好的,但没有 #0000ff@#34。
- 颜色是用一个特殊的值随机指定的,结果是由计算机产生的随机颜色。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。