[总结]FFMPEG命令行工具之ffmpeg详解

目录

1 语法 Synopsis

2 描述 Description

3 详细描述 Detailed description

3.1 滤镜 Filtering

3.1.1 简单滤镜图 Simple filtergraphs

3.1.2 复杂滤镜图 Complex filtergraphs

3.2 流拷贝 Stream copy

4 流选取 Stream selection

4.1 描述 Description

4.1.1 自动流选取 Automatic stream selection

4.1.2 手动流选取 Manual stream selection

4.1.3 复杂滤镜图 Complex filtergraphs

4.1.4 流处理 Stream handing

4.2 示例

示例:自动流选取

5 命令选项以及示例



1 语法 Synopsis


ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

注意一点:可以有多个输入,多个输出

2 描述 Description


ffmpeg是一个非常快速的音频,视频转换器,不仅可以转换本地音视频,并且可以直接转换在线的音频视频源。还可以通过高质量的滤镜转换不同采样率的音频,不同分辨率的视频。

ffmpeg可以读取多个输入文件(可以使常规的磁盘文件,管道,网络流,采集设备),可以由选项-i来指定输入文件,并将结果写入多个输出文件,输出文件由输出url指定。任何命令行中的参数如果无法被解释为选项option将被当做输出文件url。

每个输入输出url原则上可以包含任意个数不同类型的流(视频,音频,字幕,数据,附属)。被允许的流个数和类型最终取决于封装容器格式。选择哪个输入流映射到哪个输出流要么是被ffmpeg自动处理,要么可以通过-map选项来指定

要命令行中选项中引用输入文件,可以使用它们的下标指数(从0开始,依次类推),比如第一个文件是0,第二个文件是1,等等。类似的,文件中的流的引用也可以使用下标指数。比如2:3引用了第3个输入文件中的第4个流。进一步可以查看 “流选择”章节内容。

作为一般化的规则,选项都作用于下一个特定的文件。顺序是非常重要的,因为同一个选项可以在一个命令行中出现多次。每次选项出现是作用于下一个输入文件或者是输出文件。特例是全局选项,这个应该在最开始指定。

不要混淆输入和输出文件-------一开始指定所有的输入文件,然后才是所有的输出文件。不要混淆作用于不同文件的选项。所有选项仅仅作用于下一个输入或者输出文件,然后就被重置了。

      示例:

  •    设置视频的比特率为64kbit/s               ffmpeg -i 1.mp4 -b:v 64k output.mp4
  •    强制视频的帧率为24fps                      ffmpeg -i 1.mp4 -r 24 output.mp4
  •    强制输入文件帧率为1fps,输出文件的折率为24fps              ffmpeg -r 1 -i 1.mp4 -r 24 output.mp4 

3 详细描述 Detailed description


ffmpeg中的对于每个输出文件的转码过程可以使用下图表示:

ffmpeg调用libavformat库(该库包含解封装器demuxers)去读取输入文件,获取文件中编码过的数据包。当存在多个输入文件时,ffmpeg将根据所有输入流中的最低时间戳来保持同步。

编码过的数据包将进一步被传递给解码器(除非采用流复制的方式,即不改变流的编码方式)。编码器将编码过的数据包packets解码后产生数据帧frames(包括原始的视频采样数据,音频pcm采样数据...),这些数据帧还可以进一步的被滤镜处理。滤镜处理后的数据帧将被传递给编码器,编码器对数据帧进行编码,形成新的编码后的数据包packets。最终编码后的数据包传递给封装器muxer,按照文件格式要求写入到输出文件中。

3.1 滤镜 Filtering


在原始音频帧数据被编码前,ffmpeg可以使用libavfilter中的滤镜对其进行处理。滤镜图(filtergraphs)由几个滤镜链(chained filters)组成,ffmpeg中区分两种类型的滤镜图:简单和复杂的

3.1.1 简单滤镜图 Simple filtergraphs


简单的滤镜图是指处理只有一个输入文件和一个输出文件,并且二者有同样类型。在上图中,简单滤镜图表演的角色就是在解码和编码之间插入一个额外的步骤:

简单滤镜图配置为一个流一个filter选项(-vf视频滤镜,-af音频滤镜,-sf字幕滤镜)。一个视频的简单滤镜图像如下图展示的这样:

注意一些滤镜会改变帧属性但是不会改变帧内容。比如fps滤镜将改变帧的数量,但是不会去修改一帧数据中存储的内容;又比如setpts滤镜,仅仅会修改帧的时间戳,然后就完成了这帧数据的处理而没有改变帧内数据。

3.1.2 复杂滤镜图 Complex filtergraphs


复杂滤镜图用于对一个流的处理不能使用简单线性处理链(即挨个使用滤镜就能完成的功能)。比如,当过滤图含有多个输入或者输出是,或者输出流的类型与输入不一致。复杂滤镜图可以用下图表示:

复杂滤镜图的使用可以利用。注意这个选项是全局的,因为复杂滤镜图天然就是不会二义性的关联到单个流或者是文件。

选项-lavfi和-filter_complex是等价的。

用来展示复杂滤镜图的常用例子就是overlay滤镜,这个滤镜有两个视频输入和一个视频输出,这个视频输出就其中一个输入放置再另一个输出上面得来的。音频滤镜中相似的就是amix滤镜。

3.2 流拷贝 Stream copy


流拷贝是一种模式选择,可以通过选项-codec加参数copy实现。允许ffmpeg对特定的流跳过解码和编码的环节,只进行解封装和再封装。这种操作对于改变容器格式或者是改变容器级别的metadata非常有用。上面的流程图,在这种情况下,就可以简化为下图:

既然不存在解码和编码,那么流拷贝将非常快,并且没有质量损失。然而,在某些情况下因为一些因素无法正常工作。总之,使用滤镜是非常重要的,因为滤镜工作于非压缩数据这个层级。

4 流选取 Stream selection


ffmpeg提供了-map选项来实现手动控制每个输入文件的流选取。用户也可以跳过-map选项让ffmpeg自动进行流选取。-vn/-an/-sn/-dn选项可以用来跳过包含的视频,音频,字母,数据流,不管是手动映射还是自动选取,除非这些流是作为复杂滤镜输出项。

4.1 描述 Description

下面的子章节将描述流选取中各种不同的规则。下面的例子将展示在实际中利用这些规则。每种效果精确的反应了软件的行为,而ffmpeg还处于持续的开发中,因此,代码会随着时间变化,以下描述也可能会有不同。

4.1.1 自动流选取 Automatic stream selection


在没有使用任何map选项时,ffmpeg会根据输出容器格式去检查流的类型看是否能被封装进来,视频,音频,字幕的格式将都被考虑到。对于所有能接受的流类型,ffmpeg将会从所有输入文件中选择其中一个可以获取的流。

选取流的规则基于以下标准:

  • 对于视频,将选择分辨率最高的流,
  • 对于音频,将选择通道数最多的流,
  • 对于字幕,将选择第一个被找到的字幕流,但是还有一个附加的说明。输出文件格式默认字幕编码器可以是基于文本的或者是基于图像的,只有字幕流是相同类型的才会被选取。
  • 当几个流类型相同,基本上无差别,那么将选取index最低的那个。
  • 数据和附加流不能被自动选择,只能使用-map来手动选择。

4.1.2 手动流选取 Manual stream selection


当使用-map选项时,只有映射中的流会被包含进输出文件,只有一种例外,下面将描述。

4.1.3 复杂滤镜图 Complex filtergraphs


如果复杂滤镜图的输出流没有标明归属,他们将被加入到第一个输出文件中。这种情况,如果输出文件格式不支持这种流格式的话将会导致致命错误。如果没有使用-map选项,这些流将被自动选择,根据他们的流类型是否合适进行跳过。如果使用了-map选项,这些滤镜图流将会跟映射的流一起被包含进去。

复杂滤镜图中带标签的输出流必须被映射一次且只能被映射一次。

4.1.4 流处理 Stream handing


流的处理和流的选取是独立的,除了字幕。通过-codec选项对指定流进行处理并存储到指定输出文件。特别的,当-codec选项紧跟着流选取,将不会影响到后续的命令行部分。如果对于某个类型的流没有使用-codec选项,ffmpeg将选择输出文件封装器注册的默认编码器。

字幕的处理将会是个例外。如果字幕的编码器被指定,那么第一个字幕流,不管是基于文本还是基于图像的,将被包含进来。ffmpeg不会去验证指定编码器是否能转换选择的流或者转换后的流是否被输出文件封装格式所接受。对于这种应用场景也是一样:当用户手动设置编码器,选取的流处理也不会去验证编码后的流是否能被封装进输出文件。如果不能,ffmpeg将终止运行,所有输出文件的处理将以失败告终。

4.2 示例


下面所示例子展示了一般性行为,特殊情况,以及ffmpeg流选取的一些限制。

示例中三个输入文件情况如下:

示例:自动流选取


命令行中有三个输出文件,对于前两个输出文件,没有使用-map,因此ffmpeg将会为这两个输出文件自动选取流。

out1.mkv 是一个Matroska容器文件,接受视频,音频,字幕流,因此ffmpeg将会每个类型的流都试图选择一个。

对于视频,将会选择B.mp4文件的stream 0,因为在两个文件的所有视频流中它的分辨率是最高的。

对于音频,将会选择B.mp4文件的stream 3,因为在两个文件的所有音频流中它的通道数是最多的。

对于字幕,将会选择B.mp4文件的stream 2,因为它是两个文件中第一个字幕流。

out2.wav仅接受音频流,因此B.mp4文件的stream 3将被选取。

对于out3.mov,因为使用了-map选项,因此ffmpeg将不会自动选取流。-map 1:a指明选取第二个文件的所有音频流,其他流将不会被包含进输出文件。

对于前两个输出,所有包含的流将会被转码。编码器的选择使用输出文件格式所注册默认编码器,可能和选取的输入流的编解码器不一样。

对于第三个输出,编解码器选项-c:a已经被指定为copy,因此不会有解码-滤镜-编码操作过程。选取流中编码数据包将从输入文件直接封装进输出文件。

 

 

 

5 命令选项以及示例


猜你喜欢

转载自blog.csdn.net/ice_ly000/article/details/88032056