micolous.id.au

The result of a blogging accident

Webcam 2000 Timelapse Photography

Happy new year! I should really update my blog more...

This is a simple bash (shell) script to do timelapse photography with [Webcam 2000][wc2k]. In fact, it’ll work with any webcam software that outputs a single JPEG frame when given a HTTP request (as opposed to a multipart image stream).

#!/bin/bash
while [ 1 -lt 2 ]; do
    wget http://localhost:8080/ -O`date +%Y%m%d-%H%M%S.jpg`
    sleep 5s
done

This assumes the camera is running on http://localhost:8080/ I found over the space of two days worth of samples, it took `wget` about a quarter of a second to run on the machine I was using. It doesn’t go for pefect timing, and it will drift a bit from day to day. As you get more photos in the folder, the slower things will run. Bear in mind too that your webcam software takes a bit of time to respond to HTTP requests, and also has to encode the JPEG image frames. I was using a OV51x-chipset camera (Creative Webcam Vista) which actually talks JPEG over USB, so there wasn’t a great quality loss saving everything as JPEG. Plus, the camera was only 15$ anyway, and the image quality isn’t that great so I wasn’t worried.

The picture files are named YYYYMMDD-HHmmss, ie: a photo taken at 1:10:56pm on 29th December, 2008 is called 20081229-131056.jpg. This way, the frames can have their filename sorted, and the frames will be in the correct order.

Then, to encode the resulting frames in XVID, I used:

#!/bin/sh
rm divx2pass.log frameno.avi
mencoder "mf://*.jpg" -mf fps=30:type=jpg:w=800:h=600 -nosound \
   -ovc lavc -sws 2 -ffourcc XVID \
   -lavcopts vcodec=mpeg4:vbitrate=1000:vhq:vpass=1 -noskip \
   -o /dev/null
mencoder "mf://*.jpg" -mf fps=30:type=jpg:w=800:h=600 -nosound \
   -ovc lavc -sws 2 -ffourcc XVID \
   -lavcopts vcodec=mpeg4:vbitrate=1000:vhq:vpass=2 -noskip \
   -o timelapse.avi

In that example I assume 800x600 frames to be played at 30fps, with a 1000kbit/s bitrate. You can also encode in H.264 using the x264 encoder, which results in better quality:

#!/bin/sh
rm divx2pass.log frameno.avi
mencoder "mf://*.jpg" -mf fps=30:type=jpg:w=800:h=600 -nosound \
    -of rawvideo -ovc x264 \
    -x264encopts bitrate=1000:frameref=6:analyse=all:me=umh:subme=7:trellis=2:bframes=1:subq=7:brdo:mixed_refs:weight_b:bime:no_fast_pskip:direct_pred=auto:mixed_refs:nr=200:threads=auto:turbo=2:pass=1 \
    -noskip -o /dev/null
mencoder "mf://*.jpg" -mf fps=30:type=jpg:w=800:h=600 -nosound \
    -of rawvideo -ovc x264 \
    -x264encopts bitrate=1000:frameref=6:analyse=all:me=umh:subme=7:trellis=2:bframes=1:subq=7:brdo:mixed_refs:weight_b:bime:no_fast_pskip:direct_pred=auto:mixed_refs:nr=200:threads=auto:pass=2 \
    -noskip -o timelapse.264
mkvmerge -o timelapse.mkv timelapse.264

`mkvmerge` also allows you to define chapters for your time lapse, which is useful for breaking it up by day (and then, by hour if you like). But to do that you’ll need to write your own [chapters XML file][mchap].

As an example, I did some timelapse photography of a LAN at a friend’s house.

You can also see in my example that I turned on labels in Webcam 2000 to have the current time embedded at the top of each frame. They don’t always match the time on the filename (-2 seconds at most), but it’s still good for debugging things, and it also is a good caption to have in the final video.

I’m now looking into a much more elegant Linux-only solution to this. I’m looking at [camsource][] with anticipation, and I’ll do some experiments with that at some point.

[wc2k]: http://www.webcam2000.info/ [mchap]: http://www.matroska.org/technical/specs/chapters/index.html [camsource]: http://camsource.sourceforge.net/