写在前面
如果您对音视频技术感兴趣,可以订阅我的专题:音视频专辑
也可以关注我的简书账户: 张芳涛,我后期会发布更多的音视频以及图像处理方面的文章。
正文
为了最优地使用各种FFmpeg组件,需要正确理解FFmpeg的基本属性和特性。如果你基础差了点,看了不知道说的啥,您可以继续下一章,并在遇到需要了解的内容的时候再回来看。
FFmpeg介绍
FFmpeg是根据GNU通用公共许可证获得许可的多媒体处理自由软件项目的名称。 该项目最受欢迎的部分是用于视频和音频编码/解码的ffmpeg命令行工具,其主要特点是速度快,输出质量高和文件大小比较小。 FFmpeg中的“FF”表示 媒体播放器上的表示“快进”的控制按钮,“mpeg”是Moving Pictures Experts Group的缩写。 FFmpeg标志包含Z形图案,这是图片中以8x8块图示的熵编码方案的特征。
FFmpeg命令行工具
ffmpeg | 快速音频和视频编码器/解码器 |
---|---|
ffplay | 媒体播放器 |
ffprobe | 显示媒体文件的特点 |
ffserver | 使用HTTP和RTSP协议进行多媒体流的广播服务器 |
FFmpeg软件库
libavcodec | 各种多媒体编解码器的软件库 |
---|---|
libavdevice | 软件库的设备 |
libavfilter | 软件库包含过滤器 |
libavformat | 媒体格式的软件库 |
libavutil | 包含各种实用程序的软件库 |
libpostproc | 用于后期处理的软件库 |
libswresample | 用于音频重采样的软件库 |
libswscale | 用于媒体扩展的软件库 |
所有组件的编程语言是C语言,源代码可以在Linux/Unix、Windows、Mac OS X等系统上编译。
本书是使用官方二进制版本在Microsoft Windows上创建的,但几乎所有的指令和示例都应该在其他操作系统上无任何更改的情况下运行。 有关启用的选项的详细信息,请参阅词汇表中的FFmpeg配置条目。
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工具的使用和可用性问题上有特别的专长 |
参与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的所有修改 |
FFmpeg 下载
主要下载来源位于如下网页:
http://ffmpeg.org/download.html
Windows的用户可以从如下网页下载二进制文件(推荐使用静态构建):
http://ffmpeg.zeranoe.com/builds
许多Linux发行版已经安装了FFmpeg工具,否则它们可以被编译,这在OS X上也是可能的,或者OS X二进制文件可以从web页面下载:
http://www.evermeet.cx/ffmpeg or http://ffmpegmac.net
命令行语法
ffmpeg命令行工具的语法相对简单,重要的是在正确的位置键入所需的参数,而不是在各种输入和输出之间混合选项。ffmpeg命令的一般结构如下,需要注意的是全局选项影响所有输入和输出:
ffmpeg [global options] [input file options] -i input_file [output file options] output_file
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键并支持选择选项选项卡。
路径设置
将下载的FFmpeg命令行实用程序(ffmpeg.exe,ffplay.exe,ffprobe.exe)复制到环境变量Path部分中包含的目录是可以实现的,因此可以从任何目录调用它们而无需编写他们完整的路径。
或者,您可以将FFmpeg程序复制到其他目录,例如C:\ media,然后通过控制面板 - >系统和安全 - >系统 - >高级系统设置将此文件夹添加到系统路径。 请点击环境变量按钮,向下滚动系统变量的滚动条,点击路径,然后点击编辑按钮。 在弹出的窗口中单击编辑系统变量变量值字段,将光标移动到行尾,添加文本
;C:\media
点击OK按钮。分号分隔特定的目录,别复制。
对于命令提示符的当前会话,可以使用命令设置路径:
set path=%path%;C:\path_to_ffmpeg.exe
例如,如果文件ffmpeg.exe被复制到目录C:\media,命令是:
set path=%path%;C:\media
重命名为缩写形式(懒人专区)
命令名称ffmpeg有6个字符,如果每次用的话都输入"ffmpeg"这六个字符就太麻烦了,想个简单的办法,建议将文件ffmpeg.exe重命名为f.exe(ffplay.exe至fp.exe等)或类似的简写形式以保存 时间并防止被误认。 在命令提示符中,你可以使用以下命令:
ren ffmpeg.exe f.exe
为了清晰起见,本书总是使用完整的命令形式ffmpeg。
显示输出预览
在各种视频测试中,我们可以通过直接在屏幕上显示命令输出来节省大量时间,而不是将其保存到文件中,也不是在媒体播放器中预览。
FFplay媒体播放器预览
使用简化的命令,而不是使用ffmpeg工具生成一个新文件。
ffmpeg -i input_file ... test_options ... output_file
我们可以使用将显示与ffmpeg完全相同的ffplay,使用该命令保存到文件中
ffplay -i input_file ... test_options
使用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
可以在FFmpeg中使用的SI前缀
当指定数值各种ffmpeg选项如比特率或最大文件大小可以使用常见的SI后缀:K:千(103),M为百万(106),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
FFmpeg的代码转换
ffmpeg程序读入内存中指定的任意数量的输入的内容,根据输入的参数或程序的默认值对其进行处理,并将结果写入任意数量的输出。输入和输出可以是计算机文件、管道、网络流、抓取设备等。
在代码转换过程中,ffmpeg在libavformat库中调用demuxers来读取输入,并从数据包中获取编码数据。如果有更多的输入,ffmpeg可以通过跟踪任何活动输入流的最低时间戳来保持它们的同步。然后解码器从编码的数据包中生成未压缩的帧,在可选的过滤后,帧被发送到编码器。编码器产生新的编码包,它被发送到muxer并写入到输出。
FFmpeg工具的重要部分是过滤器,它可以被组织成过滤链和filtergraphs。Filtergraphs可以是简单的或复杂的。在解码源和编码输出之间实现滤波处理。转码过程在下一个图中说明。
Filters, filterchains,filtergraphs
在多媒体处理中,术语过滤器是指在编码到输出之前修改输入的软件工具。过滤器分为音频和视频过滤器(请参阅词汇表中的过滤器)。FFmpeg内置了许多多媒体过滤器,可以通过多种方式组合它们。具有复杂语法的命令根据指定的参数从一个过滤器到另一个过滤器。这简化了媒体处理,因为有有损压缩的媒体流的多译码和编码会降低整体质量。FFmpeg的过滤API(应用程序编程接口)是libavfilter软件库,它允许过滤器有多个输入和输出。过滤器包括在输入和输出之间使用-vf选项的视频过滤器和-af选项音频过滤器。例如,下一个命令生成一个测试模式顺时针旋转90°使用转置过滤器(7中描述。章):
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]标签作为覆盖过滤器的输入,从而产生最终的比较。另一个例子是在下一个图中。
选择的媒体流
一些媒体容器如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
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
颜色名称
一些视频过滤器和源有一个颜色参数,需要指定需要的颜色,并且有4种颜色规范的方法(默认值为黑色):
1.颜色被指定为W3C(万维网联盟)标准名称,以其十六进制值按字母顺序排列的标准名称的列表如下图所示。请注意,这里有几个同义词:aqua = cyan, fuchsia = magenta和gray = grey。
2.颜色被指定为十六进制数的形式0 xrrggbb @AA,RR红色通道,GG是绿色通道和BB是蓝色通道,例如0 x0000ff是蓝色的,0 xffff00是黄色的,等等。(@AA)是一个可选的alpha通道,指定有多少不透明的颜色,颜色在通道与一个@符号字符。Alpha通道值要么是从0x00到0xff的十六进制数字,要么是介于0.0和1.0之间的十进制数,其中0.0 (0x00)是完全透明的,1.0 (0xff)是完全不透明的。例如,半透明度的绿色是0x00ff00@0.5。
3。和之前的方法一样,但表示十六进制数字系统使用#符号而不是0 x前缀,一样在HTML代码中,例如# ff0000是红色的,# ffffff是白色的,等等。请注意,#前缀不能使用alpha通道,这意味着# 0000 ff@0x34是好的,但没有# 0000 ff@ # 34。
-
4.颜色是用一个特殊的值随机指定的,结果是由计算机产生的随机颜色。