1、FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件
2、FFmpeg框架基本组成
3、FFmpeg工具
5、FFmpeg编码支持与定制
FFmpeg只是提供一套基础的框架,所有的编码格式、文件封装格式与流媒体协议均可作为一个模块挂载到FFmpeg框架中,增减对应的编译参数选项可以对FFmpeg支持的格式进行裁剪
1、ffmpeg常用命令
ffmpeg --help #命令基础信息
ffmpeg --help long #高级参数部分
ffmpeg --help full #全部帮助信息
ffmpeg -L #支持的license协议
ffmpeg -version #查看ffmpeg版本
ffmpeg -formats #查看支持的文件格式
ffmpeg -codecs #查看支持的编解码全部信息
ffmpeg -encoders
ffmpeg -decoders
ffmpeg -filters #查看支持的滤镜
ffmpeg -h muxer=flv #查看某类型详细参数
ffmpeg -h encoder=h264
ffmpeg -i ./input.rmvb -vcodec mpeg4 -b:v 200k -r 15 -an output.mp4 #转码
2、ffprobe常用命令
ffprobe -show_data -show_packets input.flv #查看多媒体数据包信息
ffprobe -show_format output.mp4 #查看多媒体封装格式
ffprobe -show_frames input.flv #查看多媒体文件中的帧信息
ffprobe -show_streams input.flv #查看多媒体文件中的流信息
ffprobe -of xml[/JSON/INI/CSV/FLAT] -show_streams input.flv #XML格式化输出
ffprobe -show_frames -select_streams v -of xml input.mp4 #选择查看流媒体信息 音频(a) 视频(v) 字幕(s)
3、ffplay常用命令
ffplay -ss 10 -t 10 input.mp4 #从10秒开始播放10秒
ffplay -window_title "output" output.mp4 #显示自定义标题
ffplay -window_title "test" rtmp://test.com/live/stream #打开网络直播流
ffplay -window_title "test" -vf "subtitles=input.srt" output.mp4 #添加字幕文件到播放数据中
ffplay -showmode 1 output.mp3 #播放音频波形
ffplay-debug vis_mb_type -ss 10 -t 10 -autoexit output.mp4 #显示宏块
ffplay -vismv pf[/bf/bb] output.mp4 #显示运动估计信息 pf P帧向前 bf B帧向前 bb B帧向后
ffplay -flags2 +export_mvs -ss 10 output.mp4 -vf codecvie=mv=pf+bf+bb #滤镜方式显示运动估计信息(使用趋势)
#将MP4文件切割为MP4切片
./ffmpeg -re -i input.mp4 -c copy -f seqment -seqment_format mp4 output_%d.mp4
#查看第一份切片的最后的时间戳
ffprobe -v quiet -show_packets -select_streams v output_0.mp4 2 > x |grep pts_time |tail -n 3
#生成ffconcat格式索引文件(常用于虚拟轮播等场景)
./ffmpeg -re -i input.mp4 -c copy -f seqment -seqment_format mp4 -seqment_list_type ffconcat -seqment_list output.lst output_%d.mp4
#生成FLAT格式索引文件
./ffmpeg -re -i input.mp4 -c copy -f seqment -seqment_format mp4 -seqment_list_type flat -seqment_list output.txt output_%d.mp4
#生成CSV格式索引文件(用于类数据库操作,也可用于根据CSV生成视图图像)
./ffmpeg -re -i input.mp4 -c copy -f seqment -seqment_format mp4 -seqment_list_type csv -seqment_list output.csv output_%d.mp4
#生成M3U8格式索引文件(HLS)
./ffmpeg -re -i input.mp4 -c copy -f seqment -seqment_format mp4 -seqment_list_type m3u8 -seqment_list output.m3u8 output_%d.mp4
#使切片时间戳归0
./ffmpeg -re -i intput.mp4 -c copy -f seqment -seqment_format mp4 -reset_timestamps 1 output_%d.mp4
#按照时间点切片
./ffmpeg -re -i intput.mp4 -c copy -f seqment -seqment_format mp4 -seqment_times 3,9,12 output_%d.mp4
#指定剪切开头部分
./ffmpeg -ss 10 -i input.mp4 -c copy output.ts
ffprobe -v quiet -show_format input.mp4 |grep duration;ffprobe -v quiet -show_format output.ts |grep duration #查看文件duration对比
#指定视频总长度
./ffmpeg -i input.mp4 -c copy -t 10 -copyts output.mp4
ffprobe -v quiet -show_format input.mp4 |grep start_time;ffprobe -v quiet -show_format output.ts |grep start_time #查看起始时间对比
#指定输出start_time
./ffmpeg -i input.mp4 -c copy -t 10 -output_ts_offset 120 output.mp4
#音视频文件中抽取AAC音频流
./ffmpeg -i input.mp4 -vn -acodec copy output.aac
#音视频文件中抽取H.264视频流
./ffmpeg -i input.mp4 -vcodec copy -an output.h264
#音视频文件中抽取H.265数据
./ffmpeg -i input.mp4 -vcodec copy -an -bsf hevc_mp4toannexb -f hevc output.hevc
#转换封装格式(CPU占用一般)
./ffmpeg -re -i input.mp4 -c copy -f mpegts output.ts
#转码(CPU占用较高)
./ffmpeg -re -i input.mp4 -vcodec libx264 -acodec copy -f mpegts output.ts
1、H264编码
./ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -b:v 2000k output.mp4
H264编码优化参数tune
film
animation
grain
stillimage
psnr
ssim
fastdecode
zerolatency
H264的profile和level
./ffmpeg -i input.mp4 -vcodec libx264 -profile:v baseline -level 3.1 -s 352x288 -an -y -t 10 output.ts
./ffmpeg -i input.mp4 -c:v libx264 -g 50 -sc_threshold 0 -t 60 -y output.mp4
./ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=0" -g 50 -sc_threshold 0 -y output.mp4 #控制不出现B帧
./ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=3:b-adapt=0" -g 50 -sc_threshold 0 -y output.mp4 #每相邻p帧之间存放3个B帧
./ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=10:b-adapt=0" -b:v 1000k -maxrate 1000k -minrate 1000k -bufsize 50k -nal-hrd cbr -g 50 -sc_threshold 0 -y output.ts #控制码率 每50帧一个GOP,不强行插入关键帧
2、AAC编码
#aac
./ffmpeg -i input.mp4 -c:a aac -b:a 160k output.aac
./ffmpeg -i input.wav -c:a aac -q:a 2 output.m4a #-q:a 设置AAC的输出质量 0.1~2 (VBR质量,不可控)
#libfdk_aac
./ffmpeg -i input.mp4 -c:v copy -c:a libfdk_aac -b:a 384k output.mp4 #恒定码率
./ffmpeg -i input.wav -c:a libfdk_aac -vbr 3 output.m4a #动态码率
./ffmpeg -i intput.wav -c:a libfdk_aac -profile:a aac_he -b:a 64k output.m4a #HE-AAC高质量音频编码设置
./ffmpeg -i intput.wav -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k output.m4a
1、RTMP流
ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app live -rtmp_playpath class rtmp://publish.ffmpeg.com # 推流
ffmpeg -rtmp_app live -rtmp_playpath class -i rtmp://publish.ffmpeg.com -c copy -f flv output.flv #拉取
ffmpeg -i input.mp4 -c copy -f flv rtmp://publish.ffmpeg.com/live/class #发布流 live发布点 class流名称
ffmpeg -rtmp_pageurl "http://www.ffmpeg.com" -i rtmp://publish.ffmpeg.com/live/class #
2、RTSP流
ffmpeg -rtsp_transport tcp -i rtsp://127.0.0.1/test.ts -c copy -f mp4 output.mp4 #拉流录制
ffmpeg -user-agent "User" -i rtsp://input:554/live/1/stream.sdp -c copy -f mp4 -y output.mp4 #设置user-agent
3、HTTP流
ffmpeg -ss 20 -seekable 1 -i http://bbs.ffmpeg.com/test.ts -c copy -y output.mp4 #seek操作
ffmpeg -headers "referer:http://bbs.ffmpeg.com/index.html" -i http://play.ffmpeg.com/live/class.flv -c copy -f flv -y output.flv #设置headers参数
ffmpeg -user_agent "User" -i http://bbs.ffmpeg.com/1.flv #
ffmpeg -i http://bbs.ffmpeg.com/live.flv -c copy -f flv output.flv #拉取FLV直播流录制为FLV
ffmpeg -i http://bbs.ffmpeg.com/live.m3u8 -c copy -f flv output.flv #拉取HLS直播流录制为FLV
4、推多路流
ffmpeg -i input.mp4-vcodec libx264 -acodec aac -f flv - |ffmpeg -f flv -i - -c copy -f flv rtmp://publish.ffmpeg.com/live/stream1 -c copy -f flv rtmp://publish.ffmpeg.com/liv/stream2 #一次编码多路输出
ffmpeg -i rtmp://publish.ffmpeg.com/live/stream1 -i rtmp://publish.ffmpeg.com/live/stream2 #拉取
ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -map 0 -f tee "[f=flv]rtmp://publish.ffmpeg.com/live/stream1 | [f=flv]rtmp://publish.ffmpeg.com/live/stream2" #tee封装格式输出多路流
ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -f flv "tee:rtmp://publish.ffmpeg.com/live/stream1 |rtmp://publish.ffmpeg.com/live/stream2" #tee协议输出多路流
5、HDS(HTTP Dynamic Streaming)流
ffmpeg -re -i input.mp4 -c copy -f hds -window_size 4 -extra_window_size 1 output #控制生成列表大小以及额外文件个数
6、DASH(Dynamic Adaptive Streaming over HTTP)流
ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 index.mpd #生成文件索引列表(音视频是分开的)
ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 -single_file 1 index.mpd #是否生成的切片列表写入一个文件
1、Filter使用时的参数排列方式:
[输入流或标记名]滤镜参数[临时标记名];[输入流或标记名]滤镜参数[临时标记名];…
ffmpeg -i input.mp4 -i logo.png -filter_complex "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" output.mp4 #logo缩放放入输入视频左上角
Filter内置变量:
变量 | 说明 |
---|---|
t | 时间戳以秒表示,未知则为NAN |
n | 帧的顺序编号,0开始 |
pos | 帧的位置,未知则为NAN |
w | 帧宽度 |
h | 帧的高度 |
2、视频加水印
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100;fontfile=FreeSerif.ttf:text='hello world':x=20;y=20:fontcolor=green:box=1:boxcolor=yellow" output.mp4 #视频左上角加文字水印 drawtext滤镜
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100;fontfile=FreeSerif.ttf:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':x=20;y=20:fontcolor=green:box=1:boxcolor=yellow:enable=lt(mod(t\,3)\,1))" output.mp4 #视频左上角加时间水印 drawtext滤镜 (enable控制闪烁打印)
ffmpeg -i input.mp4 -vf "movie=logo.png,colorkey=black:1.0:1,0 [wm];[in] [wm] overlay=30:10 [out]" output.mp4 #添加图片水印 movie滤镜 colorkey滤镜
3、画中画
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay=x=main_w-480:y=main_h-320 [out]" -vcodec libx264 output.flv #静态画中画
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay=x='if(gte(t,2),-w+(t-2)*20,NAN)':y=0 [out]" -vcodec libx264 output.flv #动态画中画
4、视频多宫格
ffmpeg -re -i input1.mp4 -re -i input2.mp4 -re -i input3.mp4 -re -i input4.mp4 -filter_complex "nullsrc=size=640x480 [base]; [0:v] setpts=PTS-STARTTPTS,scale=320x240[upperleft];[1:v] setpts=PTS-STARTTPTS,scale=320x240[upperright];[2:v] setpts=PTS-STARTTPTS,scale=320x240[lowerleft];[3:v] setpts=PTS-STARTTPTS,scale=320x240[lowerright]; [base][upperleft]overlay=shortttest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320[tmp2];[tmp2][lowerleft]overlay=shortest=1:y=240[tmp3];[tmp3][lowerright]overlay=shortest=1:x=320:y-240" -c:v libx264 output.flv #分成四格显示四路视频
5、音频流滤镜
ffmpeg -i input.aac -ac 1 output.aac #双声道合并为单声道
ffmpeg -i inout.aac -map_channel 0.0.0 left.aac -map_channel 0.0.1 right.aac #map_channel参数实现双声道提取流
ffmpeg -i input.aac-filter_complex "[0:0]pan=lc|c0=c0[left];[0:0]pan=lc|c0=c1[right]" -map "[left]" left.aac -map "[right]" right.aac #pan滤镜实现双声道提取流
ffmpeg -i input.aac-filter_complex channelsplit=channel_layout=stereo output.mka #channelsplit滤镜切分音频,分成两个音频流
ffmpeg -i left.aac -ac 2 output.m4a #单声道转双声道
ffmpeg -i left.aac -filter_complex "[0:a][0:a]amerge=inputs=2[aout]" -map "[aout]" output.m4a #amerge滤镜实现单声道转双声道
ffmpeg -i left.aac -i right.aac -filter_complex "[0:a][1:a]amerge=inputs=2[aout]" -map "[aout]" output.m4a #多声音源合成双声道(类似,多声音源可合并为多声道)
6、音量探测
ffmpeg -i output.wav -filter_complex volumedetect -c:v copy -f null /dev/null #volumedetect滤镜探测音量分贝
ffmpeg -i output.wav -filter_complex "showwavespic=s=640x120" -frames:v 1 output.png #showwavespic滤镜绘制音频波形图
ffmpeg -i output.wav -filter_complex "showwavespic=s=640x120:split_channels=1" -frames:v 1 output.png #split_channels滤镜绘制多声道音频波形图
7、视频添加字幕
ffmpeg -i input.mp4 -vf ass=t1.ass -f mp4 output.mp4 #视频流中使用ASS滤镜添加字幕
ffmpeg -i input.mp4 -i t1.ass -acodec copy -vcodec copy -scodec copy output.mkv #将字幕加入MKV封装容器中,以字幕流形式存在
ffmpeg -i input.mp4 -i t1.ass -map 0:0 -map 0:1 -map 1:0 -acodec copy -vcodec copy -scodec copy output.mkv #
8、视频抠图合并
ffmpeg -i input.mp4 -i input_green.mp4 -filter_complex "[1:v]chromakey=Green:0.1:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" output.mp4 #chromakey滤镜(主要处理YUV数据)将绿色背景抠图贴到新背景中
9、3D视频处理
ffplay -vf "stereo3d=sbs1:aybd" input.mp4 #stereo3d滤镜左右效果
ffplay -vf "stereo3d=sbs1:arbg" input.mp4 #stereo3d滤镜红蓝眼镜
10、定时视频截图
ffmpeg -i input.flv -ss 00:00:7.435 -vframes 1 out.png #vframes参数获取截图
ffmpeg -i input.flv -vf fps=1/60 img%03d.jpg #fps滤镜每隔1分钟生成一张,1秒fps=1,10分钟fps=600
ffmpeg -input.flv -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync img%04d.png #关键帧截图
11、生成音视频数据测试流
ffmpeg -re -i lavfi -i abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo -acodec aac -y output.aac #lavfi虚拟音频源abuffer输入
ffmpeg -re -f lavfi "aevalsrc=sin(420*2*PI*t)|cos(430*2*PI*t):c=FC|BC" -acodec aac output.aac #aevalsrc输入(还有诸如anullsrc flite anoisesrc sine来虚拟输入的音频设备生成音频流)
ffmpeg -re -f lavfi -i testsrc=duration=5.3:size=qcif:rate=25 -vcodec libx264 -r:v 25 output.mp4 #testsrc生成
ffmpeg -re -f lavfi -i color=c=red@0.2:s=qcif:r=25 -vcodec libx264 -r:v 25 output.mp4 #color作为视频源
ffmpeg -re -f lavfi -i "nullsrc=s=256x256,geq=random(1)*255:12:128" -vcodec libx264 -r:v 25 output.mp4 #nullsrc作为视频源 随机雪花样
12、音视频倍速
ffmpeg -i input.wav -filter_complex "atempo=0.5" -acodec aacoutput.acc #atempo滤镜 范围0.5~2.0
ffmpeg -re -i input.mp4 -filter_complex "setpts=PTS*2" output.mp4 #atempo滤镜 半速处理,setpts=PTS/2 2倍速处理
1、音视频流封装
av_register_all #注册
avformat_alloc_output_context2 #申请AVFormateContext作为操作的上下文的操作线索
avformat_new_stream #申请AVStream作为存放音视频字幕数据流使用
avformate_write_header #增加目标容器头信息
av_interleaved_write_frame #不断重复执行写入帧数据AVPacket
av_write_all #写容器尾信息
2、音视频流解封装
av_register_all #注册
avformat_open_input #挂接输入文件或媒体流,构建AVFormatContext
avformat_find_stream_info #获取对应的流信息
av_read_frame #循环读取音视频流数据,存储到AVPackets中,然后再进行解码
avformat_close_input #关闭输入文件以及释放资源
3、音视频流转封装
av_register_all #注册
avformat_open_input #构建输入AVFormatContext
avformat_find_stream_info #获得流信息
-av_seek_frame #视频截取时用,视频起始时间定位以及截取视频长度
avformat_alloc_output_context2 #打开输入文件,并关联输出AVFormatContext
avformat_new_stream #申请AVStream
avcodec_copy_context #stream信息复制
avformat_write_header #增加目标容器头信息
av_read_frame #数据包循环读取
av_interleaved_write_frame #数据包循环写入
av_write_traller #写文件尾信息
avformat_close_input #关闭输入
4、内存数据操作
av_register_all #注册
avformat_alloc_context #申请AVFormatContext
avio_alloc_context #申请AVIOContext
read_packet #注册内存数据读取回调
avformat_open_input #打开AVFormatContext
avformat_find_stream_info #查看打开数据流信息
av_read_frame #读取帧数据
avformat_close_input #关闭输入
5、视频解码
avcodec_register_all #
av_packet_alloc #
av_find_Decoder #
av_parser_init #
avcodec_alloc_context3 #
avcodec_open2 #
av_frame_alloc #
av_parser_parse2 #
avcodec_send_packet #
avcodec_receive_frame #
avcodec_free_context #
av_parser_close #
av_frame_free #
av_packet_free #
6、视频编码
avcodec_register_all #
avcodec_find_encoder_by_name #
avcodec_alloc_context3 #
av_packet_alloc #
avcodec_open2 #
av_frame_alloc #
av_frame_get_buffer #
av_frame_make_writable #
avcodec_send_frame #
avcodec_receive_packet #
av_frame_free #
av_packet_free #
avcodec_free_context #
7、音频解码
avcodec_register_all #
av_packet_alloc #
avcode_find_decoder #
av_parser_init #
avcodec_alloc_context3 #
avcodec_open2 #
av_frame_alloc #
av_parser_parse2 #
avcodec_send_packet #
avcodec_receive_frame #
av_get_bytes_per_sample #
avcodec_free_context #
av_parse_close #
av_Frame_free #
av_packet_free #
8、音频编码
avcodec_register_all #
avcodec_find_encoder #
avcodec_alloc_context3 #
avcodec_open2 #
av_packet_alloc#
av_frame_alloc #
av_frmae_get_buffer #
av_frame_make_writable #
avcodec_send_frmae #
avcodec_receive_packet #
av_frame_free #
av_packet_free #
avcodec_free_context #
9、滤镜
滤镜主要有三种类型
avfilter中主要有三种类型的滤镜:音频滤镜、视频滤镜、多媒体滤镜
avfilter_register_all #
avfilter_get_by_name #获取滤镜处理源
avfilter_inout_alloc #申请滤镜结构AVFilterInOut
avfilter_graph_alloc #申请AVFilterGraph
avfilter_graph_create_filter #申请AVFilterContext
av_opt_set_int_list #设置其他参数
avfilter_graph_parse_ptr #建立滤镜解析器
avfilter_graph_config #加入到滤镜配置中
av_buffersrc_and_frame_flags #解码每帧数据给AVFilterContext进行处理
av_buffersink_get_frame #获取滤镜处理后数据