This is just a log of how I set up my webcam for this site. I tried to set this camera up some time ago using Motion, a Linux package for motion detection, but failed miserably. Since I still had the camera sitting around, I figured I might as well try putting it to use. My requirements were that I wanted to have the camera automatically take pictures on whatever interval I specify, and I wanted the output to be in jpeg format for viewing on the web.
There is nothing really special about the box. It is a an old Dell Pentium 3 workstation running FreeBSD 6.0-stable, and has 4 USB ports.
The camera is a Micro Innovations IC50C color USB webcam. You can purchase one for around $15 on ebay if you want, I got mine for free from a friend who had it laying around his house.
There is quite a bit of software required, but thanks to FreeBSD's ports system, it takes all of four commands to install everything I needed to capture jpeg or any other format images.
# cd /usr/ports/graphics/spcaview # make install clean ... # cd /usr/ports/graphics/netpbm # make install clean ...
It may take a little while to download, build, and install all the dependencies. I had most of the dependant packages already installed, so it only took me around 10 minutes.
The spcaview package installs two programs, spca5shot and spca5view. I haven't messed with spca5view much yet, but from what I have read it is used for viewing video. The other program, spca5shot, takes still images or motion jpegs, if your camera supports it. My camera only supports capturing PPM images, running spca5shot with the -j flag to capture jpegs threw an error complaining about an unsupported format. PPM is a postscript format, which is not very suitable for my web viewing requirement. This is where netpbm comes in, it has converters for almost every graphic format imaginable. The key program I needed was ppmtojpeg, which as you can guess converts PPM files to JPEG images.
Now that I had all the software to capture images, I did some tests. First I plugged in the camera to one of the USB ports. This generated the following output on tty0.
ugen0: Sunplus Technology Co., Ltd. Generic Digital camera, rev 1.10/0.00, addr 3
First I ran spca5shot with the -i flag to have it spit out some information about the camera's capabilites.
# spca5shot -i USB SPCA5XX camera found. Type Flexcam 100 (SPCA561A) [spca5xx_probe:8362] Camera type S561 All threads purged from ugen0.1 [spca5xx_getcapability:2256] maxw 352 maxh 288 minw 160 minh 120 [spca561_init:461] Find spca561 USB Product ID 561 All threads purged from ugen0.1 --- video capability --- name: Flexcam 100 Cameratype: 1 channels: 1 maxwidth: 352 maxheight: 288 minwidth: 160 minheight: 120 --- size and format --- size: 640x480 352x288 320x240 176x144 160x120 native input format: S561 output format: 24bit RGB --- video picture (initial value) --- brightness: 1920 hue: 0 colour: 0 contrast: 38464 whiteness: 0 depth: 24 palette: 4 All threads purged from ugen0.1 Done.
This didn't really give me much information that I needed, since it mostly related to video. I was curious about the "All threads purged from ugen0.1" messages, so I spent some time googling. From what I gathered reading the mailing list archives this is a problem in the in FreeBSD 6.0. When I move the camera to a new machine I will try FreeBSD 6.1 which was recently released and see if it has the same problem. For now it doesn't seem to cause any issues.
The syntax for spca5shot is very simple. By default it outputs to stdout, but we will override that with the -o flag, which allows you to specify an output file. You could also use > to pipe the output to a file. There are quite a few other options, including the -d flag to specify the device to use, but it will automatically check all of your ugen devices looking for a camera if you don't specify one. In my case I saw almost no difference speed-wise in specifying the device, so I let the program find it for me. I did some testing trying different resolutions and formats, but it turned out that the defaults were the best my camera could do, so I only specified the output file.
# spca5shot -o ~/test.ppm USB SPCA5XX camera found. Type Flexcam 100 (SPCA561A) [spca5xx_probe:8362] Camera type S561 All threads purged from ugen0.1 [spca5xx_getcapability:2256] maxw 352 maxh 288 minw 160 minh 120 [spca561_init:461] Find spca561 USB Product ID 561 All threads purged from ugen0.1 All threads purged from ugen0.1 All threads purged from ugen0.1 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 brightness 1920, colour 0, contrast 38464, hue 0, whiteness 0 All threads purged from ugen0.1 Done.
I now had a PPM file from my webcam. Next I used ppmtojpeg from the netbpm package to convert it to a jpeg image.
# ppmtojpeg ~/test.ppm > ~/test.jpg
Now I had my jpeg image. What did I take a picture of you ask?
That's right, my shoulder and the closet in my bedroom.
Now that I could capture an image and convert it to jpeg, I just needed a script to do all of that at once. One other thing I needed the script to do was copy the image file to my web server. I really didn't feel like mounting an NFS share just for that, so I decided to use SCP. I already had a set of SSH keys that don't require a password that I use for other purposes, so I just copied the private key to ~/.ssh/id_rsa on this box. Now, I am far from a shell scripting master, but after a couple minutes of hacking this is what I came up with.
#!/bin/sh spca5shot -D0 -o /home/nesteffe/shot.ppm ppmtojpeg /home/nesteffe/shot.ppm > /home/nesteffe/shot.jpg scp /home/nesteffe/shot.jpg nesteffe@dragon:/www/images/shot.jpg sleep 9
The -D0 flag for spca5shot tells it not to print any debugging messages. I added the "sleep 9" line to make the script wait 9 seconds before exiting. This was required for the scheduling of the image captures, which I did using supervise. The supervise program was installed with qmail, and basically just ensures that a script is always running. By making the script wait 9 seconds before exiting, supervise will make sure a new image is created about 10 seconds or so (1 second to actually capture the image, plus the 9 second sleep) by restarting the script. I used this method for scheduling the image captures because cron can only run jobs every minute at the fastest, and I wanted more flexibility in how often I capture images.
I put the above script in a file called /var/service/cam/run, and chmoded it to 764. I didn't give anyone except root rights to run the script, since root privledges are required to run spca5shot anyway.
Going forward I would like to create a daemon to capture the images. The method I am using now to schedule the script is a hack job, but I didn't know any other way to accomplish this task quickly. I am not sure how I will do this yet, but since I know a bit of perl, C, and few other languages, I am sure google can help me.
If you want to view the product of all this work, visit the webcam page.