Linux webcam timelapse

KewBridge-20191110-121501

This weekend I decided to set up an unused webcam to capture a timelapse of London. There were several things to consider:

  • Where to connect the camera
  • Software to capture photos
  • Accessing and presenting the photos

I connected the camera to a different machine (not the server) that I would be willing to keep switched on. I used guvcview to connect to the camera and check the configuration. Next, I installed and set up motion and set it to take a snapshot every 300 seconds and also stream a live feed to a locally accessible website. This all worked successfully.

My webcam of choice was the Logitech C920, which has a 3:2 2304×1636 sensor, however it is limited to [email protected] for video, and can only manage two photos per second at the full sensor resolution. Since I configured the webcam to take photos every five minutes I hoped to use the full sensor resolution, however, due to motion’s main use case being for detecting motion (hence the name) this was impossible. Also, motion had a very high load on the machine and caused the fan to be noticeably louder, and I was not willing to have so much noise in the room this machine is in.

So I turned instead to a combination of ffmpeg and cron to capture photos. ffmpeg supports input from video devices on linux, so this was a viable alternative. After spending a significant amount of time messing with the configuration options for my specific webcam, I managed to retrieve full-sensor images.

My webcam configuration command:

v4l2-ctl -c brightness=128 
\ -c contrast=128 
\ -c saturation=150 
\ -c sharpness=190 
\ -c backlight_compensation=1 
\ -c exposure_auto_priority=1 
\ -c focus_absolute=0 
\ -c focus_auto=0 
\ -c led1_mode=0

And my ffmpeg command:

ffmpeg -f video4linux2 # V4L2 interface
\ -input_format yuyv422 # raw video input (to access full sensor)
\ -framerate 2 # limit framerate to 2, otherwise V4L2 automatically selects 1080p instead
\ -video_size 2304x1536 -s 2304x1536 # set the desired capture size
\ -i /dev/video0 # my input device
\ -frames 1 # how many frames to take
\ -vf drawtext="fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:text='%{localtime\:%Y-%m-%d %T}':x=20:y=20:fontcolor=white" # date + time watermark on the photo
\ /var/www/html/motion/KewBridge-$(date +%Y%m%d-%H%M%S).jpg

So putting this into cron, it looks like this (escape % symbol):

@reboot v4l2-ctl -c brightness=128 -c contrast=128 -c saturation=150 -c sharpness=190 -c backlight_compensation=1 -c exposure_auto_priority=1 -c focus_absolute=0 -c focus_auto=0 -c led1_mode=0
*/5 * * * * ffmpeg -f video4linux2 -input_format yuyv422 -framerate 2 -video_size 2304x1536 -s 2304x1536 -i /dev/video0 -frames 1 -vf drawtext="fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:text='\%{localtime\:\%Y-\%m-\%d \%T}':x=20:y=20:fontcolor=white"  /var/www/html/motion/KewBridge-$(date +\%Y\%m\%d-\%H\%M\%S).jpg

Using ffmpeg allows me to access the camera when it’s not taking a photo, cpu load on my machine is significantly reduced and I still capture the same number of images.

To access and present these photos, I use apache2 in combination with this lovely apache2 directory listing theme. In fact, these images are public, and you can view them on my website here. (sorry for non-https, but it’s because the machine is on port 8080)

Best of luck in your timelapse adventures! Any questions or clarifications please feel free to comment below.

One Reply to “Linux webcam timelapse”

Leave a Reply

Your email address will not be published. Required fields are marked *