Before you start: the vidstabdetect and vidstabtransform filters exist only in FFmpeg builds made with --enable-libvidstab. The Ubuntu / Debian package from apt install ffmpeg has them (see Installation). Check your own build with ffmpeg -filters | grep vidstab.

How Video Stabilization Works

FFmpeg stabilizes video with the libvidstab library, in two passes with one filter each:

  1. vidstabdetect (pass 1) measures the camera movement and writes it to a file, transforms.trf by default.
  2. 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

crop defaults to keep, not black. If you leave it out, the borders are filled from the previous frame (it looks like smearing) instead of being painted black. Add crop=black if you want black borders. ffmpeg -h filter=vidstabtransform confirms 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 deshake filter 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.