FFmpeg 官方文档

0 / 893
FFmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
FFmpeg [全局选项] {[输入文件选项] -i 输入文件路径} ... {[输出文件选项] 输出文件地址} ...

其中,-i 表示 input[] 括起来表示可选项,{} 括起来表示一个或多个必输入项,括号外的全部必输入。

描述

FFmpeg 是一个非常快的音频、视频转换器,他也可以从直播音频、视频源进行抓取。他可以飞快地在各种不同的采样率之间进行转换、调整视频大小、使用高质量多相滤镜。

FFmpeg 读取一个或多个输入文件(可以是普通文件、管道文件、网络视频流、抓取设备等等)(这些输入文件被 -i 选项指定),然后写到一个或多个输出文件(被一段文本路径指定)。在一行命令中任何不能被识别为选项的内容都会被当成输出路径对待。

每个输入或输出路径可以,原则上,包含许多个不同种类的“流”(视频流、音频流、字幕流、附件流、数据流)。允许包含多少个流,受文件封装格式限制。可以自动或用 -map 选项(参阅“流选择”章节)手动选择哪个文件的哪个流写到哪个输出文件。

在选项中涉及输入文件时,你必须使用它们的索引号(从 0 开始的序号)。例如,第一个输入文件是 0,第二个文件是 1,以此类推。同样地,涉及一个文件内的流时也是使用这样的索引。例如,2:3(注意这里是英文冒号)表示第三个输入文件中的第四个流。(参阅“流选择”章节)。

作为总的原则,选项 总是只作用在它 之后 的那个文件上。因此,顺序很重要,你可以在一行命令中使用同一个选项多次。每次使用这个选项,都只作用在后面那个文件上。有一种例外,就是全局选项(例如啰嗦提示级别)(应当被首先指示出)。

不要混淆输入和输出文件,输入文件是先标出,输出文件是后标出。也不要混淆本该属于不同类型文件的选项。所有选项只对它后面那个文件起作用一次,然后就会被恢复默认值。

*设置输出视频的码率为64Kbps:
FFmpeg -i input.avi -b:v 64k -bufsize 64k output.avi

*强制输出视频帧率为24fps:
FFmpeg -i input.avi -r 24 output.avi

*强制输入文件帧率为1fps,同时输出视频为24fps:
FFmpeg -r 1 -i input.m2v -r 24 output.avi

处理的输入文件为原始数据(raw input file)时,可能需要一些格式选项。

详细描述

FFmpeg 对输出文件的转码过程可用下图简述:

_______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|

FFmpeg 先调用包含分流器(demuxer)的 libavformat 库读取输入文件,得到数据包(内含被编码后的数据)。当存在多个输入文件时,FFmpeg 将通过跟踪最小的时间戳来尝试同步所有活跃的输入流。

编码数据包然后被传递到解码器(除非复制流被选择用于流,详见后面进一步的说明),解码器产生的未压缩的帧(原始视频/PCM 音频/…),后者可以进一步被滤镜处理(见下一节)。通过滤镜处理后,这些帧被传递到编码器,编码器将其编码,并输出编码后的数据包。最后,这些数据包被传递给混合器,以将编码数据写入到输出文件。

滤镜

在使原始数据编码之前,FFmpeg 可以使用 libavfilter 库中的滤镜处理原始音频和视频帧。几个连接的滤镜可以形成一个滤镜组(filtergraphs)。 FFmpeg 有两种 filtergraphs:简单和复合。

简单 filtergraphs

简单 filtergraphs 是那些恰好只有一个输入和输出、并且输入输出都是相同类型的滤镜组。在下图中,它们可以被表示为,简单地在解码和编码之间插入一个附加步骤:

_________                        ______________
|         |                      |              |
| decoded |                      | encoded data |
| frames  |\                   _ | packets      |
|_________| \                  /||______________|
             \   __________   /
  simple     _\||          | /  encoder
  filtergraph   | filtered |/
                | frames   |
                |__________|

简单 filtergraphs 由对每个流的滤镜选项(-vf 和 -af 分别表示针对视频和音频的滤镜)配置。一个针对视频的简单 FilterGraph 可以看下这个例子:

_______        _____________        _______        ________
|       |      |             |      |       |      |        |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______|      |_____________|      |_______|      |________|

需知晓的是一些滤镜只改变帧的属性而不触及帧的内容。例如在上例中,fps 滤镜只改变帧的数量,不改变帧的内容。又如 setpts 滤镜,仅设置时间戳而保持帧不变。

复合 filtergraphs

复合 filtergraphs 是那些不能被描述为简单的线性处理链的滤镜组。例如,当滤镜组具有多个输入和(或)输出,或当输入和输出流是不同的类型。它们可以被表示为以下图:

_________
|         |
| input 0 |\                    __________
|_________| \                  |          |
             \   _________    /| output 0 |
              \ |         |  / |__________|
 _________     \| complex | /
|         |     |         |/
| input 1 |---->| filter  |\
|_________|     |         | \   __________
               /| graph   |  \ |          |
              / |         |   \| output 1 |
 _________   /  |_________|    |__________|
|         | /
| input 2 |/
|_________|

复合 filtergraphs 可使用 -filter_complex 选项指配。注意,此选项是全局性的,因为复合 FilterGraph,就其本质,不能只与单个流、单个文件相关联。

-lavfi 选项相当于 -filter_complex 选项。

一个复合 FilterGraph 的简单的例子是 overlay 滤镜,它具有两个视频输入和一个视频输出,内有一个视频叠加在另一个视频上面。其对应功能的音频滤镜是 amix 滤镜。

复制流

复制流是通过添加 copy 选项到 -codec 选项完成的。它使 FFmpeg 对指定的流忽略解码和编码步骤,所以它只能混合和拆包(例如从一个 mkv 文件拆包提取出视频流,放到一个 mp4 输出文件内打包,就仅仅是把视频流复制了,达到了无损转格式)。它对于改变所述容器的格式或修改容器级的元数据是有用的。在这种情况下,可以简化为这样:

_______              ______________            ________
|       |            |              |          |        |
| input |  demuxer   | encoded data |  muxer   | output |
| file  | ---------> | packets      | -------> | file   |
|_______|            |______________|          |________|

由于不存在解码或编码,复制流非常快(几乎等于复制粘贴的速度),没有画质或音质损失。然而因为许多因素,某些情况下可能无法使用。应用滤镜显然也是不可能的,因为滤镜仅能作用在未压缩的数据上(而拆包后的数据流都还是被编码了的、压缩了的数据)。

流的选择

FFmpeg 提供 -map 选项来手动控制每个输出文件中流的选择。用户可以跳过 -map 选项,让 FFmpeg 执行自动流选择(规则在下面提到)。不管是手动映射(map)还是自动选择,使用 -vn / -an / -sn / -dn 选项分别可以跳过输出文件对视频流、音频流、字幕流、数据流的选择(不过对那些复合 filtergraphs 输出的流不起作用)。

描述

接下来的小节叙述了涉及到流的选择的各种规则。后面会有例子帮你理解。

虽然,为了能够精确的反映程序的行为,文档作者们付出了很多努力来完善这个文档,但是 FFmpeg 是在被持续开发和完善的,自从写下这个文档,有些代码就可能已经改变了。

自动流选择

对于某一个输出文件,在映射(map)选项缺失的情况下,FFmpeg 会检查输出文件格式,看哪些种类的流可以被打包进去,例如视频流、音频流、字幕流。对于每个可以打包进去的种类,FFmpeg 会从所有可用的输入文件中选择一个流。

FFmpeg 会基于以下原则选择流:

  • 对于视频,选择最高分辨率的流
  • 对于音频,选择有最多声道的流
  • 对于字幕,选择第一个被找到的流,但是警告,输出文件的默认字幕编码器可能是基于文本的、也可能是基于图像的,只有与输出文件字幕类型相同的字幕流才会被选择。

在相同种类的几个流的参数同样高时,选择索引号最低的那个流。

数据流或附件流不会被自动选择,他们只能被 -map 选项选择。

手动流选择

当 -map 选项被使用时,除了下面会提到的 filtergraph 输出流,只有用户映射的(user-mapped)流会被包含在那个输出文件。

复合 filtergraph

当有一些复合 filtergraph 输出流带着未标记的 pads 时,这些输出流会被加到第一个输出文件。当这个流不被输出文件的格式支持时,就会导致严重错误。当没有 -map 选项时,这些复合 filtergraph 输出流的包含,会导致它们类型的流的自动选择被跳过。当有 -map 选项时,除了被手动映射的流,这些复合 filtergraph 输出流也会被额外囊括进去。

流处理

流处理是独立于流选择之外的(除了下面会讲到的字幕是例外)。流处理是通过-codec 选项来设定的,作用于指定输出文件内的流。尤其是,FFmpeg 是在流选择过程之后才实施流处理过程的,所以流处理过程不会影响流选择。如果对某个流没有指定 -codec 选项,FFmpeg 会根据输出文件的混合器(muxer)选择默认注册的编码器(encoder)。

对于字幕存在例外。如果一个输出文件的字幕编码器被指定,第一个被找到的字幕流(不管是文字、还是图像类型)都会被打包进去。FFmpeg 不检查指定的编码器是否能转换选择的流,也不检查转换后的流是否能被输出文件的格式兼容。这条规则是通用的:当用户手动设定一个编码器时,流选择过程无法检查被编码过的流可以被混合到输出文件中。如果不能,FFmpeg 会放弃所有输出文件,然后处理过程失败。

范例

接下来的例子会阐释 FFmpeg 流选择方法的行为、难点和限制。

假设有下列三个输入文件:

input file 'A.avi'
  stream 0: video 640x360
  stream 1: audio 2 channels

input file 'B.mp4'
  stream 0: video 1920x1080
  stream 1: audio 2 channels
  stream 2: subtitles (text)
  stream 3: audio 5.1 channels
  stream 4: subtitles (text)

input file 'C.mkv'
  stream 0: video 1280x720
  stream 1: audio 2 channels
  stream 2: subtitles (image)

自动流选择

FFmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov

这里指定了三个输出文件,对于前两个,没有设定 -map 选项,所以 FFmpeg 会为这两个文件自动选择流。

out1.mkv 是一个 Mastroska 容器的文件,可以存放视频、音频、字幕流,所以 FFmpeg 会每个种类选一个流。

  • 对视频流,会选择 B.mp4 中的 stream 0,也就是有最高分辨率的那个;
  • 对音频流,会选择 B.mp4 中的 stream 3,也就是有最大声道数的那个;
  • 对字幕流,会选择 B.mp4 中的 stream 2,也就是 A.avi 和 B.mp4 中第一个字幕流。

out2.wav 只接受音频流,所以只有 B.mp4 中的 stream 3 会被选择。

对于 out3.mov,因为有了 -map 选项,就不会发生流的自动选择了。-map 1:a 选项会选择第二个输入文件 B.mp4 中的所有音频流,不会有任何其它流被打包到这个输出文件。

自动字幕选择

FFmpeg -i C.mkv out1.mkv -c:s dvdsub -an out2.mkv

尽管 out1.mkv 是一个能够容纳字幕流的 Matroska 容器文件,但这个例子里只有视频和音频流会被选择。C.mkv 里的字幕是基于图像的,而 Mastroska 的默认字幕编码器是基于文字的,所以转码会失败,因而字幕流不会被选择。不过,out2.mkv 里,我们在命令里手动指定了一个字母编码器,所以,除了视频流,字幕流也会被选择加进 out2.mkv。-an 选项禁止了 out2.mkv 的音频流选择。

未写标签的 filtergraph 输出

FFmpeg -i A.avi -i C.mkv -i B.mp4 -filter_complex "overlay" out1.mp4 out2.srt

这里我们通过-filter_complex 选项设置了一个 filtergraph ,后者包含一个视频滤镜。overlay 滤镜要求正好两个视频输入,因为没有指定哪两个,所以会默认使用前两个可用的视频,也就是 A.avi 和 C.mkv 。由于这样,本来会选择 B.mp4 里面的流的自动视频流选择过程也就被跳过了。在 B.mp4 的 stream 3 里的音频流由最多的声道,会被自动选择上。然而不会有字幕流会被选择上,因为 mp4 格式没有默认注册的字幕编码器,而且用户也没有指定一个字母编码器。

对于第二个输出文件,out2.srt,只接受基于文字的字幕流。所以尽管第一个可用字幕流(那个属于 C.mkv 的)存在,但由于它是基于图像的所以会被跳过。被选择的流,B.mp4 中的 stream 2 ,是第一个基于文本的字幕流。

写了标签的 filtergraph 输出

(下述命令中,末尾的 / 在终端里表示换一行显示,继续写命令,执行的时候是把那几行命令当一行执行的)

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0[outv];overlay;aresample" \
   -map '[outv]' -an        out1.mp4 \
out2.mkv \
   -map '[outv]' -map 1:a:0 out3.mkv

上述命令会失败,因为带有[outv] 标签的输出板被映射了两次。所有输出文件都不会被处理。

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex
 "[1:v]hue=s=0[outv];overlay;aresample" \
   -an        out1.mp4 \
  out2.mkv \
   -map 1:a:0 out3.mkv

上述这个命令也会失败,因为带有[outv] 标签的 hue 滤镜的输出,没有被映射到任何一个输出文件。

这个命令应该像这样修改:

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0,split=2[outv1][outv2];overlay;aresample" \
-map '[outv1]' -an        out1.mp4 \
  out2.mkv \
-map '[outv2]' -map 1:a:0 out3.mkv

B.mp4 中的视频流被送到 hue 滤镜,后者的输出结果被 split 滤镜克隆了一份,两份输出分别被映射到第一个和第三个输出文件。

overlay 滤镜,要求两个视频输入,会使用前两个未被使用的视频流,也就是 A.avi 和 C.mkv 中的视频流。overlay 滤镜的输出没有被写标签,所以它会被发到第一个输出文件 out1.mp4 ( -map 选项对它不起作用)。

第一个未被使用的音频流,也就是 A.avi 的音频流,被送到 aresample 滤镜处理。因为这个滤镜的输出也是没有写标签的,所以也会被自动映射到第一个输出文件。-an 选项只抑制音频流的自动流选择、手动流选择,不会抑制 filtergraphs 送来的音频流。在 out1.mp4 中,这两个滤镜送出的流会排在映射的流的前面。

哪些音频、视频、字幕流被映射到 out2.mkv 完全取决于自动流选择。

out3.mkv 包含有 hue 滤镜输出的克隆流和来自 B.mp4 的第一个音频流。

选项

所有的数字选项,如果没有明确指名,接受由字符串表示的数字作为输入,后可接一个 SI 单位后缀,例如:K、M、G。

如果“i”被接到了 SI 单位后缀后,整个后缀会被当成二进制倍数后缀,也就是用 1024 为底的指数,而不是 1000 为底的指数。SI 单位后缀后接上“B”,会把其值乘以 8。这就可以用,例如:KB、MiB、G、B 作为数字后缀。(很好理解,bit 表示比特,Byte 表示字节,1 字节等于 8 比特)

没有后续参数的选项都是布尔选项,会将该选项设为启用。也可以通过加一个前缀“no”把这个选项关闭。例如“-nofoo”会把名字是“foo”的布尔选项关闭。

流标识符(Stream specifiers)

有些选项可能是应用到具体一个流上的,例如比特率、编码器。流标识符就是用来精确指明一个选项是属于哪个流的。

流标识符通常被连接到选项名字的后面,用冒号隔开。例如“-codec🅰️1 ac3”包含了“a:1”流标识符,匹配第二个音频流(audio 首字母是 a)。因此,对第二个音频流会使用 ac3 作为编码器(codec)。

一个流标识符可以匹配多个流,此时这个选项会应用到所有匹配到的流上。例如“-b:a 128k”会匹配所有的音频流。

没有标识符会匹配所有流,例如,-codec copy 或 -codec: copy 会让所有的流进行流复制(而不进行重新编码)。

流标识符可用的格式有:

  • stream_index(流索引号)

匹配这个索引号下的流,例如 -threads:1 会设置第二个流的线程设为 4。如果流索引号是作为附加标识符(见下面)的,那它就会选取匹配的所有流下的第索引号个流。流的序号是由 libavformat 检测流的顺序决定的,除了当程序 ID 被指定时。这时,序号是基于程序中的顺序决定的。

  • stream_type[:additional_stream_specifier](流类型[:额外流标识符])

流类型是下列字母之一:v 或 V 表示视频(video),a 为声音(audio),s 为字幕(subtitle),d 为数据(data),t 为附件(attatchments)。“v” 匹配所有的视频流,“V”只会匹配没有附加图片、缩略图、封面的视频。如果额外流标识符添加上了,那就只会匹配符合指定类型、并且匹配额外流标识符的流。否则,它就只会匹配所有符合指定类型的流

  • p:program_id[:additional_stream_specifier](p:程序 ID[:额外流标识符])

匹配拥有指定 id 的程序内的流。如果额外流标识符添加上了,那就只会匹配在拥有指定 id 的程序内的、并且匹配额外流标识符的流。

  • #stream_id or i:stream_id(流 id 或 i:流 id)

用流 id 匹配流(例如 MPEG-TS 容器内的 PID)。

  • m:key[:value](m:项名[:项值])

匹配元数据(metadata)中拥有指定标签项值的流。如果没有指定项值(value),就只匹配所有包含指定标签项的流。

  • u

匹配哪些拥有可用调整项的流,编码器必须被指定,并且关键信息(例如视频维度或音频采样率)必须被呈现。

应当知道,在 FFmpeg 中,通过元数据匹配只对输入文件有效。

通用选项

这些选项在 ff* 工具中通用

  • -L
    显示许可证。

  • -h, -?, -help, --help [arg]
    显示帮助。一个额外参数可以指定显示关于某个指定项的参数。如果没有参数,只会显示基本工具选项。
    可能的参数值有:

    long
    在基础工具选项的基础上,还显示高级工具选项
    
    full
    显示完整的选项列表,包括公共选项和编码器、解码器、分流器、混合器、滤镜的私有选项等。
    
    decoder=decoder_name
    显示所指定解码器名字的解码器详情信息。用 -decoders 选项列出所有的解码器。
    
    encoder=encoder_name
    显示所指定编码器名字的解码器详情信息。用 -encoders 选项列出所有的编码器。
    
    demuxer=demuxer_name
    显示所指定分流器名字的分流器详情信息。用 -formats 选项列出所有的分流器和混流器。
    
    muxer=muxer_name
    显示所指定混流器名字的混流器详情信息。用 -formats 选项列出所有的分流器和混流器。
    
    filter=filter_name
    显示所指定滤镜名字的滤镜详情信息。用 -filter 选项列出所有的滤镜。
    
    bsf=bitstream_filter_name
    显示所指定比特流滤镜名字的滤镜详情信息。用 -bsfs 选项列出所有的比特流滤镜。
    
  • -version
    显示版本。

  • -formats
    显示可用格式(包括设备)。

  • -demuxers
    显示可用分流器。

  • -muxers
    显示可用混流器。

  • -devices
    显示可用设备。

  • -codecs
    显示 libavcodec 库里所有已知编码器。
    需要提醒下,“codec”(编码器)这个术语,会在这个文档中多次出现,作为严格意义上“媒体比特流格式”的别称来使用。

  • -decoders
    显示可用解码器。

  • -encoders
    显示可用编码器。

  • -bsfs
    显示可用比特流滤镜。

  • -protocols
    显示可用协议。

  • -filters
    显示可用的 libavfilter 滤镜。

  • -pix_fmts
    显示可用像素格式。

  • -sample_fmts
    显示可用采样格式。

  • -layouts
    显示各种声道名和标准声道布局。

  • -colors
    显示可以被叫上名字的颜色名称。

  • -sources device[,opt1=val1[,opt2=val2]...]
    显示自动检测到的输入设备源。一些设备可能提供依赖系统的源且无法被自动检测到。不要期待返回的列表十分完整。
    FFmpeg -sources pulse,server=192.168.0.4

  • -sinks device[,opt1=val1[,opt2=val2]...]
    显示自动检测到的输出设备池。一些设备可能提供依赖系统的池且无法被自动检测到。不要期待返回的列表十分完整。
    FFmpeg -sinks pulse,server=192.168.0.4

  • -loglevel [flags+]loglevel | -v [flags+]loglevel
    设置日志记录级别和被数据库使用的标记。
    可选的标记前缀可包含下列值:

    ‘repeat’
    表示重复的日志输出不应该被压缩到第一行,并且“最后一个信息重复第n次”这样的行会被省略掉。
    
    ‘level’
    表示日志输出应该给每一行消息加上 [level] 前缀。这可以例如要将日志写到一个文件时,被用来做彩色日志的替代方法。(日志显示时,不同级别日志在终端里可以有不同颜色的显示,方便区分和查找,但写到文件里,都都是一个颜色了)
    
    可以通过添加“+”或“-”前缀来单独设置或取消设置一个标记,让这个标记被单独使用。当同时设置日志等级和标记时,在最后一个标记和日志等级之间,应当添加一个“+”分隔符。
    
    日志等级是一串包含下面数值的字符串或数字:
    
    ‘quiet, -8’
    不显示任何信息,安静。
    
    ‘panic, 0’
    只显示会导致处理过程崩溃的严重错误。现在这个还没有任何用。
    
    ‘fatal, 8’
    只显示严重错误,这些是经过让程序无法继续的错误之后的。
    
    ‘error, 16’
    显示所有错误,包括可修复的错误。
    
    ‘warning, 24’
    显示所有警告和错误,任何可能错误的、或没有预料到的事件都会被显示。
    
    ‘info, 32’
    显示处理过程中的信息消息。只是警告和错误之外的补充。这是默认值。
    
    ‘verbose, 40’
    和info一样,只是多了些啰嗦话。
    
    ‘debug, 48’
    显示所有信息,包括调试信息。
    
    ‘trace, 56’
    

    例如要启用“repeated log”输出,加上 level 前缀,然后设置日志等级为 verbose :

    FFmpeg -loglevel repeat+level+verbose -i input output
    

    另一个例子是启用“repeated log”,但是不影响当前 level 前缀标记或 loglevel 的状态:

    FFmpeg [...] -loglevel +repeat
    

    默认情况下,程序会输出日志到 stderr,如果终端程序支持着色功能,会有颜色标明错误和提醒。设置环境变量 AV_LOG_FORCE_NOCOLOR 可以关掉日志着色,设置环境变量 AV_LOG_FORCE_COLOR 可以强制开启日志着色。

  • -report
    把所有命令行和日志输出写到当前目录一个名字为 program-YYYYMMDD-HHMMSS.log 的文件中。这个文件对于调试很有帮助,后者意味着是 -loglevel 的调试。
    把任何值设置到环境变量 FFREPORT 也会有相同效果。如果这个值是一个“:”分隔的“key=value”序列,这些选项会影响 report ;如果选项值包含特殊字符或“:”,应当加上转义符。(详见 FFmpeg-utils 手册的“引用和转义符”部分)
    下面的选项是被认可使用的:

    file
    给 report 设置文件名;%p 最后会被扩充为程序(program)的名字,%t 最后会被扩充为时间戳(timestamp),%% 会被扩充为纯百分号(%)。
    
    level
    通过数字值设置日志啰嗦级别(见 -loglevel)。
    
    例如,要用 32(info级别的数字值) 日志级别输出 report 到一个叫 ffreport.log 的文件:
    FFREPORT=file=ffreport.log:level=32 FFmpeg -i input output
    
    分隔环境变量的错误不是严重的,所以不会出现在 report 中。
    
  • -hide_banner
    阻止显示 banner
    所有 FFmpeg 工具一般都会显示版权提醒、版本选项、数据库版本。这个选项可以组织显示这些信息。

  • -cpuflags flags (global)
    允许设置和清除 cpu 标识,这个选项是用于测试的,不懂相关知识可千万别瞎用!

    FFmpeg -cpuflags -sse+mmx ...
    FFmpeg -cpuflags mmx ...
    FFmpeg -cpuflags 0 ...
    

    这个选项可用的标识有:

    ‘x86’
    ‘mmx’
    ‘mmxext’
    ‘sse’
    ‘sse2’
    ‘sse2slow’
    ‘sse3’
    ‘sse3slow’
    ‘ssse3’
    ‘atom’
    ‘sse4.1’
    ‘sse4.2’
    ‘avx’
    ‘avx2’
    ‘xop’
    ‘fma3’
    ‘fma4’
    ‘3dnow’
    ‘3dnowext’
    ‘bmi1’
    ‘bmi2’
    ‘cmov’
    ‘ARM’
    ‘armv5te’
    ‘armv6’
    ‘armv6t2’
    ‘vfp’
    ‘vfpv3’
    ‘neon’
    ‘setend’
    ‘AArch64’
    ‘armv8’
    ‘vfp’
    ‘neon’
    ‘PowerPC’
    ‘altivec’
    ‘Specific Processors’
    ‘pentium2’
    ‘pentium3’
    ‘pentium4’
    ‘k6’
    ‘k62’
    ‘athlon’
    ‘athlonxp’
    ‘k8’
    

AVOptions(音视频选项)

这些选项是由 libavformat、libavdevice 和 libavcodec 库直接提供的,若要查看可用的 AVOptions 的列表,使用 -help 选项。它们被分成两类:

Generic(通用)

这些选项可以用于各种容器、编码器、设备。对于容器/设备的通用选项被列在 AVFormatContext 选项下,对于编码器的通用选项被列在 AVCodecContext 选项下。

Private(私有)

这些选项只能用于特定容器、编码器、设备。私有选项被列在对应的容器、编码器、设备下。

例如要写一个 ID3v2.3 头到一个 mp3 文件,而不是写 ID3v2.4 头,要使用 MP3 混流器 id3v2_version 的私有选项:

FFmpeg -i input.flac -id3v2_version 3 out.mp3

所有的编码器音视频选项都是针对“流”的,所以应当在选项后面加上流标识符:

FFmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4

在上述的示例命令中,一个多声道的音频流被两次映射到输出(也就是输出文件被映射了两个音频流,两个音频流的内容一样)。对第一个音频流使用了 ac3 编码器、码率值 640k。对第二个音频流使用了混合成双声道、码率值 128k(这里我们的流标识符使用了数字索引值,2 即代表第三个流)。

提醒:之前提到的 -nooption 语法不能被用于布尔 AVOptions ,应使用 -option 0 / -option 1 才行。

提醒:有一个没有提到的、老旧的、用于给 AVOptions 指定流的方法是在这些选项前加上 v/a/s ,但是这个方法已经过时,并且即将在后续版本中被删去了,所以别再用了!

主要选项

  • -f fmt (input/output)
    强制输入文件或输出文件为某个格式。一般输入文件的格式会被自动检测,输出文件的格式会被通过其后缀名推测。所以这个选项通常不用。

  • -i url (input)
    输入文件或路径(例如可以是一个网址)

  • -y (global)
    不经过询问,直接覆盖输出文件。

  • -n (global)
    不要覆盖输出文件,如果与某个输出文件同路径同文件名的文件已经存在,直接退出。

  • -stream_loop number (input)
    设定输入的流应循环几次。0 意味着不循环,-1 表示一直循环。

  • -c[:stream_specifier] codec (input/output,per-stream)
    -codec[:stream_specifier] codec (input/output,per-stream)
    当用在输出文件之前,选择编码器。当用在输入文件之前,选择解码器。codec 的值是编码器或解码器的名字,或者是一个特殊值“copy”(只对输出文件有效),意味着输出流不被经过解码、重编码。
    例如:

    FFmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
    

    会用 libx264 编码器编码所有视频流,但只复制音频流。
    对每一个流,只有最后一个匹配的 -c 选项会被应用,例如:
    FFmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:1 libvorbis OUTPUT
    除了第二个视频流会被 libx264 编码、第 138 个音频流会被 libvorbis 编码外,会复制所有流。

  • -t duration (input/output)
    当作为输入文件选项(用在 -i 之前)时,限制从输入文件读取的数据的时间。
    当作为输出文件选项(用在输出路径之前)时,写入指定持续时间的流后,停止写入。
    duration 必须是一段时间的长度,详见 FFmpeg-utils(1) 的手册中“Time duration”一节。
    -to 和 -t 是相互排它的,-t 有更高优先级。

  • -to position (input/output)
    在某个位置停止读取或写入。position 必须是一个指定的持续时间。详见 FFmpeg-utils(1) 的手册中“Time duration”一节。
    -to 和 -t 是相互排它的,-t 有更高优先级。

  • -fs limit_size (output)
    设定文件大小限制,单位是比特。超过指定大小后,不会有数据再被写入。当然,最后总的文件大小可能略微超过指定的大小。

  • -ss position (input/output)
    当作为输入选项使用时,找到输入文件中的 position 开始读。应知晓的是,对于大部分文件,很难非常精确地找到那个位置,所以 FFmpeg 会寻找最接近指定点的位置。当转码和 -accurate_seek 开启(默认都是开启的)时,这个在实际点和预期点之间的小片段就会被扔掉。但当使用流复制或 -noaccurate_seek 时,这一小段就会被保留。
    当作为输出选项使用时,会解码所有输入,但达到指定时间戳之前的内容都会被丢弃掉。
    position 必须是一段时间的长度,详见 FFmpeg-utils(1) 的手册中“Time duration”一节。

  • -sseof position (input)
    就像是 -ss 选项一样,不过这时的参照点是文件末尾(end of file)。负数表示的位置更早,0 表示在文件末尾。

  • -itsoffset offset (input)
    设定输入文件的时间偏移(the input timestamp offset)。
    offset 必须是一段时间的长度,详见 FFmpeg-utils(1) 的手册中“Time duration”一节。
    偏移被添加到输入文件的时间戳。指定一个正的偏移,表示对应的流会被延迟指定的偏移时长。
    可以简记为:input timestamp offset

  • -itsscale scale (input,per-stream)
    重缩放时间戳。scale 应当是一个浮点数。

  • -timestamp date (output)
    设定容器内的录制时间。
    date 必须是一个指定日期,详见 FFmpeg-utils(1) 的手册中“Date”一节。

  • -metadata[:metadata_specifier] key=value (output,per-metadata)
    设定元数据的 项/项值 对。
    一个可选的元数据标识符可以指定元数据被写在哪条流、章、程序上。详见 -map_metadata 部分。
    用上 -map_metadata 时,这个选项会覆盖元数据。也可以通过设定一个空数值来删除元数据。
    例如,要给输出文件设置一个作品标题(title):

    FFmpeg -i in.avi -metadata title="my title" out.flv
    

    要设定第一个字幕流的语言:

    FFmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
    
  • -disposition[:stream_specifier] value (output,per-stream)
    设定一个流的位移。
    这个选项会覆盖从输入流复制的位移。也可以通过设置它为 0 来删除位移。
    下面列出的位移可以被识别:

    default
    dub
    original
    comment
    lyrics
    karaoke
    forced
    hearing_impaired
    visual_impaired
    clean_effects
    attached_pic
    captions
    descriptions
    dependent
    metadata
    

    例如,要设第二个音频流为默认音频流:

    FFmpeg -i in.mkv -c copy -disposition:a:1 default out.mkv
    

    要设置第二个字幕流为默认字幕流,并且移除第一个字幕流的默认位移:

    FFmpeg -i in.mkv -c copy -disposition:s:0 0 -disposition:s:1 default out.mkv
    

    要添加一个内置封面/缩略图:

    FFmpeg -i in.mp4 -i IMAGE -map 0 -map 1 -c copy -c:v:1 jpg -disposition:v:1 attached_pic out.mp4
    

    并非所有混合器支持内置缩略图,而那些支持缩略图的混合器,往往只支持有限的格式,例如 JPEG 或 jpg。

  • -program [title=title:][program_num=program_num:]st=stream[:st=stream...] (output)
    创建一个程序,这个程序有指定的标题、程序号,并添加指定的流给这个程序。

  • -target type (output)
    指定目标文件类型 (vcd, svcd, dvd, dv, dv50) 。用 pal-、 ntsc- 或 film- 先指定类型后,就会使用该类型相对应的标准。所有的格式选项(码率、编码器、缓存大小)就都会被自动设置好。你只需要输入:

    FFmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
    

    不过你仍可以添加各种你所知道的附加选项(只要这些选项与设定的类型不冲突就行),就像:

    FFmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
    
  • -dn (input/output)
    作为输入选项用时,会阻止所有数据流被施加滤镜、自动映射到任何输出。想只禁用单独一条流的话,请参阅 -discard 选项。
    作为输出选项用时,会阻止数据录制,如自动选择或自动映射任何数据流。若要完整的手动控制,请参阅 -map 选项。

  • -dframes number (output)
    设定输出数据的帧数。这是 -frames:d 的一个老旧别名,以后最好老老实实用 -frames:d 。

  • -frames[:stream_specifier] framecount (output,per-stream)
    达到指定的帧总数后,就停止写输出。

  • -q[:stream_specifier] q (output,per-stream)
    -qscale[:stream_specifier] q (output,per-stream)
    使用固定品质缩放(VBR)。q/qscale 的意思是随编码器的不同而改变的。如果 qscale 选项后没有跟流标识符,那它只会被用到视频流上,这是为了保持与之前行为的兼容性,并且,当没有使用流标识符,同样一个 qscale 数值对于不同的编码器(例如视频编码器和音频编码器)意义是不同的。

  • -filter[:stream_specifier] filtergraph (output,per-stream)
    创建一个 filtergraph 并且用这个 filtergraph 给指定的流做滤镜。
    filtergraph 是一个用在流上的 filtergraph 的描述,并且必须有相同类型的严格一个输入和一个输出流。在 filtergraph 中,输入被与“标签入”关联,输出被与“标签出”关联。更多信关于 filtergraph 的语法信息详见 FFmpeg-filters 手册。
    如果你想对多个输入和/或输出创建 filtergraphs 请参阅 -filter_complex 选项部分。

  • -filter_script[:stream_specifier] filename (output,per-stream)
    这个选项和 -filter 很相像,唯一的区别是,这里的参数是一个文件名,所指的文件内包含的 filtergraph 描述会被读取。

  • -filter_threads nb_threads (global)
    规定用多少线程处理滤镜工作流。每个工作流会产生一个为并行处理的、内含这么多个可用线程数的线程池。默认值是可用的 CPUs 数量。

  • -pre[:stream_specifier] preset_name (output,per-stream)
    为匹配的流指定预设。

  • -stats (global)
    显示编码的进程/统计数据。默认是开启的,要关掉的话需要使用 -nostats 选项。

  • -progress url (global)
    发送程序可读的进程信息到一个 url(路径、网址)。
    进程信息约每秒写一次,编码完成后单独写一次。由每一行一个 "key=value" 的格式组成。key 由字母、数字组成,一系列 key 的最后一个 key 总是“progress”。

  • -stdin
    启用与标准输入的反应。默认开启,除非标准输入被用作输入。要声明关掉,请使用 -nostdin 。
    关掉与标准输入的响应是很有用的,例如,如果 FFmpeg 是一个后台进程组,使用 FFmpeg 大致上可以达到与 < /dev/null 相同的效果,只是需要一个 shell。

  • -debug_ts (global)
    显示时间戳信息。默认是关的。这个选项对于调试和找 bug 很有用,输出格式可能因版本不用而不同,所以不要根据这个信息写脚本哦~
    还可以参阅 -fdebug ts 选项。

  • -attach filename (output)
    添加附件到输出文件中。少数容器支持这个功能,例如 Matroska 用字体文件来渲染字幕。附件会被放入一个特殊类型的流,所以这个选项会添加一个流,然后就可以用通常的对流的选项处理这个流。这个选项创建的附件流会在其它流都写入完成后再写入。
    提醒下,对于 Matroska 容器,你还需要设置下元数据的 mimetype 项:
    FFmpeg -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv
    (上例假设附件流会是输出文件里的第三个流)

  • -dump_attachment[:stream_specifier] filename (input,per-stream)
    提取匹配的附件流到一个文件。如果 filename 是空的,那写出的文件名会是该元数据项中的值。
    例如提取一个附件流到一个叫“out.ttf”的文件:

    FFmpeg -dump_attachment:t:0 out.ttf -i INPUT
    

    把所有附件流提取出来,文件名就由元数据中文件流的 filename 项决定:

    FFmpeg -dump_attachment:t "" -i INPUT
    

    技术性提醒:附件是被当成 codec 的额外数据进行处理的,所以这个选项可以从任何流中提取 codec 外的额外数据,而不只是用于提取附件流。

  • -noautorotate
    不基于元数据中的信息自动旋转视频。

视频选项

  • -vframes number (output)
    为输出文件设定视频帧的总数。这是 -frames:v 的一个老旧的别称,以后最好老实用 -frames:v 。

  • -r[:stream_specifier] fps (input/output,per-stream)
    设置帧速率(单位 Hz,分数或缩写)
    作为输入选项时,忽略文件内的时间戳,而生成假设原文件是恒定帧速率(单位 fps)的时间戳。这和用于某些格式(age2、v4I2)的输入文件的 -framerate 选项不同(在一些早期版本的 FFmpeg 中,二者是相同的)。如果不确定,保险起见还是用 -framerate 代替 -r 这个输入选项吧。
    作为输出选项时,复制或丢弃输入帧,以达到恒定输出帧速率(单位 fps)。

  • -s[:stream_specifier] size (input/output,per-stream)
    设定帧大小
    作为输入选项时,这是一个视频大小私有选项的快捷方式,对于一些帧大小没有被储存在文件中或帧大小可调的输入,例如 raw 视频 或 视频采集卡数据,一些分流器可以使用这个参数。
    作为输出选项时,这会插入一个视频放缩滤镜(scale video filter)到 filtergraph 的尾部。如果要在开始或其它地方使用放缩,请直接在需要的地方插入视频放缩滤镜。
    大小格式是“宽 x 高(wxh)”,中间是一个小写 x,不是乘法符号哈~。默认数值是源大小。

  • -aspect[:stream_specifier] aspect (output,per-stream)
    设定视频播放比例为 aspect 数值。
    aspect 可以是浮点数,也可以是英文冒号分隔的比例形式“num:den”,num 代表分子(numerator),den 代表分母(denominator)。例如:4:3、16:9、1.3333、1.7777 等有效参数。
    若同时使用了 -vcodec copy ,只会在容器级别上影响视频比例,如果在编码级别有比例参数的话,对编码级别的比例参数不会有比例影响。

  • -vn (input/output)
    作为输入选项时,阻止文件内的视频流被施加滤镜、自动选择、映射到任何输出。若要禁止单独的流,请参阅 -discard 选项。
    作为输出选项时,关闭视频录制(也就是视频流自动选择或映射任何视频流),若要完全手动控制视频流的选择,请参阅 -map 选项。

  • -vcodec codec (output)
    设置视频编码器。这是 -codec:v 选项的别名。

  • -pass[:stream_specifier] n (output,per-stream)
    选择这是第几次压制(1 或 2)。常被用来做 2-pass(二压)视频编码。
    第一次压制(1-pass)视频的统计数据会被写到一个 log 文件(参阅 -passlogfile 选项),第二次压制时,会参阅这个 log 文件 ,以达到更精确的码率控制(复杂的画面给多点码率,简单的画面少给点码率)。
    第一次压制的时候,你可以直接取消音频压制,并把输出文件路径指向 NULL (null 路径是一个特殊路径,任何数据输到这个路径都会被销毁为空),省得第一次压制的输出视频占你空间。
    以下是对 Windows 和 Unix 的第一次压制示例:

    FFmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
    FFmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
    

    这里除原文外多说一下,2-pass 是要分两步命令进行的,不能直接用 -pass 2 选项,因为你还没有 -pass 1 生成的 log。例如,在 Termux 上,你要 2-pass 一个文件码率降到 2000k,应当执行像这样两步:

    FFmpeg -i input.mp4 -c:v libx264 -pass 1 -an -f rawvideo -y /dev/null
    FFmpeg -i input.mp4 -c:v libx264 -pass 2 -b:v 2000k -c:a copy output.mp4
    
  • -passlogfile[:stream_specifier] prefix (output,per-stream)
    设置 2-pass 所用 log 文件名的前缀为 prefix,默认的文件名前缀是“FFmpeg2pass”。完整的文件名是 PREFIX-N.log,这里的 N 指的是输出流的序数。
    这里除了原文外还要多说一点,例如在 FFmpeg Media Encoder 这个 App 中,用这样的参数:

    FFmpeg -i /sdcard/input.mp4 -c:v libx264 -pass 1 -an -f rawvideo -y /dev/null
    

    无法执行,会提示无法打开 stats 文件,应该是没有写入权限,这时我们就可以用-passlogfile 选项了:

    FFmpeg -i /sdcard/input.mp4 -c:v libx264 -pass 1 -passlogfile /sdcard/FFmpeg/passlog -an -f rawvideo /dev/null
    

    第一次压制后就会在 /sdcard/FFmpeg/ 目录下生成名为 passlog-0.log 的 stat 文件,然后 2-pass 时的 log 文件路径也选择这个目录:

    FFmpeg -i /sdcard/input.mp4 -c:v libx264 -pass 2 -passlogfile /sdcard/FFmpeg/passlog -b:v 2000k -c:a copy /sdcard/output.mp4
    

    或者你也可以试试把 1-pass 出来的视频保留,和 2-pass 出来的视频做对比:

    FFmpeg -i /sdcard/input.mp4 -c:v libx264 -pass 1 -passlogfile /sdcard/FFmpeg/passlog -b:v 2000k -c:a copy /sdcard/1_pass_output.mp4
    FFmpeg -i /sdcard/input.mp4 -c:v libx264 -pass 2 -passlogfile /sdcard/FFmpeg/passlog -b:v 2000k -c:a copy /sdcard/2_pass_output.mp4
    

    压制完成后,看下相同码率下,压制一次和压制两次的画质差异。

  • -vf filtergraph (output)
    创建一个由 filtergraph 指定的滤镜组,并用这个滤镜组为流添加滤镜。
    这是 -filter:v 的一个别称,详见 -filter 选项。

高级视频选项

  • -pix_fmt[:stream_specifier] format (input/output,per-stream)
    设置像素格式。
    用 -pix_fmts 可以查看都支持哪些像素格式。
    如果所选的像素格式无法使用,FFmpeg 会发出警告,然后使用该输出文件容器支持最佳的像素格式。如果此时 pix_fmt 加了个前缀“+”,FFmpeg 会提示错误并退出,并且 filtergraphs 内的自动转换也会被关闭。如果 pix_fmt 只是个单纯的“+”,那 FFmpeg 选择与输入(或图形输出)相同的像素格式并且禁用自动转换。
    除了原文,再额外提下,我们一般用的 mp4 视频的像素格式是 8bit sRGB,就是用三个数值分别表示红绿蓝颜色,每个数值的取值范围是 0-255,每个数值占用 8bit,8bit 就是一个字节(Byte),那一个像素就要占用 24bit(3 字节)。
    后来就有人觉得,一个像素 3 字节,这样视频传输就太占带宽了,后来也出现了其它的像素格式(先后顺序我没去查)。
    一个著名的像素格式就是 YUV 格式,YUV 是一个总称,其下又有许多子格式,谷歌的油管视频传输用的 webm 格式视频就用到了 yuv420p 像素格式。下面介绍下 yuv420p 格式的意思。
    人眼视网膜有三种感光细胞,一种只感受明暗(数量最多),另外两种感受颜色,人眼对于明度,比颜色更敏感,产生了 YUV 格式,其中 Y 表示明度(灰阶值),U 和 V 两个颜色向量(色差),这样就可以表示所有人眼可见的颜色。
    在传输时,对于彩色电视,使用 YUV 信号,对于黑白电视,只需要采用 Y 信号,不管 UV 就行。这样,就实现了彩色和黑白电视对同一种信号的兼容。
    因为人眼对颜色的敏感度相对较低,我们就可以缩减 UV 占用的空间。
    先看一下 YUV444,以同一行四个像素为一组,它们的数据为:

    Y0 U0 V0  Y1 U1 V1  Y2 U2 V2  Y3 U3 V3
    

    存储时,我们就要记录:

    Y0  Y1  Y2  Y3
    U0  U1  U2  U3
    V0  V1  V2  V3
    

    总共 12 个数值,要占用 12 字节,平均每个像素占 3 字节,四个像素里有 4 个 Y 值,4 个 U 值,4 个 V 值。
    再来看下 YUV422,还是以同一行四个像素为一组,因为两个像素颜色差异很小,只要明度记录正确,相邻两个像素用同一个 UV 值,人眼也看不出来,所以它们的数据为:

    Y0 U0 V0  Y1 U0 V0  Y2 U2 V2  Y3 U2 V2
    

    存储时,我们就要记录:

    Y0  Y1  Y2  Y3
    U0     U2   
    V0     V2
    

    总共 8 个数值,占用 8 字节,平均每个像素占 2 字节,四个像素里有 4 个 Y 值,2 个 U 值,2 个 V 值。这样理论上对画质有影响,可是我们人眼看不出来!这就省空间了!
    接下来看 YUV420,专家们进一步研究表示,每一行相邻两个像素与下一行同位置的两个像素数据差异不大,我们还可以进一步丢数据!考虑两行四列 8 个像素为一组,它们的数据为:

    Y0 U0 V4  Y1 U0 V4  Y2 U2 V6  Y3 U2 V6
    Y4 U0 V4  Y5 U0 V4  Y6 U2 V6  Y7 U2 V6
    

    存储时,我们就要记录:

    Y0  Y1  Y2  Y3  
    U0     U2   
    
    Y4  Y5  Y6  Y7
    V4     V6
    

    这样的话,对奇数行每四个像素,我们只需要记录 4 个 Y 值、2 个 U 值、0 个 V 值;对偶数行每四个像素,我们只需要记录 4 个 Y 值、0 个 U 值、2 个 V 值。平均每四个像素只需记录 6 个数值,占用 6 字节,平均每个像素只占 1.5 字节!
    YUV 有两种记录方式。
    打包(packed)方式就是以相邻几个像素为一组,用一小包数据记录这一组像素的所有 YUV 数值。
    平面(planar)方式就是把 Y、U、V 分开后,将它们的数值各自存储到一个数组中,就是一个 Y 数组,一个 U 数组,一个 V 数组。就像是把三种不同的数据放到三个不同平面进行存放。
    而 YUV420P 中的“P”就表示平面存储方式。
    相比较 sRGB 像素格式,视频采用 YUV420P 像素格式来存储视频,就可以在对画质影响较小的前提下,将码率折半!

  • -sws_flags flags (input/output)
    设置 SwScaler 标识。

  • -rc_override[:stream_specifier] override (output,per-stream)
    对指定区间覆盖码率控制(Rate control),格式为“int,int,int”(整数,整数,整数),用“/”隔开的列表。前两个数值是开始帧和结束帧的数值,第三个数值,正值表示量化值(quantizer),负值表示质量因子(quality factor)。

  • -ilme
    强制让编码器(只有 MPEG-2 和 MPEG-4 )支持隔行扫描(interlacing)。如果你的输入文件是隔行扫描的,并且你希望以最小的画质损失保持隔行扫描。替代方法是用 -deinterlace 执行“去除隔行扫描”,但“去除隔行扫描”会带来质量损失。

  • -psnr
    计算压缩帧的 PSNR(峰值信噪比 Peak signal-to-noise ratio)。

  • -vstats
    将视频编码统计数据(video coding statistics)写入到 vstats_HHMMSS.log 文件中。

  • -vstats_file file
    将视频编码统计数据(video coding statistics)写入到指定的“file”这个文件中。

  • -vstats_version file
    指定使用哪个版本(version)的视频编码统计数据(video coding statistics)。默认值是 2

    version = 1 :
    frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s
    
    version > 1:
    out= %2d st= %2d frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s
    
  • -top[:stream_specifier] n (output,per-stream)
    top=1/bottom=0/auto=-1 field first (官方文档就这么一行,我也不清楚该咋解读)

  • -dc precision
    Intra_dc_precision. (官方文档就这么一行,我也不清楚该咋解读)

  • -vtag fourcc/tag (output)
    强制视频 tag/fourcc。这是 -tag:v 的别名。

  • -qphist (global)
    显示 QP 直方图(QP histogram)。
    -vbsf bitstream_filter
    反对用这个,详见 -bsf。

  • -force_key_frames[:stream_specifier] time[,time...] (output,per-stream)
    -force_key_frames[:stream_specifier] expr:expr (output,per-stream)
    -force_key_frames[:stream_specifier] source (output,per-stream)
    force_key_frames 可以是以下形式的参数:

    • time[,time...]
      如果参数包含时间戳,FFmpeg 会依据编码器时间基准估计出离所给的每个时间戳最近的输出时间戳,并在确切计算出的时间戳的位置、或比计算出的时间戳稍微大点的位置的第一帧强制设一个关键帧。要提醒的是,如果编码器时间基准很粗糙,那么关键帧可能别设在比指定时间靠前一点的那一帧上。默认的编码器时间基准是输出帧率的倒数,但也可以通过 -enc_time_base 选项设定。
      如果其中一个时间是“chapters[delta]”,那这个时间就会被替换成文件内所有章节开始的时间,每连个值之间相差一个 delta ,表示方式为以秒为单位的时间。当要确保在输出文件的一个章节标记处或其它标识处存在一个 查找点(seek point)时这个选项是很有用的。
      例如,要在五分钟处插入一个关键帧,在每一章 0.1 秒前添加一个关键帧:

      -force_key_frames 0:05:00,chapters-0.1
      
    • expr:expr
      如果参数的前缀加上了”expr:“,那么“expr”就被像表达式一样被解析,并且对于每一帧都会求值。当计算结果为非 0 时会强制一个关键帧。
      表达式可以包含如下常数:

      • n
        当前总的处理过的帧数,从 0 开始。
      • n_forced
        强制添加的关键帧的数量。
      • prev_forced_n
        之前强制添加的关键帧是整个视频第几帧,当没有关键帧被添加时它的值是“NSN”。
      • prev_forced_t
        之前添加的关键帧的时间,当没有关键帧被添加时它的值是“NSN”。
      • t
        当前处理帧的时间。

      例如要每 5 秒添加一个关键帧,你可以这样写:

      -force_key_frames expr:gte(t,n_forced*5)
      

      要从第 13 秒开始,在每前一个关键帧 5 秒后插入一个关键帧:

      -force_key_frames expr:if(isnan(prev_forced_t),gte(t,13),gte(t,prev_forced_t+5))
      
    • source
      如果参数是“source”,如果当前被编码帧在原视频里就是一个关键帧,FFmpeg 会强制插入一个关键帧。

    注意,强制太多关键帧对特定编码器的向前算法(lookahead alogorithms)是非常有害的:使用 fixed-GOP 选项或相似的选项会更高效。

  • -copyinkf[:stream_specifier] (output,per-stream)
    当做复制流时,也复制在开始找到的非关键帧(copy input non-key frames found at the beginning)。

  • -init_hw_device type[=name][:device[,key=value...]]
    使用给定的参数,启用一个类型是“type”、名字是“name”的新硬件。如果没有指定的名字,那这个硬件会受到一个“type%d”形式的默认名字。
    “device”的意义和下面的参数取决于设备类型:

    • cuda
      “device”是 CUDA 设备的序号。
    • dxva2
      “device”是 Direct3D 9 显卡适配器的序号。
    • vaapi
      “device”是 X11 display 的名字或 DRM 渲染节点。如果没有指定,会尝试打开默认的 X11 display ($DISPLAY) 然后打开第一个 DRM 渲染节点(/dev/dri/renderD128)。
    • vdpau