2. FFmpeg命令行工具的使用

目录 | TABLE OF CONTENT


[TOC]


注意:为了避免专有名词翻译带来的混淆,直接使用专有名词原语言。你应该在理解其原理的基础之上来处理这些专有名词,而不是为了翻译。

1. 概述

ffmpeg是ffmpeg项目下的一个命令行工具,它是一个非常快速的音视频转换在工具,也可以从现场的音视频源获取(捕捉音视频源)。它可以在任意采样率之间进行转换,并使用高质量的多相过滤器即时调整视频大小。

ffmpeg通过指定-i选项可以从任意数量的输入"文件"中读取数据(这些可以是常规文件、命名管道文件、网络流、捕获设备等),并写入任意数量的输出"文件",其中输出由一个纯粹的输出URL指定,任何在命令行中不能被解释为选项的内容都被认为是一个输出URL。

原则上,每个输入或者输出URL都能够包含不同类型的任意数量的流(视频/音频/字幕/附件/数据)。流的数量和(或者)类型可能受到容器格式[1]的限制。选择哪个流从哪个输入到哪个输出操作是自动完成的,我们也可以使用-map选项来指定(具体请查看stream selection 章节)。

为了在选项中引用输入文件,你必须使用索引(索引从0开始)。比如:第一个输入文件是0,第二个是1,等等

类似地,文件中的流由它们的索引引用。比如:2:3 就表示引用第三个文件中的第四个流。n:m的形式其实可以简单地看作:n代表文件索引,m代表流的索引。(该知识会在后续章节详细讲解)

作为一个基本的原则,在FFmpeg中,选项被应用于下一个指定的文件。因此,顺序非常重要,并且你可以在命令行下多次使用相同的选项。然后每一个事件被应用于下一个输入或者输出文件。除了这个规则之外的选项被做为全局选项,应当首先指定。

不要混淆了输入和输出文件,首先被指定的一定是输入文件,然后才是输出文件。同样,也别混淆了属于每一个文件的选项,所有的选项被应用于下一个输入或者输出文件,并在文件之间复位。

例如:

设置输出文件的比特率为64 kbit/s[2]

ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi

强制输出文件的帧数率[3]为24fps

ffmpeg -i input.avi -r 24 output.avi

强制输入文件(仅仅适用于原始格式)的帧数率为1fps,强制输出文件的帧数率为24fps。

ffmpeg -r 1 -i input.m2v -r 24 output.avi

注意:有些格式的选项可能要求输入文件是原始的,比如要更改输入文件的帧数率的时候,有些容器格式协议难以或者不支持该操作

2. 详细说明

在FFmpeg中,每一个输出的转码过程可以用如下图来描述:

trancoding_process.png

简单地讲,转码就是将数据从一种格式转换为另一种格式的过程。

ffmpeg调用libavformat库(包含多路解复用器[4])来读取输入文件,并从中获取包含编码数据的数据包。当有多个输入文件时,ffmpeg尝试在任何活动的输入流上通过跟踪最低时间戳来保持同步。然后将编码的数据包传递给解码器。解码器会产生未压缩的数据帧(原始的video/PCM、audio/...),随后被过滤后进一步处理。过滤之后,数据帧被传递给编码器,编码器将其编码,然后输出编码包。最终这些编码好的包被传递给复用器[5],复用器将编码包写入输出文件。

这里简单解释一下复用器和解复用器。视频文件实际上类似于zip文件,它们是由多个不同类型的数据文件组成的,其中包含元数据、视频轨道、音频轨道、字幕数据等,各个数据还具备自己的元数据,因此,这些数据文件会通过一个叫做复用器的机制按照一定的标准组合成一个文件。相反,解复用器就是将文件还原为多个数据文件的机制,二者是相反的过程,由于标准的存在,二者是可逆的操作。被还原成的数据文件(如数据帧、音频等)叫做原始文件。

2.1. 过滤(filtering)

在编码之前,ffmpeg可以利用libavfilter库中的过滤器来处理原始的视频和音频数据帧(这个过程称之为过滤,在最终输出文件之前,对各个产出的数据进行处理,并且这个过程是链式的,想象一个流水线作业,多个过滤器就在该流水线中)。因此,多个过滤链就形成了一个过滤图。ffmpeg可以区分两种过滤器图类型:简单类型(simple filtergraphs)和复合类型(complex filtergraphs)。

通俗解释小贴士:filter主要处理音视频数据的各种特性,诸如视频大小伸缩、添加水印、添加logo、去除logo等。这些操作会在产生最终输出文件的过程中利用过滤器来注入,因此,形象的表示为“过滤”。虽然在命令行中一串指令即可完成需要的输出文件,但是ffmpeg底层是通过libavfilter库来对该过程进行过滤处理。

2.1.1. 简单过滤图(以下使用simple filtergraphs)

simple filtergraphs(简单过滤图)只有一个相同类型的输入和输出。可以通过简单地在编码和解码之间插入一个步骤来表示,如下图:

simple-filtergraphs.png

simple filtergraphs(简单过滤图)通过使用-vf或者-af别名选项来指定,-vf用于视频选项,展开vf为video filter,同理-af为audio filter。

由此可见,过滤操作就是在输入和输出之间插入的过程,这个过程可以对数据帧做调整,然后再次按照容器格式标准编码进行输出。下图是一个简单的对视频进行伸缩的过程:

scale.png

注意:有些过滤器会改变帧的属性,但是不会改变帧的内容,比如fps过滤器,它改变了帧数,却不改变帧内容。

小贴士:simple filtergraphs是只有一个输入和输出的过滤图。

2.1.2. 复杂过滤图(complex filtergraphs)

复杂过滤图在一个流中,不能描述为一个简单的过滤链的线性处理过程。它相比于simple filtergraphs要复杂,不再是单一的输入和输出了,它接受多个输入和产生多个输出。如下图:

complex-filter-graph.png

complex filtergraphs(复杂过滤器)使用-filter_complex选项来配置。请注意,这个选项是全局的,因此,它不能与单个的流或者文件相关联。-lavfi选项等同于-filter_complex选项。

小贴士:复杂过滤器由多个输入和输出,通过-filter_complex选项来指定,该选项是全局的,不能和单个的流或者文件关联。

2.2. 流拷贝(Stream copy)

流复制对于更改容器格式或者修改容器级别的元数据很有用。它使ffmpeg省略了指定流的编码和解码的步骤。其过程如下图:

stream-copy.png

因为省略流编码解码过程,该过程将会非常快速,并且没有质量的损失。然而,由于很多其他因素,可能会失败。而且无法提供过滤器,过滤器的过程需要未压缩的数据。

3. 流的选择(Stream selection)

默认情况下,ffmpeg只包含输入文件中存在的每种类型的一个流(video/audio/subtitle),并将它们添加到每个输出文件。它根据以下标准选择最好的:

1. 对视频而言,选择最高分辨率的流;
  2. 对音频而言,选择具有最多频道的流;
  3. 对字幕而言,选择第一个字幕流;
  4. 在相同类型的几个流速率相同的情况下,选择索引最低的一个流。

你可以使用-vn/-an/-sn/-dn选项来禁用这些默认项。对于完全地手动控制,可以使用-map选项来指定,该选项会禁用前面描述的默认项。

4. 选项(Options)

如果没有另外指定,所有的数值选项接受一个表现为数字的字符串作为输入,后面跟上国际单位制,如“K”、“M”、“G”等单位后缀。比如:1M,1K,1G等,如果在单位前缀中加入了i,ffmpeg将会解释为二进制的倍数,比如1KB=1000Byte,1KiB=1024Byte

不带参数的选项是布尔选项,这会设置相应的值为true,也可以在参数前面添加no前缀来设置为false,比如“-foo”和“-nofoo”

4.1. 流说明符

格式:

stream_index
    #通过索引来匹配,如:-threads:1 4

stream_type[:stream_index]
    # 通过类型/类型+索引来匹配,流类型由v/V(视频)、a/A(音频)、s(字幕)、d(数据)、t(附件)。
    # v匹配所有视频流,V仅仅匹配没有附加图片的视频,如视频缩略图或者封面艺术图片。
    # 如果stream_index被指定了,它将匹配该类型的指定索引的流。否则将匹配所有该类型的流。

p:program_id[:stream_index]
    # 如果指定了stream_index,将会在指定节目id的节目中匹配指定stream_index的流。否则,将匹配所有在该节目中的流。
    
stream_id 或者 i:stream_id
    # 通过流id匹配流。

m:key[:value]
    # 使用具有指定值的元数据标签键匹配流,如果没有指定值,则匹配包含具有任意值的给定标签的流。

u
    # 匹配可用配置的流,必须定义编解码器,且必须存在的信息,如视频维度、音频采样率。
    # 注意,在ffmpeg中,通过元数据匹配只对输入文件有效。

一些选项应用于每一个流中,比如比特率和编解码器。流说明符用于精确地指定哪一个指定了选项的流属于谁的。流说明符通常是附加到选项名上的一个字符串,它被一个冒号分割。如下:

-codec:a:1 ac3

上述指令中包含了a:1流说明符,这会匹配第二个音频流,a代表audio(音频),1代表索引(从0开始)。因此,它将为第二个音频流选择ac3编解码器。

一个流说明符可以匹配多个流,以便将该选项应用于所有匹配的流。比如:

-b:a 128k

在上述说明符中匹配了所有的音频流(通过省略数字)。

一个空的说明符能匹配所有所有流。比如:

-codec copy
# 或者
-codec:copy

上述指令可以匹配所有流,如流复制一节讲到的,copy不必重新编码。

4.2. 一般选项

以下选项可以在所有ff*工具中共享(如ffmpeg、ffserver、ffplay、ffprobe)。

-L
    # 显示许可(LICENSE)
    
-h,-?,-help,--help [arg]
    # 显示帮助信息,如果在后面给定了参数,那么显示该指定参数的特定帮助信息。
    [arg]的值:
        long
            # 打印除基本工具之外的高级工具选项。
        full
            # 打印完整的选项列表,包括共享选项和编解码器、解复用器、复用器、过滤器等的私有选项。
        decoder=decoder_name
            # 打印给定的解码器名的详细信息。可以使用-decoders选项获取所有的解码器。
        encoder=encoder_name
            # 打印给定编码器名称的详细信息。可以使用-encoders选项获取所有的编码器。
        demuxer=demuxer_name
            # 打印给定解复用器的详细信息。使用-formats选项获取所有解复用器和复用器。
        muxer=muxer_name
            # 打印给定复用器的详细信息。使用-formats选项获取所有复用器和解复用器。
        filter=filter_name
            # 打印给定过滤器的详细信息。使用-filters选项获取所有的过滤器。

-version
    # 显示版本号。
    
-formats
    # 显示可用的容器格式(包括设备)。
    
-demuxers
    # 显示可用的解复用器。
    
-muxers
    # 显示可用的复用器。
    
-devices
    # 显示可用的设备。
    
-codecs
    # 显示所有libavcodec已知的编解码器。
    
-decoders
    # 显示可用的解码器。
    
-encoders
    # 显示可用的编码器。
    
-bsfs
    # 显示可用的比特流过滤器。
    
-protocols
    # 显示可用的协议。
    
-filters
    # 显示可用的libavfilter过滤器。
    
-pix_fmts
    # 显示可用的像素格式。
    
-sample_fmts
    # 显示可用的简单格式。
    
-layouts
    # 显示频道名称和标准频道布局。
    
-colors
    # 显示识别的颜色名称。
    
-source device[,opt1=val1[,opt2=val2]...]
    # 显示输入设备的自动检测源,一些设备可能提供于系统相关的源名称,这些源是不能被自动检测的。
    
-sinks device[,opt1=val1[,opt1=val2]...]
    # 显示输出设备的自动检测接收器。
    
-loglevel [repeat+]loglevel | -v [repeat+]loglevel
    # 设置库使用的日志级别,添加的repeat+表明重复的日志输出不应该被压缩到第一行。
    # loglevel可用值如下:
    quiet, -8
        # 不显示任何信息。
    panic,0
        # 只显示可能导致进程崩溃的致命错误。
    fatal,8
        # 只显示致命错误,这些错误会导致进程无法继续。
        
    error,16
        # 显示所有错误。
        
    warning,24
        # 显示所有警告和错误。
        
    info,32
        # 显示处理过程中的信息。

    verbose,40
        # 同info,除了显示更多交互信息外。
        
    debug,48
        # 显示所有信息,包括调试信息。
        
    trace,56
        # 默认情况下,节目记录到标准错误输出(stderr)。如果终端支持着色,则会标记错误和警告。日志着色可以通过设定“AV_LOG_FORCE_NOCOLOR”环境变量或者“NO_COLOR”来禁用。或者强制设定环境变量“AV_LOG_FORCE_COLOR”。“NO_COLOR”在未来的ffmpeg版本中将被标记为过时的。
        
-report
    # 将完整的命令行和控制台输出到当前的一个文件中,文件自动按照“program-YYYYMMDD-HHMMSS.log”格式命名。这对于bug的报告很有帮助。这个选项隐式地使用了verbose的日志级别。
    
-hide_banner
    # 禁止打印banner。
    # ff*工具会在前几行输出固定的配置信息和库的版本等信息,使用该选项可以禁止打印这些横幅。
    
-cpuflags flags(glogal)
    # 允许设置和清除cpu 标志,该选项用于测试。除非你清楚地知道你在做什么,否则不要使用这个选项。
    # 可能的cpu标志值:
    '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’
        
-opencl_bench
    # 该选项对所有可用的opencl设备进行基准测试,并打印结果。只有使用了--enable-opencl选项编译了ffmpeg后才会生效。

4.3. AV选项

libavformat,libavdevice,libavcodec库直接提供这些选项,使用-help查看详细信息。

4.4. 主要选项

-f fmt(输入 / 输出)
    # 强制输入或者输出文件格式。通常输入文件的格式会被自动检测。然后通过文件扩展名猜测输出文件格式,因此在大多数情况下,该选项不需要显式使用。
    
-i url(输入文件)
    # 输入文件的url。
    
-y(全局)
    # 不通过询问而直接覆盖输出文件。
    
-n(全局)
    # 不覆盖输出文件,如果已经存在同名文件则立即退出。
    
-stream_loop number(输入)
    # 设置输入流应当循环的次数,0意味着不循环,-1意味着无限循环。
    
-c[:stream_specifier] codec (输入/输出,每个流)
-codec[:stream_specifier] codec (输入/输出,每个流)
    # 为一个或者多个流选择一个解码器或者编码器,codec选项是一个编码器或者解码器,或者使用copy来表明这仅仅是流复制,流的复制不需要进行重新编码。如:
    ffmpeg -i input.avi -map 0 -c:v libx264 -c:a copy output.avi # 使用libx264来编码所有的流,并复制音频。
    
-t duration(输入/输出)
    # 当用作输入选项时(-i之前),可以限制从输入文件读取数据的时间。
    # 当用作输出选项时(在输出url之前),到达持续时间后停止写入数据。
    # -t的时间值必须符合时间格式规范。具体参考后面章节。

-to position(输出)
    # 在给定的位置上停止写入数据到输出。position必须符合时间格式规范。具体参考后面章节。
    
-fslimit_size(输出)
    # 设置文件大小限制,使用字节表示。到达字节限制时会停止写入字节数,

-ss position(输入/输出)
    # 当用作输入选项时(-i之前),会在此文件中寻找position指定的位置。注意:在大多数容器格式中,不可能完全寻找到,所以ffmpeg会寻求距离position最近的点。
    # 用作输出选项时(在输出url之前),解码,但是会丢弃输入,直到时间戳抵达position。同样的,position依然是时间格式。
    
-sseof position(输入/输出)
    # 这个选项于ss相似,但是相对于文件结束符(eof=end of file),

-itsoffset offset(输入)
    # 设置输入的时间偏移量。
    # offset必须是一个时间段偏移量。偏移量会被添加到输入文件的时间戳中。指定了正的偏移量意味着相应的流被延迟了偏移量设定的时间段。
    
-timestamp date(输出)
    # 在容器中设置录制时间戳。
    # date必须是一个日期格式规范。
    
-metadata[:metadata_specifier] key=value(输出,每个metadata)
    # 设置元数据键值对。
    # 可选的元数据说明符(metadata_specifier)可以用来设置流/章节/节目上的元数据。
    # 例如:
        ffmpeg -i input.avi -metadata title="my title" out.flv # 这串指令用于设置输出文件的标题元数据。
        
        ffmpeg -i input.avi -metadata:s:a:0 language=eng out.flv # 设置该流的第一个音频的语言。
        
-disposition[:stream_specifier] value(输出,每个流)
    # 该选项会从输入流中复制配置,并且覆盖输出流。可以通过设置其值为0来删除这个设置。
    # 以下是disposition的枚举值:
    default
    dbd
    original
    comment
    lyrics
    karaoke
    forced
    hearing_impaired
    visual_impaired
    clean_effects
    captions
    descriptions
    metadata
    如:
    ffmpeg -i in.mkv -disposition:a:1 default out.mkv # 将第二个音频设置为default
    
    ffmpeg -i INPUT -disposition:s:0 0 -disposition:s:1 default OUTPUT # 将第二个字幕流设置为默认,从第一个字幕流中移除默认配置。
    
-program [title=title:][program_num=program_num:]st=stream[:st=stream...](输出)
    # 创建具有指定标题和program_num(节目编号)的节目。并将指定的流添加到其中。
    
-target type(输出)
    # 指定目标文件类型(vcd、svcd、dvd、dv、dv50),这些类型可能会加上pal-、ntsc-或者filem-前缀以使用相应的标准,然后自动地设置格式选项。如:
    ffmpeg -i input.avi -target vcd /tmp/vcd.mpg
    
-dframes number(输出)
    # 设置要输出的数据帧数量。这是一个过时的别名,它真是的样子是这样的:-frames:d,你应该使用这个来替代。
    
-frames[:stream_specifier] framecount(输出,每个流)
    # 在到达给定的帧数量后停止写入流。
    
-q[:stream_specifier] q (输出,每个流)
-qscale[:stream_specifier] q (output,per-stream)
    # 使用固定质量标尺。
    
-filter[:stream_specifier] filtergraph(输出,每个流)
    # 根据指定的filtergraph创建filtergraph。并用其过滤流。
    
-filter_script[:stream_specifier] filename (输出,每个流)
    # 该选项于-filter相似。
    
-filter_threads nb_threads (全局)
    # 定义了使用多少个线程用于处理过滤器管道。每个管道会产生一个线程池用于并行处理。默认是可用的cpu核心数。
    
-pre[:stream_specifier] preset_name (输出,每个流)
    # 为匹配的流预设。
    
-stats(全局)
    # 打印编码的进度和统计信息。该选项默认开启,如果要禁用它使用-nostats。
    
-process url(全局)
    # 发送进度信息到url。大约每秒写入一次。
    
-stdin
    # 在标准输入中启用交互,该选项默认启用,要禁用使用-nostdin。
    
-debug_ts(全局)
    # 打印时间戳信息。该选项默认禁用。调试于测试使用该选项非常有用。
    
-attach filename(输出)
    # 添加一个附件到输出文件,该选项仅有少量的格式支持。比如添加一个字体文件用于渲染字幕的字体。这个附件被实现为一个特定的流。所以,该选项会往文件中添加一个流。如:
    ffmpeg -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.flv # 注意:我们依然需要将metadata指定mime映射。
    
-dump_attachment[:stream_specifier] filename (输入,每个流)
    # 提取匹配的附件流到指定的文件中,文件名由filename指定。
    # 如,提取第一个附件到文件,命名为out.tff:
    ffmpeg -dump_attachment:t:0 out.tff -i INPUT
    
    # 如,提取所有附件到文件中:
    ffmpeg -dump_attachment:t "" -i INPUT
    
-noautorotate
    # 基于文件元数据禁用视频旋转。

4.5. 视频选项

-vframes number(输出)

# 设置视频帧数到输出文件,该选项已过时,它是-frames:v的别名。你应当使用这个选项。

-r[:stream_specifier] fps(输入、输出、流)

# 设置帧速率,单位为Hz或者分数。
# 该选项作为输入选项时,忽略所有存储于文件中的时间戳,并以固定不变的帧速率生成时间戳。
# 作为输出选项时,复制或删除输入帧以实现不变输出帧速率fps。

-s[:stream_specifier] size (输入、输出、流)

# 设置帧大小。
# 用作输入选项时,它是video_size私有选项的快捷方式。
# 用作输出选项时,它将缩放视频过滤器插入相应过滤图的尾部。

-aspect[:stream_specifier] aspect (输出、流)

# 设置由aspect指定的视频显示宽高比例。
# aspect是一个浮点数的字符串,或者是形如num:den的字符串。视频显示宽高比中,num代表分子,den代表分母。

-vn(output)

# 禁用视频录像。

-vcodec codec(输出)

# 设置视频编解码器,它是-codec:v的别名。

-pass[:stream_specifier] n(输出、流)


-vf filtergraph(输出)

通过指定的filtergraph名创建filtergraph,它是-filter:v的别名。

4.6. 视频高级选项

-pix_fmt[:stream_specifier] format(输入、输出、流)

# 设置像素格式。使用-pix_fmts查看所有支持的像素格式。如果像素格式不能被选择,ffmpeg会打印警告信息,然后选择编码器支持的最佳像素格式。

-sws_flags flags(输入、输出)

# 设置SwScaler的flags。

-vdt n

# 丢弃阈值。

-rc_override[:stream_specifier] override(输出、流)


-ilme

# 在编码器中强制隔行扫描(仅支持mpeg-2、mpeg-4),如果你的输入文件是隔行扫描的,并且想保持最低损失的隔行格式,请使用该选项。
# 另一个选择是使用-deinterlace选项来逐行扫描输入流。

-psnr

# 计算压缩帧的PSNR。

-vstats

# 将视频编码统计信息转存到vstats_HHMMSS.log文件中。

-vstats_file file

# 将视频编码信息转存到指定文件中。

-vstats_version file

# 指定使用哪一个vstats格式版本,默认为2。
# version = 1:
    frame= %5d q= %2.1f PSNR= %6.2f f_size= %8.9fkb time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s
    
# version > 2:
    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(输出、流)

# top=1/bottom=/auto=-1

-dc precision

# Intra_dc_precision

-vtag fourcc/tag (输出)

# -tag:v的别名,强制视频使用tag/fourcc。

-qphist(全局)

# 显示QP直方图。

-vbsf bitstream_filter

# 已过时

-force_key_frame[:stream_specifier] time[,time...](输出、流)
-force_key_frame[:stream_specifier] expr:expr(输出、流)

# 强制指定时间戳的关键帧,更确切地讲,是指定时间之后的第一帧。如果参数带有expr前缀,该字符串会被解释为一个表达式,在每一帧的时候会被计算。
# 如果添加了chapter [delta]选项,将会扩展到文件中所有chapter的开始。如:
-force_key_frames 0:05:00,chapters-0.1

-copyinkf[:stream_specifier](输出、流)

# 当进行流复制时,复制一些非关键帧。

-init_hw_device type[=name][:device[,key=value...]]

# 使用给定的设备参数初始化一个新的类型名称为name参数的硬件设备。如果没有指定name参数的值,则默认会接受一个格式为tyoe%d的默认name。
# 设备含义和以下参数依赖于设备类型:
cuda
    # device是CUDA设备号。
    
dxva2
    # device是Direct3D 9的显示适配器。
    
vaapi
    # device是X11显示名称或者DRM渲染节点。如果未指定,将会尝试打开默认的X11($DISPLAY),以及第一个DRM渲染节点(/dev/dri/renderD128)。
    
vdpau
    # device是X11的显示名称,如果未指定,将会尝试打开默认的X11显示($DISPLAY)。
    
qsv
    # device在“MFX_IMPL_”为前缀的值中选择一个值,我们写为"MFX_IMPL_*",用*代表所有可能的值。允许的值如下:
    auto
    sw
    hw
    auto_any
    hw_any
    hw2
    hw3
    hw4
    
    # 如果为指定这个值,“auto_any”将会成为默认选择被使用。

-init_hw_device type[=name]@source

# 初始化一个新的类型的硬件设备,类型名称由name值指定。

-init_hw_device list

# 列出ffmpeg支持的所有硬件设备类型。

-filter_hw_device name

# 发送名为name的硬件设备到任意过滤图中的所有过滤器。

-hwaccel[:stream_specifier] hwaccl(输入、流)

# 使用硬件加速器解码匹配到的流,可识别的accl值如下:
none
    # 不使用任何硬件加速器(默认)。
    
auto
    # 自动选择硬件加速器。
    
vda
    # 使用Apple硬件加速器。
    
vdpau
    # 使用vdpau硬件加速器(Video Decode and Presentation API for Unix)。
    
dxva2
    # 使用dxva2硬件加速器(DerictX Video Acceleration)。
    
vaapi
    # 使用vaapi硬件加速器(Video Acceleration API)。
    
qsv
    # 使用intel QuickSync Video Acceleration为视频转码。不同于其他选项值,该选项不启用加速解码(每当qsv解码器被选择时,都会自动使用),除了加速转码。

-hwaccl_device[:stream_speficier] hwaccl_device(输入、流)

# 选择要用于硬件加速的设备。

-hwaccels

# 列出ffmpeg支持的所有硬件加速器。

4.7. 音频选项

-aframes number (输出)

# 设置要输出的音频帧数。该选项已经过时,它是-frames:a的别名,你应当使用这个来替代。

-ar[:stream_specifier] freq (输入、输出、流)

# 设置音频采样率。

-aq q (输出)

# 设置音频质量,它是-q:a的别名。

-ac[:stream_specifier] channels (输入、输出、流)

# 设置音频通道数,对于输出流来说,它被默认设置为输入流的通道数。对于输入流来说,该选项适用于音频抓取设备和原始解复用器。

-an (输出)

# 禁用音频录音。

-acodec codec (输入、输出)

# 设置音频编解码。它是-codec:a的别名。

-sample_fmt[:stream_specifier] sample_fmt (输出、流)

# 设置音频采样格式。可以使用-sample_fmts获取受支持的所有格式列表。

-af filtergraph (输出)

# 使用给定的filtergraph创建一个filtergraph,并将这个filtergraph应用于流。该选项是-filter:a的别名。

4.8. 高级音频选项

-atag fourcc/tag (输出)

# 强制音频tag/fourcc。该选项是-tag:a的别名。

-absf bitstream_filter

# 过时。

-guess_layout_max channels (输入、流)

# 如果一些输入通道布局是未知的,只能在指定最多通道数的时候尝试猜测。

4.9. 字幕选项

-scodec codec(输入、输出)

# 设置字幕的编解码器,该选项是-codec:s的别名。

-sn(输出)

# 禁止字幕录制。

-sbsf bitstream_filter

# 过时。

4.10. 高级字幕选项

-fix_sub_duration

# 修复字幕持续时间。对于每一个字幕而言,等待相同流中的下一个数据包,并调整第一个数据包的持续时间以避免字幕重叠。这对于一些字幕的编解码器是非常必要的,尤其是DVB字幕,因为在原始的数据包中的持续时间只是一个粗略估算的值,

-canvas_size size

# 设置用于渲染字幕画布的大小。

4.11. 高级选项

-map [-]input_file_id [:stream_specifier][?][,sync_file_id[:stream_specifier]] | [linklabel](输出)

# 指定一个或者多个输流作为输出文件的源,每一个输入流都由输入文件的input_file_id索引标识,输入流的id存在与输入文件中。所有的索引都从0开始。
# 第一个选项-map指定第0个输出流的源,第二个-map选项指定第1个输出流的源,等等。理解-map选项最好的方式就是考虑这样一种方式:告诉ffmpeg你想从输入当中选择/复制哪个流到输出中去。下面举几个例子:

# 默认
ffmpeg -i INPUT OUTPUT # 当没有指定map时,这是默认行为。从本质上讲,上述指令的行为是从所有输入中“发现最高质量(单个)”的视频输入流和“最高质量的(单个)”音频输入流,并将它们发送到输出,原则上讲,所有其他输入流被丢弃,默认行为只选择最高质量的流。

# map选项基本上意味着:将此流包含进随后的输出文件中。如果我们想要使用-map选项显示出相同的行为,那么它看上去像是这样的:
ffmpeg -i INPUT -map single_highest_quality_video_stream_from_all_inputs -map single_highest_quality_audio_stream_from_all_inputs OUTPUT
# 因此,如果你想要选择从输入当中选择不同的流或者选择多个流,你会使用map的这个特性。

# 例子1,从输入文件中映射所有流到输出:
ffmpeg -i INPUT -map 0 OUTPUT

# 例子2,如果在输入文件中有两个音频流,那么这些流标记为0:0,0:1。你可以使用-map选择哪一个流输出到输出文件中:
ffmpeg -i INPUT -map 0:1 OUTPUT.wav

# 例子3,从输入文件a.mov中选择索引为2的流(通过标识0:2指定),从输入文件b.mov中选择索引为6的流(通过标识1:6指定),将二者复制到输出文件out.mov中:
ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov

# 例子4,从一个输入文件中选择所有视频流和第三个音频流,并输出到指定的OUTPUT:
ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT

# 例子5,映射除了第二个流外的所有流,使用排除映射(通过在-map选项的值前面添加-前缀来排除匹配到的流):
ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT # -0:a:1排除了第2个音频流。

# 例子6,从第一个输入中映射视频和音频流,并且使用?来跟踪,?作为-map选项值的后置,意味着当标记了?的规则不存在时,则忽略这个错误:
ffmpeg -i INPUT -map 0:v -map 0:a? OUTPUT # 如果第一个音频流不存在,则忽略。

# 例子7,选择语言为英语的音频流:
ffmpeg -i INPUT -map 0:m:lanaguage:eng OUTPUT

-ignore_unknown

# 当尝试复制流时失败,则忽略未知类型的输入流。

-copy_unknown

# 尝试复制流时出现故障,则允许使用位置类型的输入流被复制。

-map_channel [input_file_id.stream_specifier.channel_id | -1][?][:output_file_id.stream_specifier]

# 从给定的输入映射一个音频通道到输出。如果为给定output_file_id.stream_specifier,那么音频轨道从所有音轨上映射。使用-1替代input_file_id.stream_specifier.channel_id将会映射一个静音通道。
# 以?结尾将允许map_channel成为可选的:如果map_channel没有匹配到通道,那么map_channel将会被忽略,而不是抛出一个错误,

# 例子1,假设输入文件是一个立体声音频文件,你可以使用如下指令交换两个音频通道:
ffmpeg -i INPUT -map_channel 0.0.1 -map_channel 0.0.0 OUTPUT
# 如果你想使第一个通道静音,保留第二个通道,那么你可以(上面提到的使用-1提到-map_channel的值可以使其静音):
ffmpeg -i INPUT -map_channel -1 -map_channel 0.0.1 OUTPUT

# -map_channel选项的顺序决定了输出流中的音频通道顺序。输出的通道布局会从映射到的通道数中猜测(如果只有一个-map_channel选项则判定为单声道,两个则为立体声等)。

# 你也可以提取每一个输入通道到指定的输出中;以下指令从输入的音频流(文件0,流0)中提取了两个通道到输出的各自通道中(分别是OUTPUT_CH0和OUTPUT_CH1):
ffmpeg -i INPUT -map_channel 0.0.0 OUTPUT_CH0 -map_channel 0.0.1 OUTPUT_CH1

# 例子1,以下例子分离了立体声输入的通道为两个分别的流,并将这两个分离的流放到同一个输出文件中:
ffmpeg -i stereo.wav -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 -y out.ogg

# 注意:当前每一个输出流只能包含单一输入流中的通道;你不能使用-map_channel选项来挑选不同流中的多个输入音频通道,并且将它们合并到一个输出流中。因此,目前也就不可能从两个不同的单声道流转换为一个立体声流。然而,将一个立体声流分离成两个单声道流是可能的。

#如果需要上述功能,可以使用amerge过滤器来实现。比如,如果你要将2个单声道音频流合并到一个立体声道的音频流中(并且保留视频流),你可以使用以下指令:
ffmpeg -i input.mkv -filter_complex "[0:1] [0:2] amerge" -c:a pcm_s16le -c:v copy output.mkv

# 为了从第一个输入映射前两个音频通道,使用?后缀,如果第一个输入是单声道,那么忽略音频通道映射:
ffmpeg -i INPUT -map_channel 0.0.0 -map_channel 0.0.1? OUTPUT

-map_metadata[:metadata_spec_out] infile[:metadata_spec_in](输出、元数据)

# 根据infile设置下一个输出文件的元数据信息。可选的metadata_spec_in/out参数指定了哪一个元数据需要被复制。元数据的说明符可以具备如下的形式:
g
    # 全局元数据,即应用到整个文件的元数据信息。
    
s[:stream_spec]
    # 单个流的元数据。stream_spec是一个流说明符。在一个输入流元数据说明符中,第一个匹配到的流会被复制。在输出元数据说明符中,将复制所有匹配的流。
    
c:chapter_index
    # 单个章节的元数据。chapter_index是一个从0开始的索引。
    
p:program_index
    # 单个节目的元数据。同样的,program_index也是一个从0起始的索引。
    
# 如果元数据说明符被省略了,默认的说明符为g,即全局。
# 默认情况下,全局的元数据是从第一个输入文件中复制的,每个流和每个章节的元数据是随着流/章节来复制的。这些默认映射通过创建相应类型的映射来禁用。使用负的文件索引值可以创建一个假的映射,这样会禁用自动映射。
# 例子,从输入文件的第一个流中复制元数据到输出文件的全局元数据:
ffmpeg -i in.ogg -map_metadata 0:s:0 out.mp3

# 例子2,反过来,即从全局元数据复制到所有音频流:
ffmpeg -i in.mkv -map_metadata:s:a 0:g out.mkv

-map_chapters input_file_index(输出)

# 从输入文件以input_file_index索引为准复制章节到下一个输出文件。如果没有指定章节映射,那么从第一个输入文件中至少复制一个章节。使用负的文件索引来禁用章节复制。

-benchmark(全局)

# 在编码结束后显示基准信息。显示CPU使用时间、最大内存消耗。并不是所有的系统都支持最大内存消耗,如果不支持则显示0。

-benchmark_all(全局)

# 在编码期间显示基准信息。显示用于音频/视频的编解码所消耗的CPU使用时间。

-timelimit duration(全局)

# ffmpeg运行了指定的duration时间后退出。

-dump(全局)

# 转储每个输入数据包到标准错误。

-hex(全局)

# 当转存数据包时,也转存有效载荷。

-re(输入)

# 以原始帧速率读取输入。主要用于模拟抓取设备,或者现场直播的输入流。请注意这是模拟,真实环境中捕获设备或者直播流不应该使用这个选项(它会导致丢失数据包)。默认地,ffmpeg尝试尽快地读取输入。该选项会降低输入的读取速率到原始帧数率速度。这对于即时输入很有用(比如直播)。

-loop_input

# 循环输入流。目前只适用于图像流。该选项用于ffserver自动测试。该选项已经废弃,请使用-loop 1。

-loop_output number_of_times

# 根据number_of_times规格反复循环输出。该选项过时,请使用-loop。

-vsync parameter

# 视频同步方式。为了兼容问题,老版本可以使用数字指定。新版本必须指定为字符串。
0,passthrougth
    # 从解复用器到复用器的每一帧,连同其时间戳一起传送。
    
1,cfr
    # 复制并且丢弃帧,以达到所要求的恒定帧速率。
    
2,vfr
    # 连同时间戳一起传送帧或者移除。以防止存在相同时间戳的帧。
    
drop
    # 传递,移除所有时间戳。使得基于帧速率的复用器产生新的时间戳。
    
-1,auto
    # 根据复用器的功能从1和2之间选择。
    
# 注意,过后,时间戳可能进一步被复用器修改。

-frame_drop_threshold parameter

# 丢弃帧的阈值,其指定了丢弃视频帧之前可以保留多少视频帧,在帧速率单位中,1.0指的是1帧。默认是-1.1

-copyts

# 不处理输入的时间戳,但是保留其值,而不是清除它们。不要删除起始时间的偏移值。

-start_at_zero

# 当和-copyts一起使用时,转移时间戳,使其从0开始。
# 如,-ss 50 将会使输出时间戳从第50秒开始,而不管输入文件的起始时间戳。

-copytb mode

# 当进行流复制的时候,指定如何设置编码时基。mode是一个数字类型的值,它可以是以下数字中的一种:
1
    # 使用解复用器时基。
    # 从相应的输入解复用器中复制时基到输出编码器。

0
    # 使用解码器时基。
    # 从相应的输入解码器复制时基到输出编码器。
    
-1
    # 尝试自动地选择,以产生一个智能的输出。

# 默认值是-1。

-enc_time_base[:stream_specifier] timebase (输出、流)

# 设置编码器时基。timebase是一个浮点数,可以是以下值:
0
    # 根据媒体类型分配一个默认值。
    # 对于视频而言,使用1/帧速率,对于音频而言,使用1/采样率。
    
-1
    # 如果可能,使用输入流时基。
    # 如果输入流不可用,那么默认的时基将会启用。
    
>0
    # 使用提供的数字作为时基。
    # 这个字段可以是两个数字的比值(比如1/24),或者是一个浮点数。
    
# 默认情况下是0。

-shortest(输出)

# 当最短输出流结束时,完成编码。

-dts_delta_threshold

# 时间戳中断增量阈值。

-muxdelay seconds (输入)

# 设置最大解复用器解码延迟。

-muxpreload seconds (输入)

# 设置解复用器解码器初始延迟。

-streamid output-stream-index:new-value (输出)

# 分配一个新的流id给输出流。
# 例子:
ffmpeg -i input -streamid 0:33 -streamid 1:36 output.ts

-bsf[:stream_specifier] bitstream_filters (输出、流)

# 为匹配的流设置比特流过滤器。
# 例子:
ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264

-tag[:stream_specifier] codec_tag(输入/输出、流)

# 强制tag/fourcc匹配流。

-timecode hh:mm:ssSEPff

# 为写入指定时间代码。

-filter_complex filtergraph (全局)

# 定义一个负责过滤器,即:一个具有任意数量的输入和(或者)输出。
# 对于简单图来说,它们是具有相同类型的一个输入和一个输出。

-filter_complex_threads nb_threads (全局)

# 定义使用多少个线程来处理filter_complex图。默认是可用cpu数。

-lavfi filtergraph (全局)

# 定义复杂过滤图。

-filter_complex_script filename (全局)

# 该选项和-filter_complex相似,不同的是,它的参数是一个文件名。

-accurate_seek (输入)

# 该选项使用-ss选项启用或者禁用在输入文件中的精确查找。默认是启用的。使用-noaccurate_seek来禁用。

-seek_timestamp (输入)

# 该选项使用-ss选项禁用或者启用在输入文件中通过时间戳来查找的功能。默认禁用。

-thread_queue_size size (输入)

# 当从设备或者文件读取时,该选项设置最大队列数。

-override_ffserver (全局)

# 覆盖ffserver的输入规范。使用该选项可以映射任意输入流到ffserver中,从ffmpeg中控制许多编码的方面。

-sdp_file file (全局)

# 打印一个输出流的sdp信息到file中。

-discard(输入)

# 用于在解复用器处丢弃指定的流或者帧。不是所有解复用器都支持该选项。可用值如下:
none
    # 丢弃不存在的帧。

default
    # 默认值,即上述的none。
    
noref
    # 丢弃所有非引用帧。
    
nokey
    # 丢弃除关键帧外的所有帧。
    
all
    # 丢弃所有帧。

-abort_on flags(全局)

# 在多条件下停止并且退出。flags值如下:
empty_output
    # 无数据包传递给复用器,输出是空。

-xerror(全局)

# 当错误时,停止并退出。

-max_muxing_queue_size packets (输出、流)

# 当进行音频或者视频转码的时候,ffmpeg不会开始写入数据到输出,直到每个这样的流有一个数据包。当等待其发生时,  流的数据包将会被缓存。该选项设置了匹配的流的缓存的大小。

4.12. 预设文件

一个预设文件包含了option=value键值对的一个序列,每行一个,#符号开头被作为注释处理。预设文件有两种:ffpreset和avpreset文件。

4.12.1. ffpreset文件

ffpreset文件使用vpre、apre、spre、fpre来指定。fpre选项将预设文件名来替代预设名作为输入,并且可以被所有编解码使用。对于vpre、apre、spre选项来说,这些在预设文件中指定的选项被应用于当前选择的相同类型的编解码器作为预设选项。

传递给vpre、apre、spre预设选项的参数根据以下规则识别要使用的预设文件:

首先,ffmpeg从$FFMPEG_DATADIR(环境变量)目录和$HOME/.ffmpeg目录下查找的一个名为arg.ffpreset的文件。

4.12.2. avpreset files

使用pre选项指定avpreset文件。这和ffpreset文件工作原理很相似,除了仅允许编码器特定的选项。因此,不能使用指定了编码器的键值对选项。

当指定pre选项时,ffmpeg将在目录$AVCONV_DATADIR(如果设置了)和$HOME/.avconv以及在配置时定义的datadir(通常为PREFIX/share/ffmpeg)中查找后缀为.avpreset的文件,按照上述顺序。

首先,ffmpeg会在上述提到的目录中查找名为codec_name.avpreset的文件,其中,codec_name是要应用预设文件选项的编码器的名称。比如,如果使用-vcode libvpx选择视频,使用-pre 1080p。


  1. 容器格式:诸如avi,mp4等格式,专业上称之为容器格式。在后面章节会讲解视频的组成原理和容器格式。

  2. 比特率:单位,bit/s,指每秒传送的比特(bit)数。比特率越高,传输的数据越大,速度越快。在音视频中的比特率是指模拟信号转换为数字信号后单位时间内传输的二进制数据量。通常用该指标衡量声音和视频文件的质量。

  3. 帧数率:单位,fps(frame per second - 每秒帧数),是指每秒刷新的图片数量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 这是一封在隔离区里的母亲写给远在他乡儿子的信。就打出来看看吧,在战争年代母亲在要被处死的前一段时间对儿子的思念。 ...
    宝宝脚抽筋阅读 281评论 0 0
  • 交作业了,落了好多。抓紧补上一
    myselfliya阅读 181评论 2 3