Monday, October 3, 2011

Automating webcam time lapse

Leave a Comment

Ever wanted to see how stuff changes over time? With a webcam this can be done quite easily.
Set up cron/windows scheduled tasks  to go fetch a new image every minute/hour/day and compile the images to a video.
I've made a really simple script for making a sliding window view of the past 24 hours that can be used on any image feed.

Getting the images and making the video

I wanted to use ffmpeg since it has a solid command line interface and it's available on most platforms. ffmpeg wants the image files in a sequential order, so we need to rename the images after adding the newest image.

I'm not a bash expert (I usually solve stuff like this in Perl - when you have a hammer etc.), so it's probably other ways to make this work, but at least I think my code is quite easy to read and understand:

# Make sure we are in the right directory and that it has an images directory
cd /path/to/where/our/timelapse/stuff/will/be
mkdir -p images

# Delete files older than 1 day
find images/ -name '*.jpg' -mtime +0 -delete

# Download the latest image
curl '' > images/newest.jpg

# Create a prefix so files won't get overwritten in the rename process
prefix="images/$(date +%s)_"

# Rename files, oldest to newest from 0 .. xxx
for oldname in `ls -tr images/*.jpg`
  count=$(( $count + 1 ))
  newname=$prefix$(printf "%.4d.jpg" $count);
  mv $oldname $newname

# Make a video of the images, not overwriting the existing
ffmpeg -r 60 -b 4096k -i "$prefix%04d.jpg" -s 580x384 "$prefix.flv"
mv "$prefix.flv" timelapse.flv

Here I've set the framerate to 60 and the bitrare to 4096 kbit/s. (The less variation in the images the higher the frame rate). With a size of 580 x 384, this gives a file of roughly 11 mb (this will vary with the type of images of course).

Scheduling the process

Depending on your platform, there are several ways of adding scheduled tasks, but on Mac and *nix it's easiest just to add a cron job and silence the script's output so it won't fill your mailbox.

* * * * * bash /path/to/where/our/timelapse/stuff/will/be/ > /dev/null 2>&1

Adding the player

One would think that finding a decent free player capable of streaming video would be easy. I've looked at a lot of players and the only free and really good player I've found is Flowplayer (please leave a comment if you have other good alternatives). It offers lots of configuration options, but what I really like is how easy it is to implement:

<!doctype html> 
    <script type="text/javascript" src="./flowplayer-3.2.6.min.js"></script> 
    <a href="./timelapse.flv"
      style="display:block;width:580px;height:384px;" id="player"></a> 
    <script language="JavaScript"> 
      flowplayer("player", "./flowplayer-3.2.7.swf", {
          clip: { autoPlay: false, autoBuffering: true },

Just download the player and you're ready to go.

The results

I made the video below for a local ski resort.  In order to get a smooth time lapse we need to fetch the images (atleast) every minute, but  rendering the video is quite CPU intensive so this is done once every hour. The result is a "sliding window" from the last 24 hours:

Feel free to copy, although it's nice if you leave a comment and a link back to this article if you find it useful!