You are in: Home » Software » Linux Webcam Server

Linux Webcam Server

This page describes a camera server made with spare parts and cheap components. The aim of the project is to build a Linux box enclosed in an appropriate case so that it can be installed outdoor; the PC controls a webcam and/or a digital photo camera. The system can be accessed and controlled using a web interface.

This project is several years old, as can be seen by the fact that ancient Linux distributions are mentioned (e.g., Ubuntu 8.04), and the webcam server is a regular, bulky desktop PC instead of a, say, Raspberry PI that I would use today. I plan to bring the instructions up-to-date, but so far had no time to do so. Hopefully, the basic concepts should still be useful.

Table of contents

Getting the parts

My server box is a cheap Intel PIII/450 machine with 128MB of RAM, running Linux Ubuntu 8.04. The machine has a very small disk (4.3GB Maxtor), which is enough given that we are not going to install a graphical user interface with applications and libraries. To cut power consumption, I removed the floppy disk and CD/DVD unit. I added a cheap 10/100 fast Ethernet PCI network card, and a video card which comes handy in case of troubles, although we are not going to hook a monitor to this machine.

Picture of the D-Link DWL-G122 Wireless USB adapter

Wireless connectivity is provided by a D-Link DWL-G122 USB wireless adapter, which is supported under Linux by the open source rt73 module. If you install Ubuntu 8.04, you don't need to do any further configuration, as the rt73 module is already in the kernel, and the DWL-G122 adapter will be automatically recognized as soon as it is plugged in. It is a pity that the DWL-G122 is no longer manufactured by D-Link.

I use a Logitech Quickcam E3500, which is a UVC-compliant device supported under Linux by the Linux UVC modules. The webcam is capable of a physical resolution of 640×480 pixels; it includes a microphone which is supported as well (it appears as an ALSA capture device). Again, Ubuntu 8.04 comes with the uvcvideo module already in the kernel, so this camera works out of the box without any further configuration.

The Quickcam E3500 provides a reasonable resolution (640×480) with a good quality considering its cost (I paid Eur 29.90 for it, now it could be even cheaper), but to get better still images you need a digital photo camera. I bough a used 4Mpx Canon PowerShot A80, which has the important feature of being remote controllable under Linux using gphoto2. You may check the gphoto2 documentation for the list of remote-controllable cameras.

You need to power the camera using an external power supply, as internal batteries will not last for long. Unfortunately, some digital cameras are quite picky about the voltage and current supplied by the external power adapter, so it might be the case that a "generic" power supply does not provide the appropriate current (and/or voltage) for operation. For the Canon PowerShot A80, the user manual says that it needs 4.3V @ 1.5A (Canon AC Adapter Kit ACK600). However, I managed to use a generic power adapter which supplies 4.5V @ 800mA—please note that in the PowerShot A80 power connector, the center pin is positive. This adapter is not enough to power the camera LCD display (which I don't need anyway, as the camera is being controlled by the PC), but is enough for shooting, even using the internal flash. If I try to use the LCD display, the camera complains about low battery and immediately shuts off. Pay attention when powering your camera with an external power supply: it worked for me, but use the above information at your own risk. I'm not responsible for any damage you might cause to your equipment.

Finally, given that the old motherboard I'm using only has two USB1.0 ports, I bought a D-Link DUB-A2 PCI board with 2 additional USB2.0 ports. Needless to say, this board is automatically recognized by Linux, and no special configuration is needed.

This is the list of components I used:

  • Motherboard, PIII processor, 128MB RAM
  • AT Power Supply
  • AT PC case
  • 4.3GB Maxtor EIDE Hard Disk
  • D-Link DUB-A2 dual port USB2.0 PCI card
  • Intel 10/100 PCI Ethernet Adapter (only useful during the first-time system installation, can be removed when the server is finally deployed)
  • S3-Based Graphics Card (only useful for installation and debugging purposes, can be removed when the server is finally deployed)
  • D-Link DWL-G122 Wireless USB Adapter
  • Logitech Quickcam E3500 USB webcam
  • Canon PowerShot A80 4Mpx digital photo camera
  • Wooden box
  • Plexiglas sheet
  • White plastic sheet

Assembling the case

Here are some images of the assembly process. The case is a typical mid-tower, which is being put in horizontal position. The CD/DVD bay offer enough space to contain both the webcam and the Canon A80.

Securing the webcam and photo camera

A rubber bands is used to secure the webcam and photo camera to a wooden plate.

First tests

These are the first tests of the assembled case, with the photo camera and webcam in their final position. The wooden plane which holds the cameras is secured to one side of the CD/DVD bay with a couple of screws.

Fitting the case

The external case of the webcam server is made from an old wooden box. A small window has been cut to let the webcam and photo camera look outside; the window has been covered with Plexiglas, sealed with silicone on the border.

Two pairs of holes (two holes on the bottom, and two on the top of the opposite side) help circulating air from the outside. The holes have been covered with a very fine net to keep insects outside the box.

Finally, the box has been painted in white to reflect some light and hence avoid overheating the inside. The "roof" of the case is made by gluing a white plastic sheet on a wooden base.

The roof of the wooden webcam server case, made of two sheets of white plastic glued on the top of a thin wooden sheet

To cover the front window I used a small piece of Plexiglas. This piece was cut from a larger Plexiglas sheet.

The whole plexiglass sheet, top view The plexiglass window of the webcam server, still with the protective layer (which has been removed for the final assembly)

The final assembly

This is the final assembly. Note the three small pieces of wood which have been attached to the bottom of the case: these are needed to keep the internal PC case in place.

Detail of the window of the webcam server, external view The box of the webcam server, closed, front view The wooden case of the webcam server, opened, full view from the front The wooden case of the webcam server, opened, top view The wooden case of the webcam server, opened, top view Detail of the window of the webcam server, internal view The box of the webcam server on the top of a plastic garden table Detail of the window of the webcam server showing the Canon PowerShot A80, external view

Here is the box with the PC inside. Note the small plastic ball with a green top: it contains hygroscopic material which is able to absorb moisture which might form inside the box. Also, note the big fan on the rear of the PC case: it is used to force circulation of air inside the box, thus avoiding moisture to form on the inside of the window.

Looking outside the small window, from the back of the webcam/photo camera

Configuring the server

I configured the wireless adapter with a static (private) IP address. The adapter automatically connects to my access point using WPA-PSK authentication. To enable WPA authentication, you need to install the wpasupplicant package:

sudo apt-get install wpasupplicant

Now, create the configuration file for wpa-supplicant using the wpa_passphrase command, like this:

$ wpa_passphrase my_network
# reading passphrase from stdin
my_password
network={
        ssid="my_network"
        #psk="my_password"
        psk=a4ea383f2d8e77c45ec859de70b9ea37b30d79153d049cbc88fe6bc86d2cba3d
}

where my_network is the ESSID of your access point, and my_password is your WPA passphrase. You need to paste the output of the wpa_passphrase command into the /etc/wpa_supplicant.conf file. At this point, suppose that you want to automatically connect to the access point when the system boots up. Furthermore, let us assume that the (static) IP address of your webcam server will be 192.168.0.50, and the IP address of the gateway is 192.168.0.71. You need to add something like the following in your /etc/network/interfaces configuration file:

auto wlan0
iface wlan0 inet static
        address 192.168.0.50
        netmask 255.255.255.0
        gateway 192.168.0.71
        wpa-driver wext
        wpa-conf /etc/wpa_supplicant.conf

Note that if you also have a wired interface connected to your system (as I do), it is necessary to prevent it from being activated on boot as well, otherwise you might be unable to route packets correctly. If you have something like this in /etc/network/interfaces

auto eth0
iface eth0 inet static
        address ...
        netmask ...
        gateway ...

you need to remove of comment the auto eth0 line, as follows:

# auto eth0
iface eth0 inet static
        address ...
        netmask ...
        gateway ...

We can assign a better name to the webcam server, for example sacam-wlan.localdomain. To use this name on other machines, it is not necessary to install a full name server somewhere. Client Linux boxes can be configured by simply adding the following line to /etc/hosts:

192.168.0.50 sacam-wlan sacam-wlan.localdomain

Check the Wireless HOWTO and Linux Networking HOWTO for more information.

Using a Webcam

Configuration

If your webcam is an UVC device supported by the uvcvideo module (check the list of UVC supported devices), and your are using a recent kernel, the webcam should be automatically recognized when you plug it into the system. Check the output of dmesg for something like this:

...
[   77.970315] Linux video capture interface: v2.00
[   78.319026] uvcvideo: Found UVC 1.00 device <unnamed> (046d:09a4)
[   78.364309] usbcore: registered new interface driver uvcvideo
[   78.364347] USB Video Class driver (v0.1.0)
...

If the uvcvideo module is successfully loaded, you should find a /dev/video0 device which corresponds to the webcam. To check if everything is fine, you can try the following command:

mplayer tv:// -frames 10 -tv fps=5:driver=v4l2:width=640:height=480:device=/dev/video0 -vo null

The above comment grabs (and immediately drops) 10 frames from the /dev/video0 device at a rate of 5 frames per second.

Live Streaming with ffmpeg

We now describe how to configure the webcam for streaming. In order to enable streaming with the webcam, you can use ffmpeg and ffserver. Install the ffmpeg package (under Ubuntu, you simply do sudo apt-get install ffmpeg), and create a configuration file ~/ffserver.conf for ffserver. The configuration file defines three streams, which are available from other machines as the following URIs:

http://sacam-wlan:8090/webcam.mjpeg
(MJPEG format, can be used for live streaming to any browser without the need of an additional plugin on the receiving side);
http://sacam-wlan:8090/webcam.flv
(Flash video format, good quality, requires a plugin on the receiving side);
http://sacam-wlan:8090/webcam.asf
(ASF format, can stream both audio and video, good quality, requires a plugin or you can use MPlayer or VideoLAN to display the stream)

Issue these commands to start the streams:

ffserver -f ~/ffserver.conf & ffmpeg -v 2 -r 5 -s 640x480 -f video4linux2 -i /dev/video0 http://localhost:8090/webcam.ffm

If you want to stream audio using the Quickcam E3500, you need to install the oss compatibility modules:

sudo modprobe snd-mixer-oss snd-pcm-oss snd-seq-oss

Furthermore, you need to add -f audio_device -i /dev/dsp to the ffmpeg command line; finally you need to tweak the ffserver.conf configuration file to add audio capture (that is, you need to remove the Noaudio directives).

At this point, you can connect from another machine to view the video stream:

mplayer http://sacam-wlan:8090/webcam.asf

The following picture shows the MPlayer window at the receiving side (the picture on the left has been taken with the Canon PowerShot A80, the picture on the right is the live stream in ASF format captured by the Logitech Quickcam E3500):

relevant link

Live Streaming with MJPEG-streamer

MJPEG-streamer is a software which allows you to stream live images in M-JPEG format from any UVC-compliant device. M-JPEG is basically a sequence of JPEG images, and most web browser are able to display a M-JPEG stream without the need of any plugin. Also, in my experience MJPEG-streamer is more robust than ffmpeg, so it is highly recommended.

Still image capture

You can use the webcam to capture single images. Note that at the time of writing, the uvcvideo module does not support still image capture from UVC devices. So, you cannot currently take advantage of higher resolutions which some devices allow for still image captures, but you must grab a single frame from the video stream. However, care must be taken, as many image capture programs initialize and close the video device before/after each capture. It is possible that the image is captured before the webcam has settled, resulting in black or very dark frames.

There are many ways in which you can reliably grab single frames from a UVC video device. I suggest you to consider uvccapture. This tool streams the live video from the webcam, and is able to save selected frames as jpeg images. For example, suppose that we want to grab one frame every 10 seconds, at 640×480 resolution, from the /dev/video0 video device and save the frame into the webcam.jpg file in JPEG format with 95% quality. We can use the following command on the webcam server

uvccapture -d/dev/video0 -x640 -y480 -t10 -owebcam.jpg -q95

Make sure that no other program is accessing the webcam while you run uvccapture, otherwise it will complain not being able to access the video device. You can also grab a single frame from the ffmpeg stream using mplayer. If you have setup a video stream on the server machine according to the instructions on the section above, you can use this command to grab a single frame from it:

mplayer -frames 1 http://sacam-wlan:8090/webcam.asf -vo jpeg

In conditions of low light, every CCD sensor produces noise. However, it is possible to improve the quality of the captured image by averaging multiple frames. You can use this command on the webcam server machine (make sure you are not streaming with ffmpeg, otherwise mplayer will be unable to access the video device):

mplayer tv:// -frames 10 -tv fps=5:driver=v4l2:width=640:height=480:device=/dev/video0 -vo jpeg

This command grabs 10 frames (-frames 10) from the /dev/video0 device, and saves them as jpeg images which are named 00000001.jpg through 00000010.jpg.

You can also grab frames from the ffmpeg stream, as follows:

mplayer -frames 10 http://sacam-wlan:8090/webcam.asf -vo jpeg

The frames can be combined and averaged using the following command (from the ImageMagick package):

convert 000000??.jpg -average frame.jpg

Using a Digital Photo Camera

Configuration

I suggest to get a recent version of the gphoto2 and libgphoto2 packages from the gphoto2 home page. Compile and install libgphoto2 first, and the gphoto2. To access the camera you need to configure udev to have the appropriate permissions on the USB device: please see the gphoto2 instructions on how to do that. Remember that the selector on the top of the camera must be set to Auto, and the selector on the back of the camera must be set to Play, otherwise you will not be able to control the camera.

To try the camera, first make sure that the camera mode to Auto using the top dial, then power on the camera. Now, give the following command:

gphoto2 --set-config capture=1 --set-config capturetarget=0 --capture-image-and-download --set-config capture=0

The --set-config capture=1 command is used to extract the lens and enable shooting a picture. --set-config capturetarget=0 lets the camera store the image on its internal memory, rather than on the memory card. The actual picture is taken with the --capture-image-and-download switch, and the final --set-config capture=0 is used to retract the lens.

If you are using a different photo camera, you might be able to alter the settings used to capture a picture. To query the list of available controls, issue the following command:

gphoto2 --set-config capture=1 --list-config

To query a specific control, use the --get-config control_name parameter as follows:

gphoto2 --get-config capturetarget

Note that it might happen that the camera is capturing to the internal memory card, even if it reports that it is using the internal RAM. In such situation, capture times are longer and errors might occur when the camera internally switches folder. To make sure that you are indeed capturing the the internal RAM, do the following:

gphoto2 --set-config capturetarget=1 --set-config capturetarget=0

that is, set capture to memory card first, and then switch to capture to RAM. At this point the setting should be saved both on your computer and on the camera, so you do not need to issue this command again.

This is a complete capture command:

gphoto2 --set-config capture=1        # Enable capture \ 
        --set-config capturetarget=0  # Capture to internal memory \
        --set-config canonimgsize=2   # Capture at 1024x768 \
        --set-config assistlight=0    # Disable the autofocus assist light \
        -F 1680 -I 30                 # Capture one image every 30s, 1680 images \
        --capture-image-and-download  # Capture and download \
        --filename "%Y%m%d%H%M%S.jpg" # Files will be named YYYYMMDDhhmmss.jpg

More detailed information are in a separate page.

Remote Software Control

Work in progress...

Resources

This page was last updated on October 07 2018 informativa sulla privacy