FFmpeg中的libavfilter提供了一整套的基于filter的机制,filter本身是一个插件的形式,可以快速的组装需要的效果。filter可以翻译成过滤器,滤镜,可用于检查输入或者输出,按照预定的规则处理并传递这些数据,将输入数据做特定的变换并输出。
语法
filtergraph的BNF语法描述:
Name ::= sequence of alphanumeric characters and '_'
LinkLabel ::= "[" Name "]"
LinkLabels ::= LinkLabel [LinkLabels]
Filter_Arguments ::= sequence of chars (possibly quoted)
Filter ::= [LinkLabels] Name ["=" Filter_Arguments] [LinkLabels]
FilterChain ::= Filter [,FilterChain]
FilterGraph ::= [sws_flags=flags;] FilterChain [;FilterGraph]
FFmpeg filter可以认为是一些预定义的范式,可以实现类似积木的多种功能的自由组合。使用文本描述时我们可以通过标识符指定输入和输出端口,将不同filter串联起来,构成更复杂的filter。
滤镜解析
FFmpeg中filter分为:
- audio filter
- video filter
- Multimedia filter
- source filter(仅输出)
- sink filter(仅输入)
详细的滤镜说明参看:https://ffmpeg.org/ffmpeg-filters.html
视频滤镜
crop
按照特定分辨率裁剪输入视频
截取右下角1/4的区块:crop=in_w/2:in_h/2:in_w/2:in_h/2
scale
使用libswscale库完成视频缩放的filter
宽高缩小一半 scale=in_w/2:in_h/2
宽高固定拉伸比例:scale=1400:900::force_original_aspect_ratio=decrease
pad
视频边界填充
不论输入视频分辨率,统一缩放成1280x720,并且居中展示: scale=1280:720:force_original_aspect_ratio=decrease, pad=1280:720:(1280-in_w)/2:(720-in_h)/2
overlay
视频叠加
视频叠加在右下角,各空10px:overlay=main_w-overlay_w-10:main_h-overlay_h-10
rotate
视频任意角度旋转
逆时针旋转1/6圆周:rotate=-PI/6
视频一直旋转:rotate='2*PI*t:ow=hypot(iw,ih):oh=ow'
hflip & vflip
水平和垂直镜像
edgedetect
边缘检测
fps
按照指定帧率输出视频帧(丢帧或者复制)
drawbox
绘制box
半透明框:drawbox=x=10:y=10:w=100:h=100:color=pink@0.5:t=max
drawgrid
绘制grid(表格)
3x3表格:drawgrid=w=iw/3:h=ih/3:t=2:c=white@0.5
drawtext
绘制text,编译ffmpeg需要添加选项--enable-libfreetype
微软雅黑字体:drawtext=fontfile=/Users/xxx/fonts/MsYaHei.ttf:text='Hello 世界':x=50: y=500:fontsize=80: fontcolor=white
blend & tblend
将两帧视频合并为一帧。
thumbnail
提取缩略图。
transpose
图像转置。
histogram
生成每帧的各颜色分量的直方图。
showinfo
显示视频帧的参数信息,比如时间戳、采样格式、帧类型等。
视频源(video source)
cellatuo、coreimagesrc、mptestsrc、life
视频输出(video sink)
buffersink、nullsink
音频滤镜
adelay
实现不同声道的延时处理。使用参数如下adelay=1500|0|500
,这个例子中实现第一个声道的延迟1.5s,第三个声道延迟0.5s,第二个声道不做调整。
aecho
实现回声效果
amerge
将多个音频流合并成一个多声道音频流。
pan
声道处理,比如立体声变为单声道,或者通过特定参数修改声道或交换声道。
主要有两大类:
- 混音处理,比如下面的例子
pan=1c|c0=0.9*c0+0.1*c1
,实现立体声到单声道的变换; - 声道变换,比如5.1声道顺序调整,
pan="5.1| c0=c1 | c1=c0 | c2=c2 | c3=c3 | c4=c4 | c5=c5"
silencedetect & silenceremove
根据特定参数检测静音和移除静音
volume & volumedetect
实现音量调整和音量检测。
音量调为一半:volume=0.5
ashowinfo
显示每一个audio frame的信息,比如时间戳、位置、采样格式、采样率、采样点数等。
音频源(audio source)
aevalsrc
按照特定表达式生成音频信号。
anullsrc
生成特定的原始音频数据,用于模板或测试。
anoisesrc
生成噪声音频信号。
sine
生成正弦波音频信号。
音频输出(audio sink)
abuffersink
anullsink
多媒体滤镜
ahistogram
将音频转化为视频输出,并显示为音量的直方图。
concat
将音频流、视频流拼接成一个。
metadata & ametadata
操作metadata信息。
setpts & asetpts
改变输入音频帧或视频帧的pts。
showfreqs & showspectrum & showspertrumpic & showvolume & showwaves
将输入音频转换为视频显示,并显示频谱、音量等信息
split & asplit
将输入切分为多个相同的输出。
视频切分3个相同的输出:[in] split=3 [out0][out1][out2]
多媒体源
movie & amovie
从movie容器中读取音频或者视频帧。
视频叠加:
movie=/Users/xxx/video.mp4, scale=180:-1[over];
[in][over] overlay=16:16 [out]
图片叠加:
movie=/Users/xxx/logo.png, scale=180:-1[over];
[in][over] overlay=16:16 [out]
基于ffmpeg命令的例子
简单滤镜
simple filtergraph只有一个输入和输出,ffmpeg命令行中使用-vf
、-af
识别
添加logo图片来推流转播
ffmpeg -re -i ~/video.mp4 -vf "movie=/Users/xxx/logo.png, scale=180:-1[over]; [in][over] overlay=16:16 [out]" -vcodec libx264 -acodec aac -f flv "rtmp://xxx/xxx"
复杂滤镜
complex filtergraph,通常是具有多个输入输出文件,并有多条执行路径;ffmpeg命令行中使用-filter_complex
2x2布局画面(要求输入的video源分辨率一致):
ffmpeg -re -i ~/video_1.mp4 -i ~/video_2.mp4 -i ~/video_3.mp4 -i ~/video_4.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a]; [1:v]negate[b]; [2:v]hflip[c]; [3:v]edgedetect[d]; [a][b]overlay=w[x]; [x][c]overlay=0:h[y]; [y][d]overlay=w:h" -vcodec libx264 -acodec aac -f flv "rtmp://xxx/xxx"
参考
- https://ffmpeg.org/ffmpeg-filters.html
- https://trac.ffmpeg.org/wiki/FilteringGuide
- http://www.cnblogs.com/tocy/p/ffmpeg-filter-intro.html
- https://github.com/xdsnet/other-doc-cn-ffmpeg
- http://blog.csdn.net/fireroll/article/details/27992913
- http://www.jianshu.com/p/137c37561477
- http://javapyer.iteye.com/blog/1989274
- http://wenku.baidu.com/view/296eefcaf90f76c661371af1.html