Ubuntu - Stabilize your camcorder video with MELT and Vid.stab

Contents[Hide]

Ubuntu

Nowadays, street video shooting is becoming a reality.
Who is not having a smartphone, a point-and-shoot camera with video capabilities or even a HD camcorder ?

These devices are affordable, light-weight, very compact and easy to use. Whatever happens around you, you are able to record it on the spot. But, on the other end, as these devices are compact and light, they are not very steady. Your recordings tend to be shaky !

Till date, there was no simple solutions under Linux to stabilize (unshake) videos. One of the first one I used was transcode with vid.stab plugin. This stabilization plugin is very efficient. But the transcode tool is giving lots of trouble as soon as you want to encode your resulting video to h264. In fact, the interface between transcode and ffmpeg is type of 'broken'.

Short time back, the MLT framework has integrated a port of vid.stab stabilization plugin. That is a very good news as MLT framework provides a command-line tool melt which interfaces very well with FFmpeg libraries for h264 encoding.

This article will explain how to easily post-process any video file to stabilize (unshake) it. It will use :

  • latest version of MELT, a command-line tool from MLT framework, which comes now with vid.stab stabilization filter
  • latest version of FFmpeg to re-encode the resulting video with h264 codec and aac audio

It will explain 2 different approaches :

  • stabilization thru command-line
  • stabilization directly from Nautilus, thru a Nautilus script

Following procedures have been tested on Ubuntu Precise 12.04 and Ubuntu Saucy 13.10.

1. Install Packages

First step is to install all needed packages.

The stabilzation process uses :

YAD is a GUI very similar to Zenity, but with lot more possibilities.

It can be launched from command-line, it can display multiple fields and can display progression bar. We will use it for the user interface part of the Nautilus script.

1.1. Ubuntu 13.10+

Under Ubuntu 13.10+, all needed packages are available from standard repositories :

# sudo apt-get install ffmpeg melt yad

1.2. Ubuntu 12.04 LTS

Stabilization process needs FFmpeg 0.9+. You can check your installed version with :

# ffmpeg -version

Latest version of FFmpeg can be easily installed from a PPA :

# sudo add-apt-repository ppa:jon-severinsson/ffmpeg
# sudo apt-get update
# sudo apt-get upgrade --full-resolver

The vid.stab stabilization filter we are looking for is available since MLT 0.7.6. You can check your installed version with :

# melt -version

So, we again need to update MLT. We will use the Kdenlive stable PPA which provides also the right MLT version.

# sudo add-apt-repository ppa:sunab/kdenlive-release
# sudo apt-get update
# sudo apt-get install melt

As it is not available in Ubuntu 12.04 repositories, we will get yad from the well-known GetDeb PPA.

# echo "deb http://archive.getdeb.net/ubuntu oneiric-getdeb apps" | sudo tee -a /etc/apt/sources.list.d/getdeb.list
# wget -q -O- http://archive.getdeb.net/getdeb-archive.key | sudo apt-key add -
# sudo apt-get update && sudo apt-get install yad

2. Stabilize your Video

We now have everything to unshake our video files.

The stabilization process is done in 2 steps :

2.1. Calculation of Stabilization parameters

First step is done with the following command :

# melt yourvideo.mov -filter videostab2 -consumer xml:yourvideo.xml all=1 real_time=-2

This will start the stabilization analysis and will generate yourvideo.xml, containing all the stabilization parameters.

You can add some specific vid.stab parameters in the command line. Parameters are available from http://www.mltframework.org/bin/view/MLT/FilterVideostab2.

For example, if you only want to increase the shakiness level to 8, command line will become :

# melt yourvideo.mov -filter videostab2 shakiness=8 -consumer xml:yourvideo.xml all=1 real_time=-2

2.2. Encoding of resulting video

Second step is to encode the final video with the results of stabilization analysis.

For the final stabilized video, we will use the result of previous stage as video input and the original video as audio input.

In this example, the final video will be encoded with h264 video at 5Mbits and aac audio at 128Kbits.

# melt yourvideo.xml -audio-track yourvideo.mov -consumer avformat:yourvideo-stab.mp4 vcodec=libx264 b=5000k acodec=aac ab=128k tune=film preset=slow

Specific x264 encoding parameters can be added at the end of the command line. Here I've added a tune & preset parameter.
All available parameters can be found with the command x264 --fullhelp.

You now have a yourvideo-stab.mp4 file with your stabilized video !

3. Nautilus script for Stabilization

The following procedure and script will allow to launch a video file stabilization directly from Nautilus.

You will then be able to start the stabilization from a right click on the file within Nautilus and to follow the progression of the operation on a graphical user interface. You will also be able to stop the process at any time by closing the interface.

3.1. Nautilus script

Here comes the main stabilization script. Its algorithm is quite simple :

  • It ask for the main stabilization/encoding parameters
  • It calculates the stabilization parameters
  • It encodes the final file in h264 & aac in a mp4 container

For each of the 2 processing stages, the script will :

  1. launch the analysis or encoding command, asking for a progression log
  2. get the pid of the running process
  3. start a progression loop where it checks every second the process existence and the progression log

Every progression loop is linked to a YAD progress window, which displays the result of the log analysis.

If the YAD window is closed by the user, current process is killed and following steps are canceled.

The script header allows you to setup some variables to adjust :

This script should be placed under $HOME/.gnome2/nautilus-scripts/Video - Stabilize

Under Gnome 3.8, nautilus scripts should be placed under $HOME/.local/share/nautilus/scripts.
You'll need to adjust path accordingly.

$HOME/.gnome2/nautilus-scripts/Video - Stabilize

#!/bin/sh
# --------------------------------------------
#  Video Shooting Stabilization
#  Command-line & Nautilus script
#  Depends on :
#   * mlt 0.7.6 minimum
#   * ffmpeg 0.9 minimum
#   * yad
#  Revision history :
#  04/03/2012 - Creation by N. Bernaerts
#  04/04/2012 - Add codecs as parameters
# -------------------------------------------

# ----------------------------------------------------
#  User variable section
#  Please, do not modify anything out of this section
# ----------------------------------------------------

# You can define default encoding codec and rates in kbits/s
VIDEO_CODEC="libx264"
VIDEO_RATE=5000
AUDIO_CODEC="libmp3lame"
AUDIO_RATE=128

# You can setup optional parameters for stabilization & h264 encoding
OPTION_STABILIZER="shakiness=4"
OPTION_ENCODER="tune=film preset=slow"

# ------------------------------------
#  check if script is called
#  as command-line or nautilus-script
# ------------------------------------
if [ -n "$1" ]
then
  # at least one parameter, called as command-line
  FILE_PATH="$1"
else
  # no parameter, called as a nautilus script
  FILE_PATH="${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS}"
fi

# ----------------
#  Initialisation
# ----------------
STABILIZE="TRUE"
CANCELED="FALSE"

# go in the video file directory
cd $(dirname "${FILE_PATH}")

# generate the filenames
ORIGINAL=$(basename "${FILE_PATH}")
FILE_NAME=`echo ${ORIGINAL} | sed 's/^\(.*\)[.].*$/\1/g'`
FILE_STAB="${FILE_NAME}"-stab.mp4
FILE_LOG="${FILE_NAME}".log
FILE_MLT="${FILE_NAME}".mlt

# --------------------------------------------
#  function to follow progress of the process
# --------------------------------------------
MELT_PROGRESS()
{
# loop till the end of melt process
PERCENTAGE=0
while [ "$PERCENTAGE" != "100" ]
do    
  # wait for 1 second
  sleep 1

  # if process is still running
  RESULT=`ps aux | awk '{print $2 }' | grep $PID`
  if [ "$RESULT" -eq "$PID" ]
  then
    # get percentage of completion
    PERCENTAGE=`cat "${FILE_LOG}" | tail -n 1 | sed 's/^.*percentage:[ ]*\([0-9]*\).*$/\1/g'`
  else
    # else, force percentage to 100
    PERCENTAGE="100"
  fi 

  # display current percentage
  echo $PERCENTAGE
done | yad --width=400 --height=30 --progress --auto-close --title "$TITLE" --text "$TEXT"

# if encode has been canceled, kill the current process
CANCELED="FALSE"
RESULT=`ps aux | awk '{print $2 }' | grep $PID`
if [ "$RESULT" -eq "$PID" ]
then
  kill $PID
  CANCELED="TRUE"
fi
}

# -----------------------------------
#  Selection of encoding parameters
# -----------------------------------
TITLE="Stabilization of ${ORIGINAL}"
TEXT="\nFinal video file will use $VIDEO_CODEC video and $AUDIO_CODEC audio.\nPlease select the encoding parameters :\n"
CHOICE=`yad  --title "$TITLE" --text "$TEXT" --image "dialog-question" --form --field=Stabilize:CHK ${STABILIZE} --field="Video bitrate (kbits):NUM" ${VIDEO_RATE} --field="Audio bitrate (kbits):NUM" ${AUDIO_RATE}`

# extract the parameters
STABILIZE=`echo ${CHOICE}  | cut -d"|" -f1`
VIDEO_RATE=`echo ${CHOICE} | cut -d"|" -f2 | cut -d"," -f1 | cut -d"." -f1`
AUDIO_RATE=`echo ${CHOICE} | cut -d"|" -f3 | cut -d"," -f1 | cut -d"." -f1`

# -------------------------
#  Phase 1 : Stabilization
# -------------------------
if [ "$STABILIZE" = "TRUE" ]
then
  # set text & title of progress window
  TITLE="1 - Stabilization of ${ORIGINAL}"
  TEXT="This phase may take a long time ...\n"

  # start the stabilization phase with melt and videostab2 filter
  melt -progress "${ORIGINAL}" -filter videostab2 ${OPTION_STABILIZER} -consumer xml:"${FILE_MLT}" all=1 real_time=-2 2>"${FILE_LOG}" &

  # get the process id
  PID=`ps -ef | grep melt | grep "${ORIGINAL}" | sed 's/^'$USER'[ ]*\([0-9]*\).*$/\1/g'`
 
  # follow the stabilization progress
  MELT_PROGRESS
fi

# if canceled, no encoding to be done
if [ "$CANCELED" = "TRUE" ]
then
  VIDEO_RATE=0
fi

# --------------------
#  Phase 2 : Encoding
# --------------------
if [ "$VIDEO_RATE" -gt "0" ]
then
   # set text & title of progress window
  TITLE="2 - Encoding of ${FILE_STAB}"
  TEXT="This phase may also take a long time ...\n"

  # start melt encoding process with stabilized video and original audio
  melt -progress "${FILE_MLT}" -audio-track "${ORIGINAL}" -consumer avformat:"${FILE_STAB}" vcodec=${VIDEO_CODEC} b=${VIDEO_RATE}k acodec=${AUDIO_CODEC} ab=${AUDIO_RATE}k ${OPTION_ENCODER} 2>"${FILE_LOG}" &

  # get the process id
  PID=`ps -ef | grep melt | grep "${FILE_MLT}" | sed 's/^'$USER'[ ]*\([0-9]*\).*$/\1/g'`
 
  # follow the stabilization progress
  MELT_PROGRESS
fi

# ------------------------------------
#  cleaning-up of all temporary files
# ------------------------------------
rm "${FILE_LOG}"
rm "${FILE_MLT}"

exit 0

Make sure the script is executable :

# wget -O "$HOME/.gnome2/nautilus-scripts/Video - Stabilize" http://bernaerts.dyndns.org/download/ubuntu/nautilus/video-stabilize
# chmod a+x "$HOME/.gnome2/nautilus-scripts/Video - Stabilize"

3.2. Let's go

From Nautilus, you can now select any video file, do a right click, select Scripts menu and select Video - Stabilize sub-menu.

You will get a dialog box allowing you to specify the main parameters.

ubuntu-melt-script-parameters

Then video stabilization process will start …

ubuntu-melt-script-phase1

ubuntu-melt-script-phase2

At the end of the second stage, you stabilized video file will be available in the same directory as the original, with the -stab.mp4 postfix.

This Nautilus script has been tested, but not as long as I wished.
In case it contains any bug or if you have some update ideas which can benefit everybody, don't hesitate to contact me by email (see below).

Hope it helps.

This article is published "as is", without any warranty that it will work for your specific need.
If you think this article needs some complement, or simply if you think it saved you lots of time & trouble,
just let me know at This email address is being protected from spambots. You need JavaScript enabled to view it. . Cheers !

icon linux icon debian icon apache icon mysql icon php icon piwik icon googleplus