在制作音频和视频的项目中,我们经常会遇到音频和视频不同步、编码和解码错误等问题。此时,我们需要的问题视频数据提供给dump分析使用ffmpeg各种工具可以更好地分析相应的音频和视频文件。
ffmpeg
ffmpeg该工具主要用于音视频转码。 使用规则如下:
ffmpeg [global_options] {
[input_file_options] -i input_url} ... {
[output_file_options] output_url} ...
1.流说明符
stream_index 代表流量的编号从0开始,通常在使用时配合streamType使用。 示例 比如-codec:a :1 ac3.指定第二路音频流ac编码,不指定stream_index所有的流,-b:a 128k,指定的所有音频流量为128k的码率,-codec copy 或者-codec:copy这意味着它只会复制流量,而不会重新编码
stream_type
stream_type | 说明 |
---|---|
‘v’ 或者 ‘V’ | 表示视频 |
‘a’ | 表示音频 |
‘s’ | 表示字幕 |
‘d’ | 表示data |
‘t’ | 表示附加信息 |
p:program_id[:stream_index] or p:program_id[:stream_type[:stream_index]] or p:program_id??key[:value]" 在第一种情况下,匹配指定的情况stream_index流; 第二种情况,匹配指定的情况stream_type和指定的stream_index的流; 在第三种情况下,匹配指定的情况metadata的流
m:key[:value] 跟指定了metadata的key和value匹配流,value如果没有给出,匹配是相应的key的流。
u 匹配可用配置的流量。
2.通用选项
所有这些选项都在ff*通用工具
-L 显示证书
-h,-?,-help,–help [arg] 帮助说明 arg的取值
arg取值 | 说明 |
---|---|
long | 打印附加选项 |
full | 打印所有选项 |
decoder=decoder_name | 打印指定解码器的参数 |
encoder=encoder_name | 打印指定编码器的参数 |
demuxer=demuxer_name | 指定解复用器打印参数 |
muxer=muxer_name | 指定合成器的参数打印 |
filter=filter_name | 打印指定滤镜的参数 |
-version 显示版本
-formats、-demuxers、-muxers、-devices、-codecs、-decoders、-encoders、-bsfs、-protocols、-filters、-pix_fmts、-sample_fmts、-layouts-colors、-sources device[,opt1=val1[,opt2=val2]…]、-sinks device[,opt1=val1[,opt2=val2]…] 以上参数均为显示类,均为显示可用参数,bsfs是bitstream fitlers
-loglevel [flags ]loglevel | -v [flags ]loglevel
loglevel有如下的值
值 | 类型 | 说明 |
---|---|---|
-8 | quiet | 什么显示任何东西 |
0 | panic | 只显示错误信息和导致错误信息 |
8 | fatal | 显示错误信息 |
16 | error | 显示所有错误信息 |
24 | warning | 显示warning信息 |
32 | info | 显示info信息 |
40 | verbose | 显示verbose信息 |
48 | debug | 显示所有信息 |
56 | trace | 显示trace信息 |
-report 给所有的日志dump下来,文件名称的规则是program-YYYYMMDD-HHMMSS.log
-hide_bander 压制打印的banner
-cpuflags flags
3.主要选项
-f fmt (input/output) 指定输入输出格式
-i url (input) 输入的文件格式
-y (global) 重写输出文件输出文件
-n (global) 输出文件不重写
-stream_loop numberinput) 设置输入的流是否需要循环,Loop 0表示不loop,loop -l表示无限loop
-c[:stream_specifier] codec (input/output,per-stream) -codec[:stream_specifier] codec (input/output,per-stream) 指定转码的编码器
ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
-map 0表示对所有的视频流都生效,-c:v 表示指定视频流的编码器,-c:a 表示对音频流的只是复制而已。
ffmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
-t duration (input/output) 表示限制读取的数据的时间长度
-to position (input/output) 表示停止读取源文件的位置
-fs limit_size (output) 显示输出文件的大小
-ss position (input/output) 指定输入或者输出文件的起始位置
-sseof position (input) 指定输入文件的结束位置
-itsoffset offset (input) 设置输入文件的时间偏移
-timestamp date (output) 设置录制的时间戳
-metadata[:metadata_specifier] key=value (output,per-metadata) 添加输入文件的metadata信息
ffmpeg -i in.avi -metadata title="my title" out.flv
ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
-disposition[:stream_specifier] value (output,per-stream) 设置流的配置 下面有流的配置 default dub original comment lyrics karaoke forced hearing_impaired visual_impaired clean_effects attached_pic captions descriptions dependent metadata
示例 设置第二路音频流为默认的流
ffmpeg -i in.mkv -c copy -disposition:a:1 default out.mkv
-program [title=title:][program_num=program_num:]st=stream[:st=stream…] (output) 创建指定的项目
-target type (output) 设置输出的文件类型 vcd, svcd, dvd, dv, dv50等等类型,有可能要使用这些格式前缀pal-, ntsc- or film- 示例
ffmpeg -i myfile.avi -target pal-vcd /tmp/vcd.mpg
-dn (output) 不转码data数据
-dframes number (output) 设置data数据的帧率
-frames[:stream_specifier] framecount (output,per-stream) 设置达到某个帧数,然后停止转码
-q[:stream_specifier] q (output,per-stream) -qscale[:stream_specifier] q (output,per-stream) 用来解决高质量的转码
-filter[:stream_specifier] filtergraph (output,per-stream) 使用指定的滤镜效果,filtergraph是过滤器图
-filter_script[:stream_specifier] filename (output,per-stream) 和上面的参数一致
-filter_threads nb_threads (global) 定义处理filter的线程数
-pre[:stream_specifier] preset_name (output,per-stream) 设置流的预先配置
-stats (global) 打印转码的状态日志
-progress url (global) 将处理进度打印到文件当中
-stdin 开启标准输入输出
-debug_ts (global) 或者-fdebug ts 打印转码时间戳,用来测试或者debug的
-attach filename (output) 添加一个附属的文件到输出文件中
ffmpeg -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv
-dump_attachment[:stream_specifier] filename (input,per-stream) 将附属文件给dump下来
ffmpeg -dump_attachment:t:0 out.ttf -i INPUT
3.视频的选项
-vframes number (output) 设置输出文件的帧数
-r[:stream_specifier] fps (input/output,per-stream) 设置输出的帧率
-s[:stream_specifier] size (input/output,per-stream) 设置输出文件的大小,这里是等比例缩放的
-aspect[:stream_specifier] aspect (output,per-stream) 设置输出文件视频宽高比例
-vn (output) 不开视频转码
-vcodec codec (output)或者-codec:v 设置视频编码的编码器
-pass[:stream_specifier] n (output,per-stream) 选择pass的数量
ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
-passlogfile[:stream_specifier] prefix (output,per-stream) 设置pass的log文件
-vf filtergraph (output) 设置转码的变换的规则
//按照宽高最小值进行视频的转码为240p
ffmpeg -i output_p_540.mp4 -vf scale="floor(iw/min(iw\,ih)*240/2)*2:floor(ih/min(iw\,ih)*240/2)*2" output_p_480.mp4
4.高级的视频转码选项
-pix_fmt[:stream_specifier] format (input/output,per-stream) 设置输入或者输出的的pix_fmt,可以用-pix_fmts显示可用的pix_fmt
-sws_flags flags (input/output) 设置图片变换的flags
-rc_override[:stream_specifier] override (output,per-stream) 指定帧率控制的间隔
-ilme 强制编码器的交错支持
-psnr 计算PSNR即压缩后的视频质量
-vstats dump转码的日志,到 vstats_HHMMSS.log中
-vstats_file file dump转码的日志到指定的文件
-vstats_version file
version = 1 :
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
version > 1:
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 (output,per-stream) top=1/bottom=0/auto=-1 field first
-dc precision 内部精度
-vtag fourcc/tag (output) 强制将视频为四字节代码???
-qphist (global) 显示QP的柱形图
-force_key_frames[:stream_specifier] time[,time…] (output,per-stream) -force_key_frames[:stream_specifier] expr:expr (output,per-stream) 强加关键帧到指定时间戳
-copyinkf[:stream_specifier] (output,per-stream) stream copy的时候,同时将不是第一个关键帧,前面的所有帧都拷贝过去
-init_hw_device type[=name][:device[,key=value…]] -init_hw_device type[=name]@source 初始化硬编码设备
-init_hw_device list 查看ffmpeg支持的硬编码设备
-filter_hw_device name 通过硬编码设备调用指定的滤镜
-hwaccel[:stream_specifier] hwaccel (input,per-stream) 使用硬件加速去解码流
-hwaccel_device[:stream_specifier] hwaccel_device (input,per-stream) 选择一个设备去进行硬件加速
-hwaccels 列举FFmpeg支持的硬件加速
5.音频的选项
-aframes number (output) 设置输出的音频帧数
-ar[:stream_specifier] freq (input/output,per-stream) 设置音频的采样率
-aq q (output) 设置音频的质量
-ac[:stream_specifier] channels (input/output,per-stream) 设置音频的channel count
-an (output) 关闭音频的转码
-acodec codec (input/output)或者-codec:a 设置音频硬编码器
-sample_fmt[:stream_specifier] sample_fmt (output,per-stream) 设置采样的格式
-af filtergraph (output) 设置音频的转码的滤镜
6.高级音频的选项
-atag fourcc/tag (output)或者-tag:a 强制音频的选项
-guess_layout_max channels (input,per-stream) 猜测音频的channel
7.字幕选项
-scodec codec (input/output) 设置字幕的编码器
-sn (output) 不开启字幕转码
8.高级字幕选项
-fix_sub_duration 解决字幕时间
-canvas_size size 设置字幕显示的画布大小
9.高级选项
map [-]input_file_id[:stream_specifier][?][,sync_file_id[:stream_specifier]] | [linklabel] (output) 指定一个或者更多的输入的流输出到文件中
第一个-map选项,对应输出文件的流0,第二个-map选项,对应输出文件的流1,以此类推。
[-]选项,是指除了指定流以外的所有流
?选项,允许匹配到流
安排所有流从输入到输出文件
ffmpeg -i INPUT -map 0 output
假如有2路音频流在输入文件中,这些流都被指定为0:0 或者0:1,用-map来选择哪路流配置到输出文件中,下面是设置第2路音频流,到音频流中
ffmpeg -i INPUT -map 0:1 out.wav
选择第一个文件的index为2的流,并选择第二个文件的index为6的流到,输出文件中
ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
选择所有的视频流和第3路音频流到输出文件
ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT
选择除了第二路音频流的所有的流,都到输出文件中
ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
选择所有的视频流和音频流,假如这个文件没有音频流也没有问题
ffmpeg -i INPUT -map 0:v -map 0:a? OUTPUT
选择英文的音频流
ffmpeg -i INPUT -map 0:m:language:eng OUTPUT
-ignore_unknown 忽略未知类型的流拷贝错误
-copy_unknown 忽略拷贝流失败
map_channel [input_file_id.stream_specifier.channel_id|-1][?][:output_file_id.stream_specifier]
-1 是可以选择静音声道
选择输出的音频的声道
? 可以不匹配到声道
示例 假如输入文件是立体声道音频文件,通过下面命令变成双声道的音频文件
ffmpeg -i INPUT -map_channel 0.0.1 -map_channel 0.0.0 OUTPUT
静音第一个声道并且保持第二个声道
ffmpeg -i INPUT -map_channel -1 -map_channel 0.0.1 OUTPUT
-map_metadata[:metadata_spec_out] infile[:metadata_spec_in] (output,per-metadata) 设置输出文件的metadata metadata可以由下面的表单 g 全局metadata
s[:stream_spec] 流index的metadata
c:chapter_index 每个chapter的metadata
p:program_index 每个program的metadata
示例 拷贝输入文件的第一路流的metadata到输出文件的全局metadata
ffmpeg -i in.ogg -map_metadata 0:s:0 out.mp3
拷贝全局的metadata到音频流中
ffmpeg -i in.mkv -map_metadata:s:a 0:g out.mkv
-map_chapters input_file_index (output) 从输入文件拷贝chapters到下个输出文件
-benchmark (global) 显示编码结束标记
-benchmark_all (global) 显示标记信息在编码中
-timelimit duration (global) 在某个时间点退出FFmpeg
-dump (global) dump所有的输入到到文件中
-hex (global) dump文件是,同时dump payload
-re (input) 输出的帧率和输入的文件保持一致
-loop_output number_of_times 重复这个文件,比如像gif文件
-vsync parameter 视频同步方法 parameter的取值 0, passthrough 从解复用直接传递到复用中去 1, cfr 帧会复用并且丢弃去达到指定的帧率 2,vfr 帧会直接按照时间戳传递过去,并且丢弃区具有相同时间戳的视频数据帧 drop 所有的帧都传递过去,但是基于新的帧率得到新的时间戳 -1, auto 依赖复用器的能力,选择1到2之间
-frame_drop_threshold parameter 丢帧的界限
-async samples_per_second 音频同步的方法
-copyts 不处理输入的时间戳,保持它们的值不收损害
-start_at_zero 当使用上面的选项,变化输入的文件的时间戳,所以他们其实时间为0
-copytb mode 在流拷贝的时候,设置编码器的时间基点 1 使用解复用的时间基点 0 使用解码器的时间基点 -1 自动选择时间基点,保证一个正常的输出
-enc_time_base[:stream_specifier] timebase (output,per-stream) 设置编码器的时间基点 0 设置一个默认的时间基点值 -1 尽量使用出入流的时间基点 >0 使用指定的值作为时间基点
-bitexact (input/output) 启动位精确模式,给解复用器和复用器
-shortest (output) 使用最短的流进行编码
-dts_delta_threshold 时间戳不连续的阈值
-muxdelay seconds (input) 设置最大的解码延迟
-muxpreload seconds (input) 设置初始化解码延迟
-streamid output-stream-index:new-value (output) 赋值一个新的流id的值到输出流中
ffmpeg -i inurl -streamid 0:33 -streamid 1:36 out.ts
-bsf[:stream_specifier] bitstream_filters (output,per-stream) 设置位流的滤镜给匹配的流
ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
ffmpeg -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt
-tag[:stream_specifier] codec_tag (input/output,per-stream) 在指定的加个tag
-timecode hh:mm:ssSEPff 设置指定的时间点去写入
ffmpeg -i input.mpg -timecode 01:02:03.04 -r 30000/1001 -s ntsc output.mpg
-filter_complex filtergraph (global) 定义复杂的滤镜器图
覆盖一张图到视频上面
ffmpeg -i video.mkv -i image.png -filter_complex '[0:v][1:v]overlay[out]' -map
'[out]' out.mkv
[0:v]连接到第一个视频流在第一个输入的文件,连接到第一个输入输入的覆盖滤镜。
假设这里只有一个视频流的输入文件,我们可以删除输入的标志,所以上面等同于
ffmpeg -i video.mkv -i image.png -filter_complex 'overlay[out]' -map
'[out]' out.mkv
此外,我们可以忽略输出的标记和单个输出到滤镜器,并自动添加到输出文件。
ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv
完成5s的纯红视频,可以只用颜色源
ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv
-filter_complex_threads nb_threads (global) 定义多少个线程进行滤镜的处理,默认的数值是CPU的位数
-lavfi filtergraph (global) 定义一个复杂的滤镜器图
-filter_complex_script filename (global) 这个选项同-filter_complex,唯一不同的是从文件进行读取规则
-accurate_seek (input) 这个选项开启和关闭精确的seeking,配合-ss选项,并使用-noaccurate_seek进行关闭
-seek_timestamp (input) 这个选项是开启或者关闭通过时间戳进行seeking
-thread_queue_size size (input) 这个选项设置最大的数据队列,当读取文件或者设备的时候,要低延时和高码率的直播流,数据包可能会被丢弃,当没有及时被读取到,提高这个值可以避免发送这种情况。
-sdp_file file (global) 打印sdp的信息到输出的流
-discard (input) 允许丢弃指定的流或者帧在解复用的时候 none 不丢弃任何帧 default 默认,不丢帧 noref 丢所有非参考帧 bidir 丢所有双向预测帧 nokey 丢了除了关键帧之外的所有帧 all 丢所有的帧
-xerror (global) 出错是停止
-max_muxing_queue_size packets (output,per-stream) 编码的时候,设置复用的包的队列的大小
硬编字幕在DVB-T记录到MPEG-TS格式,延时字幕为1s钟
ffmpeg -i input.ts -filter_complex \
'[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \
-sn -map '#0x2dc' output.mkv
11.例子
11.1 音视频抓取
如果你指定输入的格式和设备,FFmpeg能够直接抓取视频或者音频
ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
或者使用ALSA的音频输入源替代OOS
ffmpeg -f alsa -ac 1 -i hw:1 -f video4linux2 -i /dev/video0 /tmp/out.mpg
11.2 X11抓取
通过x11显示进行抓取
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0 /tmp/out.mpg
0.0是显示屏的坐标X11 Server,和DISPLAY环境变量相似
ffmpeg -f x11grab -video_size cif -framerate 25 -i :0.0+10,20 /tmp/out.mpg
11.3 音视频文件格式变换
使用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...
使用原始YUV420P的文件
ffmpeg -i /tmp/test.yuv /tmp/out.avi
输出YUV420P文件
ffmpeg -i mydivx.avi hugefile.yuv
设置各自输入文件和输出文件
ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
可以做音频和视频转换
ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
同一时间进行几种格式的转换
ffmpeg -i /tmp/a.wav -map 0:a -b:a 64k /tmp/a.mp2 -map 0:a -b:a 128k /tmp/b.mp2
从视频里面截取图片
ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
通过使用-frames:v或者-t ,进行限制输出的帧数,或者通过-ss仅仅想视频视频
ffmpeg -f image2 -framerate 12 -i foo-%03d.jpeg -s WxH foo.avi
当导入一个图片集合,-i 同时可以支持的
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.nu
强制输出CBR视频输出
ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
四个选项Imin,Imax,mblmin和mblmax使用‘lambda’单元
ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext
12.实际项目使用的命令
AAC转PCM文件
ffmpeg -i input.aac -f s16le -ar 44100 -acodec pcm_s16le output.pcm
PCM文件转AAC
ffmpeg -f s16le -ar 44100 -ac 2 -acodec pcm_s16le -i input. output.wav
FFmpeg推拉流命令
//推流本地文件到服务器 ffmpeg -re -i /Users/xu/Desktop/bangbangbang.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/rtmplive/home //本地桌面录制或者分享 ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv rtmp://localhost:1935/rtmplive/home //桌面+
麦克风 ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/rtmplive/home //桌面+麦克风+摄像头 ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480 -i "0" \-c:v libx264 -preset ultrafast \-filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/rtmplive/home
FFmpeg的视频分辨率转换公式
ffmpeg -i output_p_540.mp4 -vf scale="floor(iw/min(iw\,ih)*240/2)*2:floor(ih/min(iw\,ih)*240/2)*2" output_p_480.mp4
FFmpeg进行转码
ffmpeg -i input_ac3.mp4 -vcodec copy -acodec aac -f flv output.flv
主要的参考的文档有 https://ffmpeg.org/ffmpeg-resampler.html https://www.jianshu.com/p/d541b317f71c