Skip to content

Instantly share code, notes, and snippets.

@max-mapper
Last active January 31, 2025 03:52
Show Gist options
  • Select an option

  • Save max-mapper/43219d6dcb9006042849 to your computer and use it in GitHub Desktop.

Select an option

Save max-mapper/43219d6dcb9006042849 to your computer and use it in GitHub Desktop.
Video stabilization using VidStab and FFMPEG (Mac OS X)

Video stabilization using VidStab and FFMPEG

Examples here use the default settings, see the VidStab readme on GitHub for more advanced instructions.

Here's an example video I made

Install ffmpeg with the vidstab plugin from homebrew

brew install ffmpeg --with-libvidstab

Analyze your video to create a .trf file

This won't modify your video or create a new video, but it should create a new file called transform.trf

ffmpeg -i clip.mov -vf vidstabdetect -f null -

Use the .trf file to create a stabilized video

ffmpeg -i clip.mov -vf vidstabtransform=smoothing=5:input="transforms.trf" clip-stabilized.mov

This should create a new stabilized video called clip-stabilized.mov

Bonus: create a side by side comparison video

Found on a forum here

ffmpeg -i Clip8.mov -i Clip8-vidstab.mov -filter_complex "[0:v:0]pad=iw*2:ih[bg]; [bg][1:v:0]overlay=w" merged.mov
@paulirish

paulirish commented Jul 6, 2017

Copy link
Copy Markdown

Edits from 2021. There's some errors/inefficiencies above due to changes since it was written (in Dec 2015).

Here's the rewritten 2021-era guide

On Mac OS, install ffmpeg and vidstab from homebrew:

brew install ffmpeg
brew install libvidstab

Run stabilization in two passes

There are plenty of options for libvidstab, like shakiness, accuracy, smoothing. The defaults are good, but you may want to experiment. There's even a visual diagnostic mode.

# Assuming the source video is named `clip.mkv`…

# The first pass ('detect') generates stabilization data and saves to `transforms.trf`
# The `-f null -` tells ffmpeg there's no output video file
ffmpeg -i clip.mkv -vf vidstabdetect -f null -

# The second pass ('transform') uses the .trf and creates the new stabilized video.
ffmpeg -i clip.mkv -vf vidstabtransform clip-stabilized.mkv

You now have a clip-stabilized.mkv!

Bonus: create a comparison video

Use the vstack or hstack filter, depending on if you want them stacked vertically or side-by-side:

# vertically stacked
ffmpeg -i clip.mkv -i clip-stabilized.mkv  -filter_complex vstack clips-stacked.mkv

# side-by-side
ffmpeg -i clip.mkv -i clip-stabilized.mkv  -filter_complex hstack clips-sxs.mkv

And here's a two-liner that does everything (because repeating these filenames gets annoying)

export vid="sourcevid.mkv"
ffmpeg -i "$vid" -vf vidstabdetect -f null -; ffmpeg -i "$vid" -vf vidstabtransform "$vid.stab.mkv"; ffmpeg -i "$vid" -i "$vid.stab.mkv"  -filter_complex vstack "$vid.stacked.mkv"

@mrgloom

mrgloom commented Nov 12, 2018

Copy link
Copy Markdown

What is -f null - do?

ghost commented Nov 16, 2018

Copy link
Copy Markdown

@mrgloom ..that is the syntax of the 1st-phase,
here is an extended version, that I use in a Windows-compatible batch-file.

ffmpeg -y -i "%~1" -to "00:10:00.000" -an -vf "setpts=PTS-STARTPTS,vidstabdetect=result=data.trf"   -f null  nul
ffmpeg -y -i "%~1" -to "00:10:00.000" -an -vf "setpts=PTS-STARTPTS,vidstabtransform=input=data.trf" out.mkv

::---------------------------------------------------------------------------------------
::advance features (slower), in additional, the use of the 'unsharp' filter.
::  https://ffmpeg.org/ffmpeg-filters.html#toc-vidstabdetect-1
::  https://ffmpeg.org/ffmpeg-filters.html#toc-vidstabtransform-1
::ffmpeg -y -i "%~1" -to "00:10:00.000" -an -vf "setpts=PTS-STARTPTS,vidstabdetect=result=transforms.trf:shakiness=3:accuracy=10:stepsize=12:mincontrast=0.5:show=0"   -f null  nul
::ffmpeg -y -i "%~1" -to "00:10:00.000" -an -vf "setpts=PTS-STARTPTS,vidstabtransform=input=transforms.trf:smoothing=20:optalgo=gauss:maxshift=-1:maxangle=-1:crop=black:interpol=bicubic:zoom=5,unsharp=5:5:0.8:3:3:0.4" out.mkv

the null is a ffmpeg-preserved phrase, for forced-format encoding, to essentially do not output anything from the encoder-phase, but to still run it, it is used in various filters that need to 'walk over' the video-frames, the output-file is usually handled by the filter, as one of its-given variables. In the example above the output is actually written by the filter, using the file name, given in the result= part (and then again in the input= part for the 2nd-phase).

The nul at the end (missing l) is Windows-related and essentially same as /dev/null on *nix systems, it keeps the standard/error streams empty (less I/O).

@diehl

diehl commented Nov 23, 2018

Copy link
Copy Markdown

So I've installed ffmpeg as indicated above using homebrew on a Mac and run a bunch of tests to stabilize a video. The problem is that none of my attempts have yielded any visible stabilization. Wondering if anyone else has encountered this?

@kumowoon1025

Copy link
Copy Markdown

So I've installed ffmpeg as indicated above using homebrew on a Mac and run a bunch of tests to stabilize a video. The problem is that none of my attempts have yielded any visible stabilization. Wondering if anyone else has encountered this?

Do you mean the output looks identical to input?

@ArneAnka

ArneAnka commented Jan 26, 2019

Copy link
Copy Markdown

Having a hard time with ffmpeg version 4.1, doesn't support either --with-libvidstab or --enable-libvidstab :(

EDIT: using brew on MacOS

@davidschlachter

Copy link
Copy Markdown

@ArneAnka Homebrew is removing options for installing customizing packages, including FFMPEG with libvidstab.

@ArneAnka

Copy link
Copy Markdown

@ArneAnka Homebrew is removing options for installing customizing packages, including FFMPEG with libvidstab.

That was a bummer...

@pnbv

pnbv commented Feb 13, 2019

Copy link
Copy Markdown

@ArneAnka Regarding current state of macOS homebrew installation (with options), feel free to use the following:

brew remove ffmpeg

brew tap pnbv/homebrew-ffmpegvidstab

brew install pnbv/homebrew-ffmpegvidstab/ffmpeg

Check brew tap docs and manage your own custom formula (for vid.stab only you can just duplicate mine, above)

@kpennell

Copy link
Copy Markdown

@pnbv Thanks for making this.

https://docs.brew.sh/Taps

@kibotu

kibotu commented Aug 23, 2019

Copy link
Copy Markdown

https://github.com/varenc/homebrew-ffmpeg#installation-and-usage

brew tap varenc/ffmpeg
brew install varenc/ffmpeg/ffmpeg --with-libvidstab

@mkormendy

Copy link
Copy Markdown

@kibotu what is the difference between varenc's version over pnbv's?

@kibotu

kibotu commented Oct 8, 2019

Copy link
Copy Markdown

well not quite sure exactly, but that one worked for me and the other didn't :/ just wanted to drop this info in case someone else couldn't get the main example to work :3

@yefim

yefim commented Dec 10, 2019

Copy link
Copy Markdown

Looks like varenc/ffmpeg/ffmpeg has been superseded by homebrew-ffmpeg/ffmpeg according to https://github.com/varenc/homebrew-ffmpeg.

@silasfc

silasfc commented Dec 10, 2020

Copy link
Copy Markdown

What is -f null - do?

This (-f null -) occurs because when performing step 1 (vidstabdetect) we do not (yet) need the final video file, but only "transforms.trf", necessary for step 2 (vidstabtransform).

By the way: "-f" specifies the output format (null in this case) for ffmpeg.

@gth001

gth001 commented Oct 31, 2021

Copy link
Copy Markdown

Edits from 2021. There's some errors/inefficiencies above due to changes since it was written (in Dec 2015).

With ffmpeg -i clip.mkv -vf vidstabdetect -f null -I just get the error
No such filter: 'vidstabdetect'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment