icon sc-linkedinlogo of codepen-iconlogo of github-iconyoutube play button

notes by Adam Sullovey

web & mobile application developer
practicing in Toronto, ON

Stabilizing GoPro Video with FFmpeg and vid.stab

ffmpeg is open-source video processing software that is used with a command line interface. vid.stab is video stablization software that is integrated into ffmpeg and can stabilize shakey video. Here’s a very impressive demo from vid.stab’s site:

Video from http://public.hronopik.de/vid.stab/

Video from https://gist.github.com/maxogden/43219d6dcb9006042849

Getting the right version of ffmpeg

brew install ffmpeg installed a build off ffmpeg without the vid.stab plugin compiled in. ffmpeg from the ffmpeg site includes vid.stab, so get it from there.

After linking the ffmpeg executable to the /usr/local/bin folder, running ffmpeg shows me this:

$ ffmpeg
ffmpeg version 3.4.2-tessus Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.39.2)
  configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

I’m using ffmpeg 3.4.2, and the configration line includes --enable-libvidstab which is what I need.

Workflow suggestions

It took me lots of trial and error to find settings I liked. To speed up my process, I:

  • use flags -t (duration) and -ss (position) to work on a small segment of the video instead of the whole video
  • use -y flag to allow overwriting previous files if you are trying lots of different settings and don’t need to compare outputs side-by-side.
  • leave out audio with the -an flag
  • scale down video dimensions with the scale filter

I skip these flags for the final encode with the best stablization settings I find.

Test different settings

vid.stab’s docs go into detail about what all the parameters like stepsize, shakiness, and accuracy do. Sometimes I wasn’t sure if changing them made a difference.

There are 2 seteps to the stabilization process:

  1. Generate info about shakes and save it to transform_vectors.trf

    • best improvement comes bigger stepsize. 32 is max
    ffmpeg -t 5 -i GOPR7182.MP4 -vf vidstabdetect=stepsize=32:shakiness=10:accuracy=10:result=transform_vectors.trf -f null - 
    
  2. Stabilize the video using data from the first pass

    • high smoothing (30) makes for more wobbly jello-y frames, 10 looks good to me
    • for best compression quality: remove scale filter, add ‘-preset slow’
    ffmpeg -t 5 -i GOPR7182.MP4 -y -vf vidstabtransform=input=transform_vectors.trf:zoom=0:smoothing=10,unsharp=5:5:0.8:3:3:0.4,scale=480:-1 -vcodec libx264 -tune film -an stabilized.mp4
    

After a bunch of test encodes, I found some settings that worked for my video, and tweaked the commands a bit for my final output.

Final Output

  1. Remove -t 5 so that the whole video is processed

    ffmpeg -i GOPR7182.MP4 -vf vidstabdetect=stepsize=32:shakiness=10:accuracy=10:result=transform_vectors.trf -f null -
    
  2. For the final output:

    • remove scaling
    • use -acodec copy to copy the audio stream from the source video file to the stabilized video file
    • add -tune film and -preset slow which might help with x264’s compression quality
    • remove -y flag so ffmpeg confirms overwriting previous files
    ffmpeg -i GOPR7182.MP4 -vf vidstabtransform=input=transform_vectors.trf:zoom=0:smoothing=10,unsharp=5:5:0.8:3:3:0.4, -vcodec libx264 -tune film -acodec copy -preset slow stabilized.mp4
    

Other stuff

I found the deshake filter did not improve my video much. Vidstab was effective after fiddling with settings for an hour.