FFMPEG document

ffmpeg学习笔记

简介

说明

要将输出文件的视频比特率设置为64 kbit/s:

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

要将输出文件的帧速率强制为24 fps:

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

要将输入文件的帧速率(仅对原始格式有效)强制为1 fps,将输出文件的帧速率强制为24 fps:

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

详细描述

每个输出的ffmpeg转码过程可以用下图描述:
 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|

ffmpeg调用libavformat库(包含demuxer)来读取输入文件并从中获取包含编码数据的包。当存在多个输入文件时,ffmpeg试图通过跟踪任何活动输入流上的最低时间戳来保持同步。然后将编码的数据包传递给解码器(除非为流选择了streamcopy,否则请参阅进一步的描述)。解码器产生未压缩帧(原始视频/pcm音频/…),可通过过滤进一步处理(参见下一节)。过滤后,帧被传递给编码器,编码器对其进行编码并输出编码的数据包。最后,这些数据被传递给muxer,muxer将编码数据包写入输出文件。

过滤

在编码之前,ffmpeg可以使用libavfilter库中的过滤器处理原始音频和视频帧。几个链接的过滤器形成一个过滤图。ffmpeg区分了两种类型的过滤图:简单和复杂。

简单筛选图

简单的过滤图是那些只有一个输入和输出的过滤图,它们都是同一类型的。在上图中,它们可以通过在解码和编码之间插入一个额外的步骤来表示:
 _________                        ______________
|         |                      |              |
| decoded |                      | encoded data |
| frames  |\                   _ | packets      |
|_________| \                  /||______________|
             \   __________   /
  simple     _\||          | /  encoder
  filtergraph   | filtered |/
                | frames   |
                |__________|
简单的过滤图配置为每个流的“-filter”选项(视频和音频分别使用“-vf”和“-af”别名)。例如,一个简单的视频过滤图可以如下所示:
 _______        _____________        _______        ________
|       |      |             |      |       |      |        |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______|      |_____________|      |_______|      |________|

请注意,某些过滤器会更改框架属性,但不会更改框架内容。例如,上面示例中的fps过滤器更改帧的数量,但不接触帧内容。另一个例子是setpts过滤器,它只设置时间戳,否则传递的帧不变。

复杂过滤图

复杂的过滤图不能简单地描述为应用于一个流的线性处理链。例如,当图形有多个输入和/或输出时,或者当输出流类型与输入不同时,就是这种情况。它们可以用下图表示:
 _________
|         |
| input 0 |\                    __________
|_________| \                  |          |
             \   _________    /| output 0 |
              \ |         |  / |__________|
 _________     \| complex | /
|         |     |         |/
| input 1 |---->| filter  |\
|_________|     |         | \   __________
               /| graph   |  \ |          |
              / |         |   \| output 1 |
 _________   /  |_________|    |__________|
|         | /
| input 2 |/
|_________|
使用“-filter_complex”选项配置复杂的过滤图。请注意,此选项是全局的,因为根据其性质,复杂的筛选图不能明确地与单个流或文件关联。
“-lavfi”选项等效于“-filter_complex”。
一个简单的例子就是叠加滤波器,它有两个视频输入和一个视频输出,其中一个视频叠加在另一个视频上。它的音频对应物是amix过滤器。

流复制

流复制是通过将复制参数提供给“-codec”选项选择的模式。它使ffmpeg省略了指定流的解码和编码步骤,因此它只进行反编译和多路复用。它对于更改容器格式或修改容器级元数据很有用。在这种情况下,上图将简化为:
 _______              ______________            ________
|       |            |              |          |        |
| input |  demuxer   | encoded data |  muxer   | output |
| file  | ---------> | packets      | -------> | file   |
|_______|            |______________|          |________|

由于没有译码或编码,所以速度非常快,并且没有质量损失。但是,在某些情况下,由于许多因素,它可能不起作用。应用过滤器显然也是不可能的,因为过滤器处理未压缩的数据。

流选择

ffmpeg提供了-map选项,用于手动控制每个输出文件中的流选择。用户可以跳过-map并让ffmpeg执行如下所述的自动流选择。-vn/-an/-sn/-dn选项可用于分别跳过视频、音频、副标题和数据流的包含,无论是手动映射的还是自动选择的,但作为复杂过滤图输出的流除外。

说明

下面的小节描述了流选择中涉及的各种规则。接下来的例子说明了这些规则是如何在实践中应用的。
虽然尽一切努力准确地反映程序的行为,但是ffmpeg正在不断地开发中,并且代码可能在编写之后发生了变化。

自动流选择

在特定输出文件没有任何映射选项的情况下,ffmpeg检查输出格式,以检查其中可以包含哪些类型的流,即。视频、音频和/或字幕。对于每个可接受的流类型,ffmpeg将从所有输入中选择一个可用的流。
它将根据以下条件选择该流:
对于视频,它是分辨率最高的流,
对于音频,它是拥有最多频道的流,
对于字幕,这是找到的第一个字幕流,但有一个警告。输出格式的默认字幕编码器可以是基于文本的,也可以是基于图像的,并且只选择相同类型的字幕流。
在相同类型速率的多个流相同的情况下,将选择索引最低的流。
数据或附件流不是自动选择的,只能使用-map包含。

手动流选择

使用-map时,该输出文件中只包含用户映射的流,下面描述的filtergraph输出可能有一个例外。

复杂过滤图

如果有任何具有未标记的pad的复杂filtergraph输出流,它们将被添加到第一个输出文件中。如果输出格式不支持流类型,这将导致致命错误。在没有map选项的情况下,包含这些流将导致跳过其类型的自动流选择。如果存在映射选项,则除了映射的流之外,还包括这些筛选图流。
带有标签的PAD的复杂筛选图输出流必须映射一次且恰好映射一次。

流处理

流处理独立于流选择,下面描述的字幕除外。流处理通过-codec选项设置,该选项针对特定输出文件中的流。尤其是,在流选择过程之后,ffmpeg应用编解码器选项,因此不会影响后者。如果没有为流类型指定-codec选项,ffmpeg将选择输出文件muxer注册的默认编码器。
字幕例外。如果为输出文件指定了字幕编码器,则将包括找到的任何类型、文本或图像的第一个字幕流。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’是一个matroska容器文件,接受视频、音频和副标题流,因此ffmpeg将尝试选择每种类型中的一种。
对于视频,它将从“b.mp4”中选择流0,该流在所有输入视频流中具有最高分辨率。
对于音频,它将从“b.mp4”中选择流3,因为它有最多的频道。
对于字幕,它将从“b.mp4”中选择流2,这是“a.avi”和“b.mp4”中的第一个字幕流。
“out3.mov’,因为A是集地图选项,选择要自动流没有发生。图1:一个选项选择所有的音频流从第二输入b.mp4’。没有其他的输出流将包括在本文件。
对于前两个输出,所有包含的流都将被转码。所选的编码器将是每个输出格式注册的默认编码器,可能与所选输入流的编解码器不匹配。
对于第三个输出,音频流的编解码器选项已设置为“复制”,因此不会发生或可能发生解码筛选编码操作。所选流的数据包应从输入文件传送,并在输出文件中混合。

自动字幕选择

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

虽然“out1.mkv”是一个接受字幕流的matroska容器文件,但只能选择视频和音频流。‘c.mkv’的字幕流是基于图像的,Matroska Muxer的默认字幕编码器是基于文本的,因此字幕的转码操作预计会失败,因此不会选择该流。但是,在’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,它由一个视频过滤器组成。覆盖过滤器只需要两个视频输入,但未指定任何输入,因此使用前两个可用的视频流,即“a.avi”和“c.mkv”。过滤器的输出板没有标签,因此发送到第一个输出文件“out1.mp4”。因此,跳过视频流的自动选择,这将选择“b.mp4”中的流。大多数频道的音频流。“b.mp4”中的流3自动选择。但是,没有选择字幕流,因为MP4格式没有注册默认字幕编码器,并且用户没有指定字幕编码器。
第二个输出文件out2.srt只接受基于文本的副标题流。因此,尽管第一个可用的副标题流属于“c.mkv”,但它是基于图像的,因此被跳过。所选流“b.mp4”中的流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],而且还没有映射到任何地方。
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”的视频流被发送到色调过滤器,色调过滤器的输出使用拆分过滤器克隆一次,并且两个输出都被标记。然后将每个副本映射到第一个和第三个输出文件。
叠加滤波器需要两个视频输入,使用前两个未使用的视频流。这些是来自“a.avi”和“c.mkv”的流。覆盖输出没有标记,因此它被发送到第一个输出文件“out1.mp4”,而不管存在-map选项。
将发送第一个未使用的音频流,即“a.avi”的音频流。由于此过滤器输出也未标记,因此它也映射到第一个输出文件。存在-an只会抑制音频流的自动或手动流选择,而不是从筛选图发送的输出。这两个映射流都应在“out1.mp4”中的映射流之前排序。
映射到out2.mkv的视频、音频和副标题流完全由自动流选择决定。
“out3.mkv”由来自色调过滤器的克隆视频输出和来自“b.mp4”的第一个音频流组成。

选项

所有的数字选项,如果没有另外指定,接受一个表示数字的字符串作为输入,后面可能跟一个国际单位前缀,例如:“K”、“M”或“G”。
如果“i”附加到SI单位前缀,则完整前缀将被解释为二进制倍数的单位前缀,其基于1024次幂而不是1000次幂。将“b”附加到SI单位前缀后,值乘以8。这允许使用,例如:“kb”、“mib”、“g”和“b”作为数字后缀。
不带参数的选项是布尔选项,并将相应的值设置为true。它们可以通过在选项名前面加上“no”来设置为false。例如,使用“-nofoo”会将名为“foo”的布尔选项设置为false。

流说明符

每个流应用一些选项,例如比特率或编解码器。流说明符用于精确指定给定选项所属的流。
流说明符是一个字符串,通常附加到选项名后,用冒号分隔。例如,-codec:a:1 ac3包含与第二个音频流匹配的a:1流说明符。因此,它将为第二个音频流选择AC3编解码器。
流说明符可以与多个流匹配,以便将选项应用于所有流。例如,-b:a 128k中的流说明符与所有音频流匹配。

.
.
.

示例

视频和音频抓取

如果指定输入格式和设备,那么ffmpeg可以直接获取视频和音频。

ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg

或者使用ALSA音频源(单声道输入,卡ID 1)而不是OSS:

ffmpeg -f alsa -ac 1 -i hw:1 -f video4linux2 -i /dev/video0 /tmp/out.mpg

请注意,在使用任何电视观众(如Gerd Knorr的xawtv)启动ffmpeg之前,必须激活正确的视频源和频道。您还必须使用标准混音器正确设置录音音量。

抓取X11

使用ffmpeg via获取x11显示器

ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0 /tmp/out.mpg

0.0是x11服务器的display.screen编号,与display环境变量相同。
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0+10,20 /tmp/out.mpg
0.0是x11服务器的display.screen编号,与display环境变量相同。10是抓取的X偏移量,20是抓取的Y偏移量。

视频和音频文件格式转换

任何支持的文件格式和协议都可以作为ffmpeg的输入:
您可以使用yuv文件作为输入:

ffmpeg -i /tmp/test%d.Y /tmp/out.mpg

它将使用以下文件:
/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
Y文件的分辨率是U和V文件的两倍。它们是原始文件,没有头文件。它们可以由所有像样的视频解码器产生。如果ffmpeg无法猜测,则必须使用“-s”选项指定图像的大小。
可以从原始yuv420p文件输入:

ffmpeg -i /tmp/test.yuv /tmp/out.avi

test.yuv是包含原始yuv平面数据的文件。每个框架由Y平面和U、V平面组成,垂直和水平分辨率为一半。
您可以输出到原始YUv420P文件:

ffmpeg -i mydivx.avi hugefile.yuv

可以设置多个输入文件和输出文件:

ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg

将音频文件a.wav和原始yuv视频文件a.yuv转换为mpeg文件a.mpg。
您还可以同时进行音频和视频转换:

ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2

以22050赫兹采样率将A.wav转换为MPEG音频。
您可以同时编码为多种格式,并定义从输入流到输出流的映射:
ffmpeg -i /tmp/a.wav -map 0:a -b:a 64k /tmp/a.mp2 -map 0:a -b:a 128k /tmp/b.mp2
将A.wav转换为64 kbit时的A.mp2和128 kbit的B.mp2。“-map file:index”按输出流定义的顺序指定每个输出流使用的输入流。
您可以对解密的VOB进行转码:
ffmpeg -i snatch_1.vob -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi
这是一个典型的DVD翻录示例;输入是VOB文件,输出带有MPEG-4视频和MP3音频的AVI文件。请注意,在该命令中,我们使用B帧,因此MPEG-4流与divx5兼容,gop大小为300,这意味着29.97fps输入视频每10秒一帧。此外,音频流是MP3编码的,因此您需要通过传递启用lame支持--enable-libmp3lame进行配置。映射对于DVD转码以获得所需的音频语言特别有用。
注意:要查看支持的输入格式,请使用ffmpeg-demuxers
您可以从视频中提取图像,或从许多图像中创建视频:
从视频中提取图像:

ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg

这将从视频中每秒提取一个视频帧,并将其输出到名为“foo-001.jpeg”、“foo-002.jpeg”等文件中。图像将重新缩放以适应新的wxh值。
如果只提取有限数量的帧,可以将上述命令与-frames:v或-t选项结合使用,或者与-ss结合使用,以开始从某个时间点提取。
从许多图像创建视频:
ffmpeg -f image2 -framerate 12 -i foo-%03d.jpeg -s WxH foo.avi
语法foo-%03d.jpeg指定使用由三位数字组成的十进制数字(用零填充)来表示序列号。它与c printf函数支持的语法相同,但只有接受普通整数的格式才适用。
导入图像序列时,-i还支持在内部扩展类似shell的通配符模式(globbing),方法是选择Image2特定的-pattern_type glob选项。
例如,对于从与全局模式foo-*.jpeg匹配的文件名创建视频:
ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi
您可以在输出中放入许多相同类型的流:
ffmpeg -i test1.avi -i test2.avi -map 1:1 -map 1:0 -map 0:1 -map 0:0 -c copy -y test12.nut
生成的输出文件“test12.nut”将包含输入文件的前四个流,顺序相反。
要强制CBR视频输出:
ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
四个选项lmin、lmax、mblmin和mblmax使用“lambda”单位,但您可以使用qp2lambda常量轻松地从“q”单位转换:

ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext

把本地视频推流到rtsp

ffmpeg.exe -re -i F:/video/video1.mp4 -f rtsp rtsp://127.0.0.1/test

列设备

ffmpeg -list_devices true -f dshow -i dummy

获取摄像头数据编码为H.264,最后保存成mycamera.mkv

ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 mycamera.mkv

直接播放摄像头的数据

ffplay -f dshow -i video="Integrated Camera"
ffplay -f vfwcap -i 0

获取摄像头数据->编码为H.264->并发送至RTMP服务器

ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://localhost/oflaDemo/livestream

See Also

ffmpeg-all ffplay ffprobe ffmpeg-utils ffmpeg-scaler ffmpeg-resampler ffmpeg-codecs ffmpeg-bitstream-filters ffmpeg-formats ffmpeg-devices ffmpeg-protocols ffmpeg-filters

作者

ffmpeg开发人员。
有关作者的详细信息,请参见项目的git历史记录(git://source.ffmpeg.or g/ffmpeg),例如,在ffmpeg源目录中键入命令git log,或浏览http://source.ffmpeg.org上的在线存储库。
特定组件的维护人员列在源代码树的“维护人员”文件中。

猜你喜欢

转载自blog.csdn.net/qq122716072/article/details/91375996