ffmpeg的常用选项

基础指令

一.查看FFmpeg支持的编码器

1
ffmpeg configure -encoders

二.查看FFmpeg支持的解码器

1
ffmpeg configure -decoders

三.查看FFmpeg支持的通信协议

1
ffmpeg configure -protocols

四.查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议

1
ffmpeg configure --help

map选项

默认情况下只在输入文件中的每种流里选择第一个流。

需要指定放入输出文件的流就需要使用-map选项。

用法举例:

-map 0
From input index #0 (the 1st input) select all streams.

-map 1:a
From input index #1 (the 2nd input) select all audio streams.

-map 3:s:4
From input index #3 (the 4th input) select subtitle stream index #4 (the fifth subtitle stream)。

-map 0 -map -0:s
Will select all streams from input index #0 (the 1st input) except subtitles.

改变视频帧率

有两种方法可以改变输出文件的视频流帧率:

  1. 使用 -r 选项
  2. 使用 fps滤镜。
1
2
ffmpeg -i [inputfile] -r 30 [output]
ffmpeg -i [inputfiel] -filter:v fps=30 [output]

有两种方法可以改变输出文件的视频流帧率:

改变默认音轨

使用ffmpeg修改默认的音频轨道,先取消第二音轨的默认值,在设置为第一音轨。

1
ffmpeg -i input.mkv -map 0:0 -map 0:1 -map 0:2  -c copy -disposition:a:1 0 -disposition:a:0 default -y output.mp4

改变音频采样率

-ar 48k 44.1k 96k

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k output.flac

改变音频通道数量

-ac

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 2 -filter:0 aformat=channel_layouts=stereo output.flac
1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

改变音频位深 bit depth

-sample_fmt

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -sample_fmt s24 -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

生成空白音频

可以使用anullsrc来生成静音音频:

1
ffmpeg -f lavfi -i anullsrc=r=48000:cl=stereo -t 0.875 /Users/redtux/Movies/converted/silent-audio.aac
  • sample_rate, r
    指定采样率,默认44100。

  • channel_layout, cl
    指定通道布局,详见 libavutil/channel_layout.cchannel_layout_map 定义,常见mono stereo 5.1

  • -t
    文件时长,单位事秒,不指定就一直生成。

截取视频片段

1
ffmpeg  -i 源文件名 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 目标文件名 -y

视频拼接

一.将4个视频拼接成一个很长的视频(无声音)

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][1:0] [2:0][3:0] concat=n=4:v=1 [v]' -map '[v]' output.mp4

二.将4个视频拼接成一个很长的视频(有声音)

1
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][0:1] [1:0][1:1] [2:0][2:1] concat=n=3:v=1:a=1 [v][a]' -map '[v]' -map '[a]’  output.mp4

参数解释:

1
2
3
4
5
6
7
8
[0:0][0:1] [1:0][1:1] [2:0][2:1] 
分别表示第1个输入文件的视频、音频,第2个输入文件的视频、音频,第3个输入文件的视频、音频。

concat=n=3:v=1:a=1
表示有3个输入文件,输出一条视频流和一条音频流。

[v][a]
得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。

四.竖向拼接2个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" out_2.mp4

五.横向拼接3个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw*3:ih*1[a];[a][1:v]overlay=w[b];[b][2:v]overlay=2.0*w" out_v3.mp4

六.竖向拼接3个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw:ih*3[a];[a][1:v]overlay=0:h[b];[b][2:v]overlay=0:2.0*h" out_v4.mp4

七.4个视频2x2方式排列

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4

视频帧操作

一.查看每帧的信息

1
ffprobe -v error -show_frames gemfield.mp4 

从pict_type=I可以看出这是个关键帧,然后key_frame=1 表示这是IDR frame,如果key_frame=0表示这是Non-IDR frame。

二.截取视频中的某一帧
把gemfield.mp4视频的第1分05秒的一帧图像截取出来。

1
2
3
4
# input seeking
ffmpeg -ss 00:1:05 -i gemfield.mp4 -frames:v 1 out.jpg
# output seeking
ffmpeg -i gemfield.mp4 -ss 00:1:05 -frames:v 1 out1.jpg

参数解释:

-frame:v 1,在video stream上截取1帧。
input seeking使用的是key frames,所以速度很快;而output seeking是逐帧decode,直到1分05秒,所以速度很慢。

重要说明:

ffmpeg截取视频帧有2种 seeking 方式,对应有2种 coding 模式:transcoding 和 stream copying(ffmpeg -c copy)。

transcoding 模式:需要 decoding + encoding 的模式,即先 decoding 再encoding。

stream copying 模式:不需要decoding + encoding的模式,由命令行选项-codec加上参数copy来指定(-c:v copy )。在这种模式下,ffmpeg在video stream上就会忽略 decoding 和 encoding步骤。

三.查看视频总帧数

1
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 gemfield.mp4

四.查看 key frame 帧数

1
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 -skip_frame nokey gemfield.mp4

五.查看 key frame 所在的时间

1
ffprobe -v error -skip_frame nokey -select_streams v:0 -show_entries frame=pkt_pts_time -of csv=print_section=0 gemfield.mp4

六.查看 key frame 分布的情况

1
ffprobe -v error -show_frames gemfield.mp4 | grep pict_type

七.查看 key frame 所在的帧数

1
ffprobe -v error -select_streams v -show_frames -show_entries frame=pict_type -of csv gemfield.mp4 | grep -n I | cut -d ':' -f 1

八.重新设置 key frame interval

1
ffmpeg -i gemfield.mp4 -vcodec libx264 -x264-params keyint=1:scenecut=0 -acodec copy out.mp4

九.查看视频波特率

1
ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 gemfield.mp4

调整播放速度

调整视频文件中视频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//2倍速播放
ffmpeg -i test.mp4 -an -filter:v "setpts=0.5*PTS" out_test.mp4

-i test.mp4是输入文件名

-an 将音频禁掉 (可以不加)

-filter:v 对视频进行处理

"setpts=0.5PTS" 设置时间戳参数PTS为原先的一半,可接受调整范围为[0.25,4]

out_test.mp4 输出视频文件

还可以在命令中加上指定fps(-r 60),使得不会丢帧

调整视频文件中音频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ffmpeg -i test.mp4 -filter:a "atempo=2.0" -vn out_test.mp4
-i 后满test.mp4是输入文件名

-filter:a 对音频进行处理

"atempo=2.0" 设置播放速度是原来的2倍 , 倍率调整范围[0.5, 2.0]

-vn 将视频禁掉 (可以不加)

out_test.mp4 输出视频文件

需要调整到4倍可以采取以下方法:

ffmpeg -i test.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn out_test.mp4

同时调整视频文件的视频、音频:

1
ffmpeg -i test.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]"  out_test.mp4

如果不想丢帧就同时设置 -r ,把帧率设置为原帧率的2倍。

metadata的使用

1
ffmpeg -i /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio.mp4  -metadata title="Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG" -map 0:0 -c:0 copy -metadata:s:0 title='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -metadata:s:0 handler='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -map 0:1 -c:1 copy -metadata:s:1 title="国语配音" -metadata:s:1 handler="国语配音" -metadata:s:1 language="chi"  -disposition:1 default -map 0:2 -c:2 copy -metadata:s:2 title="English" -metadata:s:2 handler="English" -metadata:s:2 language="eng"  -disposition:2  0 /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG.mp4

提取mp4文件中的封面

1
ffmpeg -i input.mp4 -map 0:v -map -0:V -c copy ./cover.jpg

设置mp4文件的封面

1
ffmpeg -i video.mp4 -i image.png -map 1 -map 0 -c copy -disposition:0 attached_pic out.mp4

综合实例

1
2
3
4
5
6
7
8
9
10
11
12
13
ffmpeg   -y -i  input.mp4  \
-i ~/cover.jpg \
-metadata title="[繁花].Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" \
-metadata comment="[繁花].Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" \
-filter_complex "[0:0]select='between(t,131.32,1106.48)+between(t,1132.92,2647.88)',setpts=N/FRAME_RATE/TB,scale=1920:-8:flags=lanczos,setsar=1:1,hqdn3d=luma_spatial=2:chroma_spatial=1.5:luma_tmp=3:chroma_tmp=2.25[v]" \
-map "[v]" -metadata:s:0 title="Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" -c:0 libx265 -pix_fmt yuv420p \
-x265-params "aq-mode=3:repeat-headers=0:strong-intra-smoothing=1:bframes=4:b-adapt=2:frame-threads=0:colorprim=bt709:transfer=bt709:colormatrix=bt709:chromaloc=0" \
-crf:0 30 -preset:0 slow -tag:0 hvc1 -g 250 \
-map 0:1 -metadata:s:1 title="Mandarin" -metadata:s:1 handler="Mandarin" -metadata:s:1 language=chi \
-c:1 libfdk_aac -profile:1 aac_he -b:1 64k -af:1 "aselect='between(t,131.32,1106.48)+between(t,1132.92,2647.88)',asetpts=N/SR/TB" \
-map 1 -c:2 copy -disposition:2 attached_pic \
-movflags +faststart -map_metadata -1 -map_chapters 0 \
"/Users/redtux/Movies/Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo.mp4"

ffprobe命令

ffprobe是ffmpeg中一个查看多媒体文件信息的模块。此模块可以用来查看多媒体文件格式以及编码。ffprobe的命令较多,这里只简单的列举了一些比较常用的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
-L 显示协议
-h/-?/-help/--help topic 帮助可以选择话题
-version 显示版本
-buildconf 展示编译配置选项
-formats 显示支持的编码
-muxers 展示支持的封装器
-demuxers 展示支持的解封装器
-devices 展示支持的设备
-codecs 展示支持的编码
-decoders 显示支持的解码器
-encoders 显示支持的编码器
-bsfs 显示支持的比特流过滤器
-protocols 展示支持的协议
-filters 展示支持的过滤器
-pix_fmts 显示支持的像素格式
-layouts 展示支持的声道格式
-sample_fmts 显示支持的采样格式
-colors 展示支持的颜色名称
-loglevel loglevel 设置日志级别
-v loglevel 设置日志级别
-report 生成报告
-max_alloc bytes 设置单个已分配块的最大大小
-cpuflags flags 指定cpu标志
-hide_banner hide_banner 不显示程序横幅
-sources device 列出源的输出设备
-sinks device 列出输出设备的接收器
-f format 指定格式
-unit 显示显示值的单位
-prefix 对显示的值使用SI前缀
-byte_binary_prefix 对字节单位使用二进制前缀
-sexagesimal 对时间单位使用六十进制格式 HOURS:MM:SS.MICROSECONDS
-pretty 美化显示输出的值,让人可读
-print_format format 设置打印格式 (available formats are: default, compact, csv, flat, ini, json, xml)
-of format -print_format的编码
-select_streams stream_specifier 选择指定的stream
-sections 打印节结构和节信息,然后退出
-show_data 显示数据包信息
-show_data_hash 显示数据包hash值
-show_error 显示探测中的错误
-show_format 显示格式/容器信息
-show_frames 显示帧信息
-show_format_entry entry 显示格式/容器信息中的特定条目
-show_entries entry_list 显示一组指定的项
-show_log 显示log
-show_packets 显示packet信息
-show_programs 显示程序信息
-show_streams 显示stream的信息
-show_chapters 显示chapters的信息
-count_frames 每个stream中的帧数
-count_packets 每个stream中的包数量
-show_program_version ffprobe的版本
-show_library_versions 库的版本
-show_versions 程序和库的版本号
-show_pixel_formats 展示像素格式描述
-show_private_data 显示私有数据
-private 和显示私有数据一样
-bitexact 强制提取bit输出
-read_intervals read_intervals 设置读取间隔
-default 默认所有选项
-i input_file 读取指定文件
-print_filename print_file 重新显示输入的文件名
-find_stream_info 读取并解码流,用启发式方法填充缺失的信息

举个例子说明一下:

1
ffprobe -show_format test.mp4 -print_format json

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"format": {
"filename": "test.mp4",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "319.204000",
"size": "20393093",
"bit_rate": "511098",
"probe_score": 100,
"tags": {
"major_brand": "isom",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"artist": "张国荣",
"comment": "163 key(Don't modify):LxuL/bhXK+eaR4o7F6vxHKbEgEKNGLg65XxJgCCH5+sQLLnuMmlonrU27WIYQt6PVE6HRptXEzkJGEUUyqRRgCQJCfXHsb5uK0bdi2lw2dOZM6en1xhkYzGV5bS0uqXI0ZMFdk2CrlfK9x7cKCXIO7AU63YasnAy7YR4dW6boVAOaUvjIWxu5CuHaCLpAF8idLjG4VlAtUpZDj2WEXQJRcZZUFLtJWNVzfbnajHn6j7qG9e0XlNSmOu6RlE/X4MR",
"title": "追 ",
"encoder": "Lavf56.4.101"
}
}
}

Select滤镜常用场景

select滤镜的使用方法见官网

1.提取视频关键帧

1
ffmpeg  -i input.mp4 -an -vf select='eq(pict_type\,I)' -vsync 2  -c:v png  image-%03d.png

2.创建缩略图

1
ffmpeg -i input.mp4 -vf select='gt(scene\,0.4)',scale=-1:200,tile=4x10 -frames:v 1 preview.png

3.裁剪视频文件的多个部分,并将其合并成一个新的视频

使用选择滤镜

1
ffmpeg -i video -vf "select='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',asetpts=N/SR/TB" out.mp4

select及其对应的滤波器分别应用于视频和音频,选择的分段是4到6.5秒,17到26秒,最后是74到91秒;时间戳与设置点及其对应的过滤器保持连续。

ffmpeg的常用选项

map选项

默认情况下只在输入文件中的每种流里选择第一个流。

需要指定放入输出文件的流就需要使用-map选项。

用法举例:

-map 0
From input index #0 (the 1st input) select all streams.

-map 1:a
From input index #1 (the 2nd input) select all audio streams.

-map 3:s:4
From input index #3 (the 4th input) select subtitle stream index #4 (the fifth subtitle stream)。

-map 0 -map -0:s
Will select all streams from input index #0 (the 1st input) except subtitles.

改变视频帧率

有两种方法可以改变输出文件的视频流帧率:

  1. 使用 -r 选项
  2. 使用 fps滤镜。
1
2
ffmpeg -i [inputfile] -r 30 [output]
ffmpeg -i [inputfiel] -filter:v fps=30 [output]

有两种方法可以改变输出文件的视频流帧率:

改变默认音轨

使用ffmpeg修改默认的音频轨道,先取消第二音轨的默认值,在设置为第一音轨。

1
ffmpeg -i input.mkv -map 0:0 -map 0:1 -map 0:2  -c copy -disposition:a:1 0 -disposition:a:0 default -y output.mp4

改变音频采样率

-ar 48k 44.1k 96k

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k output.flac

改变音频通道数量

-ac

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 2 -filter:0 aformat=channel_layouts=stereo output.flac
1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

改变音频位深 bit depth

-sample_fmt

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -sample_fmt s24 -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

生成空白音频

可以使用anullsrc来生成静音音频:

1
ffmpeg -f lavfi -i anullsrc=r=48000:cl=stereo -t 0.875 /Users/redtux/Movies/converted/silent-audio.aac
  • sample_rate, r
    指定采样率,默认44100。

  • channel_layout, cl
    指定通道布局,详见 libavutil/channel_layout.cchannel_layout_map 定义,常见mono stereo 5.1

  • -t
    文件时长,单位事秒,不指定就一直生成。

截取视频片段

1
ffmpeg  -i 源文件名 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 目标文件名 -y

裁剪视频文件的多个部分,并将其合并成一个新的视频

调整播放速度

调整视频文件中视频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//2倍速播放
ffmpeg -i test.mp4 -an -filter:v "setpts=0.5*PTS" out_test.mp4

-i test.mp4是输入文件名

-an 将音频禁掉 (可以不加)

-filter:v 对视频进行处理

"setpts=0.5PTS" 设置时间戳参数PTS为原先的一半,可接受调整范围为[0.25,4]

out_test.mp4 输出视频文件

还可以在命令中加上指定fps(-r 60),使得不会丢帧

调整视频文件中音频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ffmpeg -i test.mp4 -filter:a "atempo=2.0" -vn out_test.mp4
-i 后满test.mp4是输入文件名

-filter:a 对音频进行处理

"atempo=2.0" 设置播放速度是原来的2倍 , 倍率调整范围[0.5, 2.0]

-vn 将视频禁掉 (可以不加)

out_test.mp4 输出视频文件

需要调整到4倍可以采取以下方法:

ffmpeg -i test.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn out_test.mp4

同时调整视频文件的视频、音频:

1
ffmpeg -i test.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]"  out_test.mp4

如果不想丢帧就同时设置 -r ,把帧率设置为原帧率的2倍。

metadata的使用

1
ffmpeg -i /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio.mp4  -metadata title="Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG" -map 0:0 -c:0 copy -metadata:s:0 title='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -metadata:s:0 handler='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -map 0:1 -c:1 copy -metadata:s:1 title="国语配音" -metadata:s:1 handler="国语配音" -metadata:s:1 language="chi"  -disposition:1 default -map 0:2 -c:2 copy -metadata:s:2 title="English" -metadata:s:2 handler="English" -metadata:s:2 language="eng"  -disposition:2  0 /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG.mp4