Create a MPEG-4 time lapse video from still images

This is a set of scripts and commands I use to join many JPEG images into a single MPEG-4 video. In this example, we are fetching the images from a web cam. You can use an ordered series from any source. I do this on Linux, but it could also run in cygwin or on a mac.
  1. Script to get the image.
    Here is the script I use to actually do the download the images from the web cam server. It does an initial download, pauses 28 seconds, then gets another image. This gives me two images about 30 seconds apart. It then renames the image to a time stamp.
    cd /var/tmp/webcam_cache/;
    wget --quiet http://www.SomeDomain.com/webcam/picture.jpg;
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg >>/dev/null 2>&1
    sleep 28
    wget --quiet http://www.SomeDomain.com/webcam/picture.jpg;
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg >>/dev/null 2>&1
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg.1 >>/dev/null 2>&1
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg.2 >>/dev/null 2>&1
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg.3 >>/dev/null 2>&1
    jhead -nf%Y_%m_%d-%H_%M_%S picture.jpg* >>/dev/null 2>&1
    Download: get_webcam.sh

  2. Keep running our script!
    I add the following line to my crontab file using the crontab -e command. This will call our get_webcam.sh script every minute between 4am and 9pm. Since the web cam I'm interested is black at night, I don't want to waste bandwidth or have a long boring black screen. Change the frequency to suit your needs.
    * 4-21 * * * /home/username/bin/get_webcam.sh
    Download: crontab

  3. Delete duplicate images
    Once you have all your images, it is time to process. If your source images could have duplicates, like if your web cam URL is actually a cached image somewhere, we want to remove them.
    @file = `ls *[a-z].jpg`;

    foreach $filename (@file)
    {
    chomp($filename);
    $filename2 = $filename;
    $filename2 =~ s/[a-z].jpg/.jpg/ig;
    if (`diff $filename $filename2` eq '')
    {
    print "$filename and $filename2 are the same: delete $filename\n";
    unlink($filename);
    }
    else
    {
    print "!!!! $filename is different\n";
    }
    }
    Download: rm_dups.pl

  4. Rename image in sequence
    Our final assembly wants our images numbered in sequential order.
    @file = `ls *jpg`;

    $count=1;

    foreach $filename (@file)
    {
    chomp($filename);
    $newfilename = sprintf("%05d", $count);
    $newfilename = $newfilename . ".jpg";
    `mv -iv $filename $newfilename`;
    print "mv -iv $filename $newfilename\n";
    $count++;
    }
    Download: name_in_seq.pl

  5. Make a temporary directory (Optional)
    To preserve our original images, we will make a temporary directory to work in.
    mkdir tmp

  6. Shrink images (Optional)
    To shrink the images for a more reasonable final video size, this will shrink the images into the tmp directory
    @file = `ls *jpg`;

    foreach $filename (@file)
    {
    chomp($filename);
    `convert $filename -resize 50% tmp/$filename`
    }
    Download: shrink.pl

  7. Go into your temporary directory (Optional)
    cd tmp

  8. Make the movie!
    This makes the out.mp4 file from our sequential JPGs. You can adjust the bit rate based on your input image sizes, your desired output file size, and the quality of the final movie.
    ffmpeg -r 30 -b 900k -i %05d.jpg out.mp4
    Download: make movie.sh
philip at shuman dot org
http://www.shuman.org