= FFmpeg Filtering Guide =
[[PageOutline(2-3, Contents)]]
FFmpeg has access to many filters and more are added on a regular basis. To see what filters are available with your build see `ffmpeg -filters`.
== Documentation ==
Refer to the [http://ffmpeg.org/ffmpeg-filters.html FFmpeg filters documentation] for more information and examples for each filter. This wiki page is for user contributed examples and tips, and contributions to this page are encouraged.
== Examples ==
=== Scaling ===
Starting with something simple. Resize a 640x480 input to a 320x240 output.
{{{
ffmpeg -i input -vf scale=iw/2:-1 output
}}}
`iw` is input width. In this example the input width is 640. 640/2 = 320. The `-1` tells the scale filter to preserve the aspect ratio of the output, so in this example the scale filter will choose a value of 240. See the [http://ffmpeg.org/ffmpeg-filters.html#scale FFmpeg documentation] for additional information.
=== Speed up your video ===
See [[How to speed up / slow down a video]] for examples.
=== Filtergraph,Chain,Filter relationship ===
What follows the `-vf` in an ffmpeg command line is a [http://ffmpeg.org/ffmpeg-filters.html#Filtergraph-description filtergraph] description. This filtergraph may contain a number of chains, each of which may contain a number of filters.
Whilst a full filtergraph description can be complicated, it is possible to simplify it for simpler graphs provided ambiguity is avoided.
Remembering that filters in a chain are separated by commas "," chains by a semicolon ";" and that if an input or output is not specified it is assumed to come from the preceding or sent to the following item in the chain.
The following are equivalent:
{{{
ffmpeg -i input -vf [in]scale=iw/2:-1[out] output
ffmpeg -i input -vf scale=iw/2:-1 output # the input and output are implied without ambiguity
}}}
As are:
{{{
ffmpeg -i input -vf [in]yadif=0:0:0[middle];[middle]scale=iw/2:-1[out] output # 2 chains form, one filter per chain, chains linked by the [middle] pad
ffmpeg -i input -vf [in]yadif=0:0:0,scale=iw/2:-1[out] output # 1 chain form, with 2 filters in the chain, linking implied
ffmpeg -i input -vf yadif=0:0:0,scale=iw/2:-1 output # the input and output are implied without ambiguity
}}}
=== multiple input overlay in 2x2 grid ===
[[Image(multiple_input_overlay.jpg)]]
Here four inputs are filtered together using the `-filter_complex` option. In this case all of the inputs are the `-f lavfi -i testsrc` (the [https://ffmpeg.org/ffmpeg-filters.html#color_002c-haldclutsrc_002c-nullsrc_002c-rgbtestsrc_002c-smptebars_002c-smptehdbars_002c-testsrc testsrc source filter]) but could be other inputs.
Within the filtergraph the first input is unchanged, and the other three inputs are individually filtered using [https://ffmpeg.org/ffmpeg-filters.html#hflip hflip], [https://ffmpeg.org/ffmpeg-filters.html#negate negate], and [https://ffmpeg.org/ffmpeg-filters.html#edgedetect edgedetect]. The [https://ffmpeg.org/ffmpeg-filters.html#hstack hstack] and [https://ffmpeg.org/ffmpeg-filters.html#vstack vstack] filters are then used to stack each video into the desired location.
{{{
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
}}}
This next example is the same as above, but uses the [https://ffmpeg.org/ffmpeg-filters.html#pad pad] and [https://ffmpeg.org/ffmpeg-filters.html#overlay-1 overlay] filters instead. The pad filter is used to make an appropriate sized background, and overlay is used to place each video into the correct location. This method is slower than using hstack + vstack as shown above.
{{{
ffmpeg -f lavfi -i testsrc -f lavfi -i testsrc -f lavfi -i testsrc -f lavfi -i testsrc -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[out]" -map "[out]" -c:v ffv1 -t 5 multiple_input_grid.avi
}}}
Be aware that frames are taken from each input video in timestamp order, so it is a good idea to pass all overlay inputs through a `setpts=PTS-STARTPTS` filter to have them begin in the same zero timestamp, such as `[0:v]hflip,setpts=PTS-STARTPTS[a];[1:v]setpts=PTS-STARTPTS[b];[a][b]overlay`.
=== Escaping characters ===
As described in the documentation, it can be necessary to escape commas "," that need to appear in some arguments, for example the select filter:
{{{
ffmpeg -i input -vf select='eq(pict_type\,I)' -vsync vfr output_%04d.png # to select only I frames
}}}
However an alternative, which also allows for white space within the filtergraph, and which may assist in clarity of reading complex graphs, is to enclose the whole filtergraph within double quotes " " thus:
{{{
ffmpeg -i input -vf "select='eq(pict_type,I)'" output # to select only I frames
ffmpeg -i input -vf "yadif=0:-1:0, scale=iw/2:-1" output # deinterlace then resize
}}}
Note that the examples given in the documentation mix and match the use of "full quoting" and "\" escaping, and that use of unusual shells may upset escaping. See [http://ffmpeg.org/ffmpeg-filters.html#Notes-on-filtergraph-escaping Notes on filtergraph escaping] for more information.
=== Burnt in Timecode ===
Using the [http://ffmpeg.org/ffmpeg-filters.html#drawtext-1 drawtext] video filter.
PAL 25 fps non drop frame:
{{{
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
}}}
NTSC 30 fps drop frame
{{{
(change the : to a ; before the frame count)_________________________________________________________
\
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
}}}
=== Scripting your command line parameters ===
If building complex filtergraphs the command line can get very messy so it can help to break things down into manageable pieces. However one needs to be careful when joining them all together to avoid issues due to your shell and escaped characters.
The following example shows a sample bash script containing a filtergraph of one chain with three filters; yadif, scale and drawtext.
{{{
#!/bin/bash
# ffmpeg test script
path="/path/to/file/"
in_file="in.mp4"
out_file="out.mp4"
cd $path
filter="yadif=0:-1:0, scale=400:226, drawtext=fontfile=/usr/share/fonts/truetype/DroidSans.ttf: \
text='tod- %X':x=(w-text_w)/2:y=H-60 :fontcolor=white :box=1:boxcolor=0x00000000@1"
codec="-vcodec libx264 -pix_fmt yuv420p -b:v 700k -r 25 -maxrate 700k -bufsize 5097k"
command_line=(ffmpeg -i "$in_file" -vf "$filter" "$codec" -an $out_file")
echo "${command_line[@]}"
"${command_line[@]}"
exit
}}}
Note that the filtergraph spans more than one line. The echo command shows the full command as it is executed. Useful for debugging.
The array in the $command_line variable helps avoid loss of the quotes which occurs otherwise. Other shells may behave differently.
=== Synthetic Input ===
The [http://ffmpeg.org/ffmpeg-filters.html#color_002c-haldclutsrc_002c-nullsrc_002c-rgbtestsrc_002c-smptebars_002c-smptehdbars_002c-testsrc testsrc source filter] generates a test video pattern showing a color pattern, a scrolling gradient, and a timestamp. This is useful for testing purposes.
This example will create a 10 second output, 30 fps (300 frames total), with a frame size of 1280x720:
{{{
ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 output.mpg
}}}
`ffplay` can also be used to view the resulting filtergraph:
{{{
ffplay -f lavfi -i "testsrc=duration=10:size=1280x720:rate=30"
}}}
You can also specify testsrc as a filter:
{{{
ffmpeg -filter_complex testsrc OUTPUT
}}}
Another type of testsrc is using the [http://ffmpeg.org/ffmpeg-filters.html#color_002c-haldclutsrc_002c-nullsrc_002c-rgbtestsrc_002c-smptebars_002c-smptehdbars_002c-testsrc smptebars source filter]:
{{{
ffmpeg -f lavfi -i "smptebars=duration=5:size=1280x720:rate=30" output.mp4
}}}
Or a color
{{{
./ffmpeg -f lavfi -i color=c=red:size=100x100
}}}
There are other options for generating synthetic video input, see [http://stackoverflow.com/questions/11640458/how-can-i-generate-a-video-file-directly-from-an-ffmpeg-filter-with-no-actual-in here] and [http://stackoverflow.com/a/15795112/32453 here] ("generic equation" filter).
=== Other Filter Examples ===
* [[FancyFilteringExamples|Fancy Filtering Examples]] – Examples for various psychedelic effects and other weird filtering.
* [[Null]] describes the nullsink filter.
=== Developing your own Filters ===
* See [http://wiki.multimedia.cx/index.php?title=FFmpeg_filter_howto FFmpeg filter HOWTO]