FFmpeg filter

来自艺搜天下
跳到导航 跳到搜索

scale

ffmpeg -i input -vf scale=iw/2:-1 output  #Resize a 640x480 input to a 320x240 output.  -1是保持宽高比

Some codecs require the size of width and height to be a multiple of n. by setting the width or height to -n:如-2

ffmpeg -i input.jpg -vf scale=320:-2 output_320.png
ffmpeg -i test.tif -vf scale=504:376 -sws_flags bilinear out.bmp #指定算法

filter

Several chained filters form a filter graph(simple and complex).filters in a chain are separated by "," chains by ";"

ffmpeg -i input.jpg -vf "scale='min(320,iw)':'min(240,ih)'" input_not_upscaled.png # 选一个最小值

-filter_complex 与-vf有何区别? -filter_complex 一般用于多个输入输出的。

ffplay -f lavfi -graph "testsrc [out0]; testsrc,hflip [out1]; testsrc,negate [out2]" test3  #lavfi是indev,libavfilter input virtual device.
ffplay -f lavfi testsrc
ffplay -f lavfi -i color=c=red:size=1024x720


ffmpeg -f lavfi -i testsrc -f lavfi -i testsrc -f lavfi -i testsrc -f lavfi -i testsrc -filter_complex \
"[1:v]negate[a]; \
[2:v]hflip[b]; \
[3:v]edgedetect[c]; \
[0:v][a]hstack=inputs=2[top]; \
[b][c]hstack=inputs=2[bottom]; \
[top][bottom]vstack=inputs=2[out]" -map "[out]" -c:v ffv1 -t 5 multiple_input_grid.avi 

4个testsrc inputs,这是一个方便测试的输入源。

begin in the same zero timestamp:setpts=PTS-STARTPTS

ffmpeg -i input -vf select='eq(pict_type\,I)' -vsync vfr output_%04d.png        # to select only I frames
ffmpeg -i input -vf "select='eq(pict_type,I)'" output  #最好使用双引号,这样","不用转义
ffmpeg -i input -vf "yadif=0:-1:0, scale=iw/2:-1" output    # deinterlace then resize

在视频下方打印时间

ffmpeg -i in.mp4 -vf "drawtext=fontfile=/usr/share/fonts/truetype/DroidSans.ttf: timecode='09\:57\:00\:00': r=25: \
x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1" -an -y out.mp4  #PAL 25 fps non drop frame, timecode是刚开始显示时的起始时间 
ffmpeg -i in.mp4 -vf "drawtext=fontfile=/usr/share/fonts/truetype/DroidSans.ttf: timecode='09\:57\:00\;00': r=30: \
x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1" -an -y out.mp4  #NTSC 30 fps drop frame,注意秒后面的冒号变成了分号
ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 output.mpg # ffplay -f lavfi -i "testsrc=duration=10:size=1280x720:rate=30"

drawtext

--enable-libfreetype,drawtext依赖libfreetype画字库,libfontconfig字体库两个库(图片水印要比文字水印简单些,如果想要文字,可以把文字放在图片上。),注:用到strftime的地方已被弃用了

Show the text at a random position, switching to a new position every 30 seconds: 位置随机

ffmpeg -y -i input.mp4  -vf \
"drawtext=fontsize=50:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:text='hello world':x=if(eq(mod(t\,30)\,0)\,rand(0\,(w-text_w))\,x):y=if(eq(mod(t\,30)\,0)\,rand(0\,(h-text_h))\,y)" \
-an out.mp4

在视频下方,从右到左滑动文字,LONG_LINE.txt里面有一行文字(没有换行符)

ffmpeg -y -i input.mp4  -vf  "drawtext=fontsize=50:fontcolor=red:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:textfile=LONG_LINE.txt:y=h-line_h:x=-50*t"  -an out.mp4

文字从视频底部慢慢升到视频上部,直至看不到。 ffmpeg -y -i in.mp4 -vf \

"drawtext=fontsize=50:fontcolor=red:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:textfile=LONG_LINE.txt:y=h-20*t" \
-an out.mp4

每隔3秒显示1秒钟的文字

ffmpeg -y -i in.mp4  -vf \
"drawtext=fontsize=50:fontcolor=red:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:text=elesos:x=100:y=x/dar:enable=lt(mod(t\,3)\,1)" \
-an out.mp4

文本淡入淡出(出现/消失)

#!/bin/sh
DS=1.0 # display start
DE=10.0 # display end
FID=1.5 # fade in duration
FOD=5 # fade out duration
ffplay -f lavfi "color,drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%{eif\\\\: clip(255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID) + (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) )\\, 0\\, 255) \\\\: x\\\\: 2 }"

2个drawtext水平对齐

ffmpeg -y -i input.mp4  -vf \
"drawtext=fontsize=24:fontcolor=red:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:text=DOG:x=10:y=20+24-max_glyph_a,drawtext=fontsize=24:fontcolor=red:fontfile=/d/env/android_sdk/platforms/android-21/data/fonts/DroidSans.ttf:text=cow:x=80:y=20+24-max_glyph_a" \
-an out.mp4

有趣的示例

ffplay -f lavfi -i life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_color=#00ff00,scale=1200:800:flags=16  #life生命
ffplay -f lavfi -i mandelbrot
ffplay -i input.mp4 -vf "crop=iw/2:ih:0:0,split[left][tmp];[tmp]hflip[right];[left][right] hstack" # 左右镜像
直方图和波形 ffplay -f lavfi -i mandelbrot -vf "format=gbrp,split=4[a][b][c][d],[d]histogram=display_mode=0:level_height=244[dd],[a]waveform=m=1:d=0:r=0:c=7[aa],[b]waveform=m=0:d=0:r=0:c=7[bb],[c][aa]vstack[V],[bb][dd]vstack[V2],[V][V2]hstack"

audio channel

取右声道

ffmpeg -i stereo.wav -filter_complex "[0:a]channelsplit=channel_layout=stereo:channels=FR[right]" -map "[right]" front_right.wav

将2个声道分别保存

ffmpeg -i stereo.wav -filter_complex "[0:a]channelsplit=channel_layout=stereo[left][right]" -map "[left]" left.wav -map "[right]" right.wav

将stereo双声道输出到文件中,形成2个独立的mono streams

ffmpeg -i in.mp3 -filter_complex "[0:a]channelsplit=channel_layout=stereo" output.mka

2 × mono → stereo

ffmpeg -i left.mp3 -i right.mp3 -filter_complex "[0:a][1:a]join=inputs=2:channel_layout=stereo[a]" -map "[a]" output.mp3 或者
ffmpeg -i left.mp3 -i right.mp3 -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map "[a]" output.mka

6 × mono → 5.1

ffmpeg -i front_left.wav -i front_right.wav -i front_center.wav -i lfe.wav -i back_left.wav -i back_right.wav \
-filter_complex "[0:a][1:a][2:a][3:a][4:a][5:a]join=inputs=6:channel_layout=5.1[a]" -map "[a]" output.wav

5.1 → 6 × mono

ffmpeg -i in.wav \
-filter_complex "channelsplit=channel_layout=5.1[FL][FR][FC][LFE][BL][BR]" \
-map "[FL]" front_left.wav \
-map "[FR]" front_right.wav \
-map "[FC]" front_center.wav \
-map "[LFE]" lfe.wav \
-map "[BL]" back_left.wav \
-map "[BR]" back_right.wav

Switch stereo channels

ffmpeg -i stereo.mp3 -filter_complex "channelmap=map=FL-FR|FR-FL:channel_layout=stereo" output.mp3

Mute a channel

ffmpeg -i stereo.wav -af "pan=stereo|c1=c1" output.wav # mute the first channel (front left) 

音量

ffmpeg -i input.wav -filter:a "volume=0.5" output.wav  #音量减半
fmpeg -i input.wav -filter:a "volume=1.5" output.wav  #150%

参考

http://trac.ffmpeg.org/wiki/FilteringGuide

http://stackoverflow.com/questions/11640458/how-can-i-generate-a-video-file-directly-from-an-ffmpeg-filter-with-no-actual-in

http://stackoverflow.com/a/15795112/32453

http://trac.ffmpeg.org/wiki/FancyFilteringExamples