Before you start: the
vidstabdetectandvidstabtransformfilters exist only in FFmpeg builds made with--enable-libvidstab. The Ubuntu / Debian package fromapt install ffmpeghas them (see Installation). Check your own build withffmpeg -filters | grep vidstab.
How Video Stabilization Works
FFmpeg stabilizes video with the libvidstab library, in two passes with one filter each:
vidstabdetect(pass 1) measures the camera movement and writes it to a file,transforms.trfby default.vidstabtransform(pass 2) reads that file and shifts and rotates each frame to cancel the shake.
Two passes are needed because a smooth camera path can only be worked out once the movement of the whole clip is known.
Basic Two-Pass Stabilization
Pass 1 (motion detection):
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf vidstabdetect -f null /dev/null
This writes transforms.trf to the current folder. -f null /dev/null throws the video output away, because only the motion file is needed.
Pass 2 (stabilization):
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf vidstabtransform output.mp4
This reads transforms.trf and writes the stabilized video.
Tuning Stabilization Strength
Pass 1: shakiness
shakiness (1–10, default 5) sets how hard the detector looks for motion. Raise it for very shaky footage:
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabdetect=shakiness=8:accuracy=15" -f null /dev/null
| Parameter | Range | Default | Description |
|---|---|---|---|
shakiness |
1–10 | 5 | Motion range to detect |
accuracy |
1–15 | 15 | Detection accuracy (higher = slower) |
result |
path | transforms.trf |
Output motion file |
Pass 2: smoothing and crop
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=smoothing=30:crop=black" output.mp4
| Parameter | Default | Description |
|---|---|---|
smoothing |
15 | Temporal smoothing radius (frames). Higher = smoother, but the corrections grow: more automatic zoom with the default optzoom=1, wider borders with optzoom=0 |
crop |
keep |
Border handling: keep (fill the edge from the previous frame; the default) or black (fill with black) |
zoom |
0 | Additional zoom percentage; positive zooms in, negative zooms out |
optzoom |
1 | Automatic zoom: 0 = none, 1 = optimal static zoom (default), 2 = optimal dynamic zoom |
interpol |
bilinear |
Interpolation method: no, linear, bilinear, bicubic |
cropdefaults tokeep, notblack. If you leave it out, the borders are filled from the previous frame (it looks like smearing) instead of being painted black. Addcrop=blackif you want black borders.ffmpeg -h filter=vidstabtransformconfirms the default: it prints(default keep).
Hiding Black Borders with Zoom
Stabilization shifts each frame to cancel the camera movement, which can leave black borders at the edges. By default (optzoom=1), vidstabtransform already zooms in just enough to hide them; only very strong movement still shows them. zoom adds more zoom on top of that:
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=smoothing=20:zoom=5:crop=black" output.mp4
zoom=5 adds 5% on top of the automatic zoom, which hides more of the borders. You lose a little more of the picture at the edges.
Complete Pipeline with Custom Paths
In scripts, or when you process several files, set the path of the motion file yourself: result= in pass 1 and input= in pass 2.
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabdetect=result=/tmp/transforms.trf" -f null /dev/null
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=input=/tmp/transforms.trf:smoothing=20" output.mp4
Installation
Ubuntu / Debian
The standard package works. You do not need a PPA or a custom build.
sudo apt install ffmpeg
On Ubuntu, apt-get install ffmpeg installs libvidstab1.1 as a dependency. The apt log shows it:
Unpacking libvidstab1.1:amd64 (1.1.0-2build1) ...
The configuration: line of ffmpeg -version lists it too:
--enable-libvidstab --enable-libvorbis --enable-libvpx
To check your own FFmpeg:
ffmpeg -version | grep -o -- "--enable-libvidstab"
Some guides say Ubuntu’s apt build leaves out libvidstab. That is wrong at least for version 6.1.1-3ubuntu5 on Ubuntu 24.04: it is built with --enable-libvidstab, and the vidstab filters work without a rebuild. ffmpeg -filters | grep vidstab shows what your own build has.
If your build really lacks it, install libvidstab-dev and rebuild FFmpeg with --enable-libvidstab, or download a static build from BtbN/FFmpeg-Builds. Installing libvidstab-dev alone does not help. It only adds the library’s development headers and does not change an FFmpeg that is already built.
macOS (Homebrew)
brew install ffmpeg-full
Homebrew’s plain ffmpeg formula does not include libvidstab; ffmpeg-full does. ffmpeg-full is keg-only, so add it to your PATH as brew info ffmpeg-full explains. Then check with ffmpeg -filters | grep vidstab.
Windows
Download a build from gyan.dev/ffmpeg/builds. The “full” build includes libvidstab.
Verifying Your Build
ffmpeg -filters 2>/dev/null | grep vidstab
If both vidstabdetect and vidstabtransform appear, your FFmpeg can stabilize video.
Limitations
- libvidstab works best on moderate shake. Very strong shake, such as footage shot while running, can end up with visible warping or too little correction.
- vidstab always needs two passes; it has no single-pass mode. FFmpeg’s separate
deshakefilter works in a single pass. - Zoom cuts off part of the picture. The more shake there is to correct, the more zoom you need to hide the borders, and the more of the frame is lost.