基础指令
一.查看FFmpeg支持的编码器
1
| ffmpeg configure -encoders
|
二.查看FFmpeg支持的解码器
1
| ffmpeg configure -decoders
|
三.查看FFmpeg支持的通信协议
1
| ffmpeg configure -protocols
|
四.查看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.
改变视频帧率
有两种方法可以改变输出文件的视频流帧率:
- 使用 -r 选项
- 使用 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.c
中 channel_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倍。
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秒;时间戳与设置点及其对应的过滤器保持连续。