I’ve had this WiFi enabled webcam looking down my driveway for over a year now. Since I work at home, it’s great for monitoring when deliveries, Jehova’s Witnesses and family members approach the house.
It is also useful for checking on home when I am away on vacation. I have grown to rely on it daily and I keep a small browser window with the video stream always up on one of my work monitors.
Up until this week, however, I didn’t remotely save any captured data from the camera. After reading about a home break-in over the weekend I decided to fix this. Below are the steps to quickly and easily store and display a series of 5-minute increment snapshot from your home webcam to a remote server.
Here is a sample day from my camera and my detailed reply on Wantbox to someone who was looking for an outdoor wireless security camera.
Prerequisites
- A web accessible webcam.
- A remote server (shared is fine, no root access needed, I use and love Dreamhost).
The basic steps
- Setup your home router to allow remote viewing of your webcam.
- Figure out what the image file for your video stream is. Mine is “snapshot.cgi”. View source on the web page that displays your video stream and search the HTML until you find the correct file.
- Create a shell script on your server which wgets and saves the image.
- Create a cron job which fires off the script every five minutes.
- Monitor and enjoy knowing that you’ll at least have a nice snapshot of you home intruder’s car.
Note: my simple little webcam has a few modes: one is a live feed from the camera and the other is tailored for smart phones and updates the camera image every few seconds. It was on this second page where I found the appropriate video image file for grabbing.
The cron job
Nothing fancy here, simply “crontab -e” on your remote server and add the following entry to call the shell script every five minutes.
# Grab a screen cap every 5 minutes 0,5,10,15,20,25,30,35,40,45,50,55 * * * * ~/yourdomain.com/assets/grab_snap.sh
The shell script
The shell script does a few things:
- Parses the current date into its year, month and day parts. You need this because the snaps are stored in a directory like “/2011/10/18/”.
- Checks if today’s target directory exists, if not it creates it and creates a symbolic link to a standard “index.html” file.
- Fires off wget to grab a screen grab from your home webcam. A sample snapshot filename is “snap_19:55_PDT.jpg”.
#!/bin/bash
#
# Grab and save a frame from our home driveway camera.
# Usage: ./grab_snap.sh
# Sample: 0,5,10,15,20,25,30,35,40,45,50,55 * * * * ~/yourdomain.com/grab_snap.sh
#
curryear="`date +%Y`"
currmonth="`date +%m`"
currday="`date +%d`"
currtime="`date +%H:%M_%Z`"
outfile="/home/you/yourdomain.com/snaps/${curryear}/${currmonth}/${currday}/snap_${currtime}.jpg"
target="http://yourhome.com:50881/snapshot.cgi?${currday}-${currtime}"
# Check if this year's directory exists
if [ ! -d ~/yourdomain.com/snaps/${curryear} ]; then
mkdir ~/yourdomain.com/snaps/${curryear}
fi
# Check if this month's directory exists
if [ ! -d ~/yourdomain.com/snaps/${curryear}/${currmonth}/ ]; then
mkdir ~/yourdomain.com/snaps/${curryear}/${currmonth}/
fi
# Check if this day's directory exists
if [ ! -d ~/yourdomain.com/snaps/${curryear}/${currmonth}/${currday}/ ]; then
mkdir ~/yourdomain.com/snaps/${curryear}/${currmonth}/${currday}/
ln -s ~/yourdomain.com/assets/index.html ~/yourdomain.com/snaps/${curryear}/${currmonth}/${currday}/index.html
fi
# Grab the screen cap
wget --user=yourcamerausername --password='yourcamerapassword' --output-document=$outfile $target
The index.html file
This index file shows all of the thumbnails from your webcam and displays the full sized image when you rollover one (see demo). There’s a little bit of CSS embedded in the head. There are no other dependencies outside of this index file and the captured data.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<meta http-equiv="refresh" content="600">
<style>
body {background-color:#000;}
h1 {color:#FFF; margin-left:50px;}
a {color:#FFF; text-decoration:none;}
a:hover {color:#CCC; text-decoration:underline;}
.container {width:1470px;}
#preview {float:right; width:640px; height:480px; background-color:#222; border:1px solid #FFF;}
.hour_row {width:880px;}
.row_label {color:#666; width:50px; height:48px; display:inline-block;}
.thumb {width:64px; height:48px; background-color:#111; display:inline-block;}
</style>
<script type="text/javascript">
date=new Array();
date=document.location.pathname.split("/");
title="Snaps from "+date[2]+"-"+date[3]+"-"+date[4];
document.title=title;
// Thumbnail rollover function
function update_preview(src,hr) {
document.getElementById('preview').style.marginTop=hr*40+"px";
document.getElementById('preview').style.background='url(' + src + ')';
}
</script>
</head></pre>
<pre lang="foo"><body>
<div class='container'>
<div id='preview'></div>
<script type="text/javascript">
document.write("<h1>Snaps from <a href='../..'>"+date[2]+"</a>-<a href='..'>"+date[3]+"</a>-"+date[4]+"</h1>");
for (h=0; h<=23; h++) {
hour=h;
// Pad single digit hours
if (h<10) hour='0'+h;
// Calc AM/PM and convert from pacific (server) to eastern time
am_pm=' am';
if (h>8 && h<21) am_pm=' pm';
eastern=h+3;
if (eastern>12) { eastern-=12; }
if (eastern>12) { eastern-=12; } // yes, really needed, take it out and see why
document.write("<div class='hour_row'>");
document.write("<div class='row_label'>"+hour+":00<br>"+eastern+am_pm+"</div>");
for (m=0; m<=55; m+=5) {
minute=m;
if (m<10) minute='0'+m; // Pad single minutes
document.write("<div class='thumb'><img src='snap_"+hour+":"+minute+"_PDT.jpg' ");
document.write("title='"+eastern+":"+minute+am_pm+"' width='64' height='48' ");
document.write("onmouseover='update_preview(this.src,"+hour+")'></div>");
}
document.write("</div>");
}
</script>
</div>
</body>
</html>
Use an .htaccess file to protect your directory (for Apache users)
Personally, I don’t want people rooting around my webcam image history, so I have protected my server by placing the following .htaccess file at the root level of my camera archive web server.
You can create the appropriate entry in the passwd file by executing: “htpasswd -c /home/you/.htpasswds/passwd yourname”. When you are prompted enter the password that your would like to use.
AuthName "Dialog prompt" AuthType Basic AuthUserFile /home/you/.htpasswds/passwd Require valid-user
That’s all she wrote. If and when you improve on my default index.html file please share it with me!











4 Responses to “How to capture and remotely save a webcam screen grab”
on January 7th, 2012 at 9:11 pm #
[...] Here is the new Gallery pages showing snaps with 5 minutes intervals. This setup has been sourced from Mitch Fournier’s Blog [...]
Hello Mitch, Thanks for your Post, I have converted your c shell script and turned it into a CGI Perl Script. Great job. You can see the result here:
http://www.sharpnet.co.uk/webcam/snaps/2012/01/07/
Here is a better cron tab entry
*/5 * * * * ~/yourdomain.com/assets/grab_snap.sh
Hello Mitch
I raly like your site and what you are doing.
now I did like to do this also on my site, to capture and remotely save the webcam screen grabs.
but I can not get it working. Now I am a newbi in this stuff. Do you have this somewhere I litle more in detailed discribed where I could read it. Thank you very much if you could help me.
Joe