Webcam and Video Wizardry

(For more resources related to this topic, see here.)

Setting up your camera

Go ahead, plug in your webcam and boot up the Pi; we'll take a closer look at what makes it tick.

If you experimented with the dwc_otg.speed parameter to improve the audio quality during the previous article, you should change it back now by changing its value from 1 to 0, as chances are that your webcam will perform worse or will not perform at all, because of the reduced speed of the USB ports..

Meet the USB Video Class drivers and Video4Linux

Just as the Advanced Linux Sound Architecture (ALSA) system provides kernel drivers and a programming framework for your audio gadgets, there are two important components involved in getting your webcam to work under Linux:

  • The Linux USB Video Class (UVC) drivers provide the low-level functions for your webcam, which are in accordance with a specifcation followed by most webcams produced today.
  • Video4Linux (V4L) is a video capture framework used by applications that record video from webcams, TV tuners, and other video-producing devices. There's an updated version of V4L called V4L2, which we'll want to use whenever possible.

Let's see what we can find out about the detection of your webcam, using the following command:

pi@raspberrypi ~ $ dmesg

The dmesg command is used to get a list of all the kernel information messages that of messages, is a notice from uvcvideo.

Kernel messages indicating a found webcam

In the previous screenshot, a Logitech C110 webcam was detected and registered with the uvcvideo module. Note the cryptic sequence of characters, 046d:0829, next to the model name. This is the device ID of the webcam, and can be a big help if you need to search for information related to your specifc model.

Finding out your webcam's capabilities

Before we start grabbing videos with our webcam, it's very important that we find out exactly what it is capable of in terms of video formats and resolutions. To help us with this, we'll add the uvcdynctrl utility to our arsenal, using the following command:

pi@raspberrypi ~ $ sudo apt-get install uvcdynctrl

Let's start with the most important part—the list of supported frame formats. To see this list, type in the following command:

pi@raspberrypi ~ $ uvcdynctrl -f

List of frame formats supported by our webcam

According to the output of this particular webcam, there are two main pixel formats that are supported. The first format, called YUYV or YUV 4:2:2, is a raw, uncompressed video format; while the second format, called MJPG or MJPEG, provides a video stream of compressed JPEG images.

Below each pixel format, we find the supported frame sizes and frame rates for each size. The frame size, or image resolution, will determine the amount of detail visible in the video. Three common resolutions for webcams are 320 x 240, 640 x 480 (also called VGA), and 1024 x 768 (also called XGA).

The frame rate is measured in Frames Per Second (FPS) and will determine how "fuid" the video will appear. Only two different frame rates, 15 and 30 FPS, are available for each frame size on this particular webcam.

Now that you know a bit more about your webcam, if you happen to be the unlucky owner of a camera that doesn't support the MJPEG pixel format, you can still go along, but don't expect more than a slideshow of images of 320 x 240 from your webcam. Video processing is one of the most CPU-intensive activities you can do with the Pi, so you need your webcam to help in this matter by compressing the frames first.

Capturing your target on film

All right, let's see what your sneaky glass eye can do!

We'll be using an excellent piece of software called MJPG-streamer for all our webcam capturing needs. Unfortunately, it's not available as an easy-to-install package for Raspbian, so we will have to download and build this software ourselves.

Often when we compile software from source code, the application we're building will want to make use of code libraries and development headers. Our MJPG-streamer application, for example, would like to include functionality for dealing with JPEG images and Video4Linux devices.

  1. Install the libraries and headers for JPEG and V4L by typing in the following command:

    pi@raspberrypi ~ $ sudo apt-get install libjpeg8-dev libv4l-dev

  2. Next, we're going to download the MJPG-streamer source code using the following command:

    pi@raspberrypi ~ $ wget http: //
    viewvc/mjpg-streamer/mjpg-streamer/?view=tar -O mjpg-streamer.tar.gz

    The wget utility is an extraordinarily handy web download tool with many uses. Here we use it to grab a compressed TAR archive from a source code repository, and we supply the extra -O mjpg-streamer.tar.gz to give the downloaded tarball a proper filename.

  3. Now we need to extract our mjpg-streamer.tar.gz article, using the following command:

    pi@raspberrypi ~ $ tar xvf mjpg-streamer.tar.gz

    The tar command can both create and extract archives, so we supply three fags here: x for extract, v for verbose (so that we can see where the files are being extracted to), and f to tell tar to use the article we specify as input, instead of reading from the standard input.

  4. Once you've extracted it, enter the directory containing the sources:

    pi@raspberrypi ~ $ cd mjpg-streamer

  5. Now type in the following command to build MJPG-streamer with support for V4L2 devices:

    pi@raspberrypi ~/mjpg-streamer $ make USE_LIBV4L2=true

  6. Once the build process has finished, we need to install the resulting binaries and other application data somewhere more permanent, using the following command:

    pi@raspberrypi ~/mjpg-streamer $ sudo make DESTDIR=/usr install

  7. You can now exit the directory containing the sources and delete it, as we won't need it anymore:

    pi@raspberrypi ~/mjpg-streamer $ cd .. && rm -r mjpg-streamer

  8. Let's fre up our newly-built MJPG-streamer! Type in the following command, but adjust the values for resolution and frame rate to a moderate setting that you know (from the previous section) that your webcam will be able to handle:

    pi@raspberrypi ~ $ mjpg_streamer -i " -r 640x480 -f
    30" -o " -w /usr/www"

    MJPG-streamer starting up

    You may have received a few error messages saying Inappropriate ioctl for device; these can be safely ignored. Other than that, you might have noticed the LED on your webcam (if it has one) light up as MJPG-streamer is now serving your webcam feed over the HTTP protocol on port 8080. Press Ctrl + C at any time to quit MJPG-streamer.

  9. To tune into the feed, open up a web browser (preferably Chrome or Firefox) on a computer connected to the same network as the Pi and enter the following line into the address field of your browser, but change [IP address] to the IP address of your Pi. That is, the address in your browser should look like this: http://[IP address]:8080.

    You should now be looking at the MJPG-streamer demo pages, containing a snapshot from your webcam.

    MJPG-streamer demo pages in Chrome

    The following pages demonstrate the different methods of obtaining image data from your webcam:

    • The Static page shows the simplest way of obtaining a single snapshot frame from your webcam. The examples use the URL http://[IP address]:8080/?action=snapshot to grab a single frame. Just refresh your browser window to obtain a new snapshot. You could easily embed this image into your website or blog by using the <img src = "http://[IP address]:8080/?action=snapshot"/> HTML tag, but you'd have to make the IP address of your Pi reachable on the Internet for anyone outside your local network to see it.
    • The Stream page shows the best way of obtaining a video stream from your webcam. This technique relies on your browser's native support for decoding MJPEG streams and should work fne in most browsers except for Internet Explorer. The direct URL for the stream is

      http://[IP address]:8080/?action=stream.

    • The Java page tries to load a Java applet called Cambozola, which can be used as a stream viewer. If you haven't got the Java browser plugin already installed, you'll probably want to steer clear of this page. While the Cambozola viewer certainly has some neat features, the security risks associated with the plugin outweigh the benefits of the viewer.
    • The JavaScript page demonstrates an alternative way of displaying a video stream in your browser. This method also works in Internet Explorer. It relies on JavaScript code to continuously fetch new snapshot frames from the webcam, in a loop. Note that this technique puts more strain on your browser than the preferred native stream method. You can study the JavaScript code by viewing the page source of the following page:

      http://[IP address]:8080/javascript_simple.html

    • The VideoLAN page contains shortcuts and instructions to open up the webcam video stream in the VLC media player. We will get to know VLC quite well during this article; leave it alone for now.
    • The Control page provides a convenient interface for tweaking the picture settings of your webcam. The page should pop up in its own browser window so that you can view the webcam stream live, side-by-side, as you change the controls.

Viewing your webcam in VLC media player

You might be perfectly content with your current webcam setup and viewing the stream in your browser; for those of you who prefer to watch all videos inside your favorite media player, this section is for you. Also note that we'll be using VLC for other purposes further in this article, so we'll go through the installation here.

Viewing in Windows

Let's install VLC and open up the webcam stream:

  1. Visit and download the latest version of the VLC installer package(vlc-2.0.5-win32.exe, at the time of writing).
  2. Install VLC media player using the installer.
  3. Launch VLC using the shortcut on the desktop or from the Start menu.
  4. From the Media drop-down menu, select Open Network Stream….
  5. Enter the direct stream URL we learned from the MJPG-streamer demo pages (http://[IP address]:8080/?action=stream), and click on the Play button.
  6. (Optional) You can add live audio monitoring from the webcam by opening up a command prompt window and typing in the following command:

    "C:\Program Files (x86)\PuTTY\plink" pi@[IP address] -pw
    [password] sox -t alsa plughw:1 -t sox - | "C:\Program Files
    (x86)\sox-14-4-1\sox" -q -t sox - -d

Viewing in Mac OS X

Let's install VLC and open up the webcam stream:

  1. Visit and download the latest version of the VLC dmg package for your Mac model. The one at the top, vlc-2.0.5.dmg (at the time of writing), should be fne for most Macs.
  2. Double-click on the VLC disk image and drag the VLC icon to the Applications folder.
  3. Launch VLC from the Applications folder.
  4. From the File drop-down menu, select Open Network….
  5. Enter the direct stream URL we learned from the MJPG-streamer demo pages (http://[IP address]:8080/?action=stream) and click on the Open button.
  6. (Optional) You can add live audio monitoring from the webcam by opening up a Terminal window (located in /Applications/Utilities ) and typing in the following command:

    ssh pi@[IP address] sox -t alsa plughw:1 -t sox - | sox -q -t sox
    - -d

Viewing on Linux

Let's install VLC or MPlayer and open up the webcam stream:

  1. Use your distribution's package manager to add the vlc or mplayer package.
  2. For VLC, either use the GUI to Open a Network Stream or launch it from the command line with vlc http://[IP address]:8080/?action=stream
  3. For MPlayer, you need to tag on an MJPG article extension to the stream, using the following command: mplayer "http://[IP address]:8080/?action= stream&stream.mjpg"
  4. (Optional) You can add live audio monitoring from the webcam by opening up a Terminal and typing in the following command:

    ssh pi@[IP address] sox -t alsa plughw:1 -t sox - | sox -q -t sox - -d

Recording the video stream

The best way to save a video clip from the stream is to record it with VLC, and save it into an AVI article container. With this method, we get to keep the MJPEG compression while retaining the frame rate information.

Unfortunately, you won't be able to record the webcam video with sound. There's no way to automatically synchronize audio with the MJPEG stream. The only way to produce a video article with sound would be to grab video and audio streams separately and edit them together manually in a video editing application such as VirtualDub.

Recording in Windows

We're going to launch VLC from the command line to record our video:

  1. Open up a command prompt window from the Start menu by clicking on the shortcut or by typing in cmd in the Run or Search fields. Then type in the following command to start recording the video stream to a article called myvideo.avi, located on the desktop:

    C:\> "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" http://[IP
    address]:8080/?action=stream --sout="#standard{mux=avi,dst=%UserPr

    As we've mentioned before, if your particular Windows version doesn't have a C:\Program Files (x86) folder, just erase the (x86) part from the path, on the command line.

  2. It may seem like nothing much is happening, but there should now be a growing myvideo.avi recording on your desktop. To confirm that VLC is indeed recording, we can select Media Information from the Tools drop-down menu and then select the Statistics tab. Simply close VLC to stop the recording.

Recording in Mac OS X

We're going to launch VLC from the command line, to record our video:

  1. Open up a Terminal window (located in /Applications/Utilities) and type in the following command to start recording the video stream to a file called myvideo.avi, located on the desktop:

    $ /Applications/ http://[IP
    address]:8080/?action=stream --sout='#standard{mux=avi,dst=/Users/

    Replace [username] with the name of the account you used to log in to your Mac, or remove the directory path to write the video to the current directory.

  2. It may seem like nothing much is happening, but there should now be a growing myvideo.avi recording on your desktop. To confirm that VLC is indeed recording, we can select Media Information from the Window drop-down menu and then select the Statistics tab. Simply close VLC to stop the recording.

Recording in Linux

We're going to launch VLC from the command line to record our video:

Open up a Terminal window and type in the following command to start recording the video stream to a file called myvideo.avi, located on the desktop:

$ vlc http://[IP address]:8080/?action=stream

Replace [username] with your login name, or remove the directory path to write the video to the current directory.

Detecting an intruder and setting off an alarm

Let's dive right in to the wonderful world of motion detection!

The basic idea of motion detection is pretty simple from a computer's point of view—the motion detection software processes a continuous stream of images and analyzes the positions of the pixels that make up the image. If a group of contiguous pixels above a certain threshold starts to change from one frame to the next, that must be something moving. The tricky part of motion detection is weeding out false positives triggered by naturally occurring changes in light and weather conditions.

  1. We'll be working with a motion detection application called Motion.Install it using the usual command:

    pi@raspberrypi ~ $ sudo apt-get install motion

  2. With Motion installed, the next step is to create a configuration article for our webcam. The Motion installation puts a sample configuration article inside the /etc/motion directory. We will use this configuration article as a template and modify it for our needs.
    1. First, create a configuration directory for Motion in your home folder with the following command:

      pi@raspberrypi ~ $ mkdir .motion

    2. Then copy the example configuration from /etc/motion into your new directory:

      pi@raspberrypi ~ $ sudo cp /etc/motion/motion.conf ~/.motion

    3. The configuration file is still owned by the root user, so let's make it ours by using the chown command:

      pi@raspberrypi ~ $ sudo chown pi:pi ~/.motion/motion.conf

    4. Now we can open up the configuration file for editing.

      pi@raspberrypi ~ $ nano ~/.motion/motion.conf

Creating an initial Motion configuration

Motion has plenty of options to explore, and it's easy to be overwhelmed by them all. What we're aiming for, at this point, is to get a basic demonstration setup going with as few bells and whistles as possible. Once we've established that the main motion detection functionality is working as expected, we can move on to the advanced, extra features of Motion.

Apart from the regular, helpful comments preceded by the # character, the ; character is used to make individual configuration directives inactive. ; tunerdevice /dev/tuner0, for example, means that the line will be ignored by Motion.

We will now go through the configuration directives and pause to explain or change options, from top to bottom:

  • videodevice, v4l2_palette, width, height, and framerate: It is indeed important to update these directives if you want Motion to grab video directly from your webcam. However, we will not be doing this. Instead, we will be feeding the video stream that we have already set up with MJPG-streamer, into Motion. We will do this for three reasons:
    • MJPG-streamer is simply better at grabbing video from webcams using advanced V4L2 features.
    • You'll learn how to connect conventional IP security cameras to Motion.
    • We can utilize the tiny HTTP server of MJPG-streamer and you can keep watching your stream at a high frame rate.
  • netcam_url: Uncomment and change the line to read

    netcam_url http: //localhost:8080/?action=stream

    The netcam_url directive is used to feed network camera feeds into Motion, like our MJPG-streamer feed. Since we're running MJPG-streamer on the same machine as Motion, we use localhost instead of the IP address of the Pi.

  • netcam_http: Uncomment and change this to netcam_http 1.1 to speed up the communication with MJPG-streamer.
  • gap: Change value to 2 for this initial setup. This will be the number of seconds it takes for our alarm to reset as we're testing the system.
  • output_normal: Change to off for now, as we don't need any JPG snapshots to be stored until we have everything set up.
  • ffmpeg_cap_new: Change this to off during setup; we don't need any movies to be written either, until we have everything set up.
  • locate: Change to on for our initial setup, because it'll help us understand the motion detection process.
  • text_changes: Also change to on for our initial setup as it'll help us dial in the sensitivity.
  • webcam_maxrate: Change this value to match the frame rate of your MJPG-streamer video feed.
  • webcam_localhost: You'll need to change this to off, because we'll be monitoring the webcam from another computer and not from the Pi.
  • control_port: This value needs to be changed to 7070 (or any number you like, above 1024) because it's currently conficting with the port we're using for MJPG-streamer.
  • control_localhost: Also needs to be changed to off as we'll be accessing Motion from another computer and not from the Pi.
  • on_event_start: Uncomment and change the line to read on_event_start speaker-test -c1 -t sine -f 1000 -l 1. This is our temporary alarm sound. Don't worry, we'll find something better in a minute.

That's it for now; press Ctrl + X to exit, press y when prompted to save the modifed buffer, and then press Enter to confirm the filename to write to.

Initial Motion setup configuration

Trying out Motion

All right, let's take our Motion system out for a spin!

  1. First, make sure that MJPG-streamer is running. You can make it run in the background by applying the -b fag, as shown in the following command:

    pi@raspberrypi ~ $ mjpg_streamer -b -i " -r 640x480 -f
    30" -o " -w /usr/www"

    Note the number in parenthesis that mjpg_streamer provides when forking to the background. This is called a Process ID (PID), and can be used to stop the mjpeg_streamer application by passing it to the kill command:

    pi@raspberrypi ~ $ kill [PID]

    You can explore all processes running on your Pi using the following command:

    pi@raspberrypi ~ $ ps aux

  2. Point your webcam away from yourself and any movement in the room and type in the following command:

    pi@raspberrypi ~ $ motion

    Motion with one camera starting up

    Press Ctrl + C at any time, to quit Motion.

  3. Now try waving your hand in front of the webcam. If your Pi sent out a high-pitched note through the speakers and you see messages from the speaker test application on the console, we have managed basic motion detection! Even if you didn't trigger anything, keep reading to find out what's going on with the detection system.
  4. In your web browser, visit the address http://[IP address]:8081. You should be looking at your feed from MJPG-streamer, but with a few key differences—a clock in the lower-right corner, and the number of changed pixels in the upper-right corner. If you're looking, instead, at a gray image with the text unable to open video device, there's most likely a problem with MJPG-streamer or the netcam_url line.

    Studying the number of changed pixels is one of the best ways to understand the motion detection system. The number will spike whenever you move the camera, but should come to a rest at zero as Motion learns about light sources and applies an automatic noise filter to minimize the risk of false positives.

  5. Now if you wave your hand in front of the camera, the pixel counter should climb and a rectangle will be drawn onto those areas in the image where Motion detected the largest changes in pixels. If the number of pixels climbs over the threshold value (1500 by default) set in the configuration article, an event will fire, which is currently set to play the high-pitched tone. When no motion has been detected for the number of seconds specified by the gap value (60 by default, currently 2), the event ends and a new event may begin.
  6. Let's look at an alternative method for tweaking the detection system called setup mode. Open up a new tab in your browser and enter the address http://[IP address]:7070 in the address bar.

    What you're seeing here is a simple web admin interface to control Motion. When we hook up more than one webcam to Motion, each camera will have its own thread and configuration, but right now there's only one thread and one configuration labeled All. Click on this to proceed.

  7. The little menu system is not very advanced but does contain a few convenient shortcuts: detection allows us to temporarily disable the motion alarm, and action allows us to write JPG snapshots or quit Motion. The config shortcut is perhaps the most useful one and allows us to try out different configuration directives on the fly. Click on config and then click on list to get a list of the currently loaded configuration directives. Now click on setup_mode, select on from the drop-down menu, and click on the set button.
  8. Now switch back to your camera tab (http://[IP address]:8081); you'll be viewing the camera in setup mode. Now wave your hand in front of the webcam again; you'll see the largest areas of changed pixels highlighted in blue, and minor changes in gray tones. You'll also notice three counters—D: for difference in pixels, L: for labels (connected pixel areas), and N: for noise-level.

    Motion camera in setup mode

    The configuration directives you'd want to tweak if you find that the motion detection is performing poorly can all be found under the Motion Detection Settings section of the configuration file.

Collecting the evidence

Now that we've established an initial working Motion setup, we have to decide what actions we want the system to take upon detection. Sounding an alarm, saving images and videos of the detected activity, logging the activity to a database, or alerting someone via e-mail are all valid responses to detection.

Let's create a directory to hold our evidence:

pi@raspberrypi ~ $ mkdir ~/evidence

We're going to revisit the configuration article, but this time, we're setting up the system for use in the real world. Once again, we'll go through the configuration article and pause to explain or change options, from top to bottom. You'll need to type in the following command first to open the article for editing:

pi@raspberrypi ~ $ nano ~/.motion/motion.conf

  • gap: We're changing this back to the default 60 seconds.
  • output_normal: Change this to best to save a JPG snapshot when the biggest change in motion occurs. We're also going to record a movie, so you won't miss anything.
  • ffmpeg_cap_new: Change this to on to record a movie of the event that triggers the detection.
  • ffmpeg_video_codec: Change this to mpeg4 to get a video that can be played back on the Pi itself with OMXPlayer, or on another computer with VLC.
  • locate: Change this back to off, as we don't want a rectangle drawn onto our evidence.
  • text_changes: Same for this one; change it back to off for cleaner video output.
  • target_dir: Change this to our newly created /home/pi/evidence directory.
  • webcam_maxrate: Change this back to 1 to lower the CPU usage. We can still directly watch the MJPG-streamer feed at 30 FPS.
  • on_event_start: It's up to you whether you want to keep the alarm tone. Why not record a better one yourself with Sound eXchange (SoX)— perhaps a robot voice saying "intruder alert!"—and then play it back with a simple sox command.

Real world Motion configuration

Now if you start Motion again and trigger a detection, a video article will start recording the event to your ~/evidence directory, and after the 60-second gap, a JPG snapshot with the largest change in motion will be written to the same location.

Viewing the evidence

Whenever a new article is recorded, the filename will be announced in the Motion console log:

[1] File of type 8 saved to: /home/pi/evidence/01-20130127111506.avi
[1] File of type 1 saved to: /home/pi/evidence/01-20130127111526-04.jpg

To view the videos on the Pi itself, use omxplayer and specify a filename:

pi@raspberrypi ~ $ omxplayer ~/evidence/01-20130127111506.avi

Before we view the images, we need to install the FIM (Fbi IMproved) image viewer:

pi@raspberrypi ~ $ sudo apt-get install fim

Now we can start fim and point it to an individual image (by specifying its filename) or a collection of images (by using the wildcard asterisk character):

pi@raspberrypi ~ $ fim ~/evidence/*.jpg

Press Enter to show the next image, and press Q to quit fim.

Hooking up more cameras

If you've got an extra webcam at home, perhaps built into a laptop, it would be a shame not to let it help out with the motion detection mission, right?

We're going to look at how to connect more camera streams to Motion. These streams might come from conventional IP security cameras, but the same method works equally well for webcams on Windows and Mac computers, with some tinkering.

Preparing a webcam stream in Windows

We'll be using webcamXP to add additional cams in Windows:

  1. Visit to download the latest version of the webcamXP application installer (wlite551.exe, at the time of writing). webcamXP is free for private use (single video source).
  2. Install webcamXP using the installer.
  3. Launch webcamXP using the shortcut (webcamXP 5) from the Start menu.
  4. You will be prompted for the version of webcamXP that you would like to run. You can select webcamXP Free for our purposes, and then click on the OK button.
  5. Right-click on the large image frame and select your webcam from the list; it will most likely be located under PCI / USB (WDM Driver).
  6. You should be able to confirm that the stream is working by opening up a new tab in your browser and entering the following address in the address bar, but change [WinIP] to the IP address of your Windows computer:
  7. http://[WinIP]:8080/cam_1.cgi
  8. If the stream is working all right, proceed to add it to the Motion setup. You may quit webcamXP to stop the stream at any time.

Preparing a webcam stream in Mac OS X

We'll be using VLC to add additional cams in Mac OS X:

  1. You should have VLC installed already as per the instructions in the Viewing your webcam in VLC media player section.
  2. Launch VLC from the Applications folder.
  3. From the File drop-down menu, select Open Capture Device….
  4. Select your webcam from the list and click on the Open button.
  5. VLC will start playing a live capture from your webcam. The important part is the title of the window, which starts with qtcapture:// followed by the ID number of your particular webcam. You will need this string later. Click on the Stop button to be able to see it clearly in the playlist. From the Window drop-down menu, select Media Information…, where you will be able to copy the string.
  6. Now quit VLC and open up a Terminal window (located in /Applications/ Utilities) and type in the following command, replacing [ID] with the ID of your webcam and adjusting the width and height to suit your webcam:
  7. /Applications/ qtcapture://[ID]
    --qtcapture-width 640 --qtcapture-height 480 --sout='#transcod

    VLC will start serving a raw M-JPEG stream over HTTP on port 8080, suitable for feeding into Motion.

  8. You should be able to confirm that the stream is working by opening up a new tab in your browser and entering the address http://[MacIP]:8080/ stream.mjpg in the address bar, but change [MacIP] to the IP address of your Mac.
  9. If the stream is working all right, proceed to add it to the Motion setup. You may quit VLC to stop the stream at any time.

Configuring Motion for multiple input streams

To incorporate our new webcam stream into Motion, we will need to rework the configuration so that each camera runs in its own thread. We do this by taking all the configuration directives that are unique to each webcam and putting them in separate configuration files: ~/.motion/thread1.conf for camera one, ~/.motion/ thread2.conf for camera two, and so on.

  1. Let's begin with our first webcam, the one plugged into the Pi. The following directives are unique to camera one and will be moved into thread1.conf:
    • netcam_url http: // localhost:8080/?action=stream: This line is the primary identifier for camera one; it should be commented out in motion.conf and added to thread1.conf.
    • webcam_port 8081: This port is also unique to camera one, and should be commented out in motion.conf and added to thread1.conf.
  2. Then we add the new stream to thread2.conf:
    • netcam_url http://[WinIP]:8080/cam_1.cgi or http://[MacIP]:8080/stream.mjpg: This line is unique to our second camera.
    • webcam_port 8082: We specify this port to see the live feed from camera two.
  3. Now the last thing we have to do is to enable the threads in ~/.motion/ motion.conf. At the bottom of the article, you'll find the thread directives. Change two of them to include your new thread configurations:
    • thread /home/pi/.motion/thread1.conf

    • thread /home/pi/.motion/thread2.conf

    As a final touch, you can uncomment the text_left configuration directive to enable text labels that'll make it easier to tell the camera feeds apart.

  4. That's it! Fire up Motion and observe the startup messages.

    Motion starting up with multiple camera threads

  5. Now visit http://[IP address]:7070, and you'll see that the initial web admin menu makes more sense. The feed of camera one is available at http://[IP address]:8081, and for camera two at http://[IP address]:8082.

Building a security monitoring wall

The only thing missing from our motion detection system is a proper villain's lair security monitoring wall! We can easily throw one together using basic HTML, and serve the page with the tiny HTTP server already running with MJPG-streamer.

Let's add and edit our custom HTML document, with the following command:

pi@raspberrypi ~ $ sudo nano /usr/www/camwall.html

Use this code template and replace [IP address] with the IP address of your Raspberry Pi:

<!DOCTYPE html>
<title>Motion Camera Wall</title>
img{border:black solid 1px; float:left; margin:0.5%;}

<img src = "http://[IP address]:8081/" width="320" height="240"/>
<img src = "http://[IP address]:8082/" width="320" height="240"/>
<img src = "http://[IP address]:8083/" width="320" height="240"/>
<img src = "http://[IP address]:8084/" width="320" height="240"/>

Adjust the number of img tags to match the number of Motion threads. Feel free to increase the width and height values if your monitor resolution can fit them. Then save and exit nano.

So what we've built here is a simple HTML page that shows four different video feeds on the same page in a grid-like pattern. You can see this in the following screenshot.Each <img> tag represents one video camera.

Your security monitoring wall may now be admired at the following address:

http://[IP address]:8080/camwall.html

Motion security monitoring wall

Turning your TV on or off using the Pi

For this example, we are relying on a technology called Consumer Electronics Control (CEC), which is a feature of the HDMI standard for sending control messages to your home electronics equipment.

To help us send these messages, we'll need a software package called libCEC. Unfortunately, the libCEC version that is currently part of the Raspbian package repository doesn't actually support the Raspberry Pi, so we'll need to build our own software from source code.

  1. Before building the software, we will need to add some developer headers and code libraries that libCEC relies on:

    pi@raspberrypi ~ $ sudo apt-get install autoconf libtool libudev-
    dev liblockdev1-dev

  2. Next, we check out the libCEC source code from the project's Git repository:

    pi@raspberrypi ~ $ git clone git://

  3. Now we enter the source directory and build the software using the following sequence of commands: <

    pi@raspberrypi ~ $ cd libcec
    pi@raspberrypi ~/libcec $ ./bootstrap
    pi@raspberrypi ~/libcec $ ./configure --prefix=/usr --with-rpi-
    include-path=/opt/vc/include --with-rpi-lib-path=/opt/vc/lib
    pi@raspberrypi ~/libcec $ make
    pi@raspberrypi ~/libcec $ sudo make install

  4. Note that the build process will take some time. You might want to step away from the Pi for twenty minutes to stretch your legs. Once it's finished, you may exit the source directory and delete it:

    pi@raspberrypi ~/libcec $ cd .. && rm -rf libcec

  5. We will be using a utility called cec-client to send CEC messages to the TV. Issue the following command to switch off your TV:

    pi@raspberrypi ~ $ echo "standby 0" | cec-client -d 1 -s

  6. Use the following command to turn your TV on again:

    pi@raspberrypi ~ $ echo "on 0" | cec-client -d 1 -s

Scheduling video recording or staging a playback scare

At this stage, you already know all the individual techniques used for this example. It's simply a matter of combining what you've learned so far to achieve the effect you want.

We'll try to illustrate a bit of everything with one sweet prank: you will prepare your Pi at home, take it over to your friend's house, and sneakily hook it up with the living room TV. In the middle of the night, the TV will turn itself on and a creepy video of your choice will start to play. This freaky incident might repeat itself a couple of times during the night, or we could take the prank to phase two: whenever someone walks into the room, their presence is detected and the video is played.

Let's start prepping the Pi! We will assume that no network connection is available at your friend's house, so we'll have to create a new ~/ script to perform our prank, together with an at timer in /etc/rc.local that starts counting down when the Pi is plugged in at your friend's house.

Here's the new ~/ script:

# Raspberry Pi Video Prank Script
# Use chmod +x ~/ to enable.
CREEPY_MOVIE="AJn5Y65GAkA.mp4" # Creepy movie to play, located in the
Pi home directory
MOVIE_LOOPS="1" # Number of times to play creepy movie (1 by default)
MOVIE_SLEEP="3600" # Number of seconds to sleep between movie plays (1
hour by default)
WEBCAM_PRANK="y" # Set to y to enable the motion detection prank
tv_off() {
if [ "$(echo "pow 0" | cec-client -d 1 -s | grep 'power status:
on')" ]; then # If TV is currently on
echo "standby 0" | cec-client -d 1 -s # Send the standby command
prepare_tv() {
tv_off # We switch the TV off and on again to force the active
channel to the Pi
sleep 10 # Give it a few seconds to shut down
echo "on 0" | cec-client -d 1 -s # Now send the on command

sleep 10 # And give the TV another few seconds to wake up
echo "as" | cec-client -d 1 -s # Now set the Pi to be the active
play_movie() {
if [ -f ~/"$CREEPY_MOVIE" ]; then # Check that the creepy movie file
omxplayer -o hdmi ~/"$CREEPY_MOVIE" # Then play it with sound
going out through HDMI
start_webcam_prank() {
if [ "$WEBCAM_PRANK" = "y" ]; then # Continue only if we have
enabled the webcam prank
mjpg_streamer -b -i " -r 640x480 -f 30" -o "output_ -w /usr/www" # Start our webcam stream
motion -c ~/.motion/prank.conf # Start up motion with our special
prank configuration file
case "$1" in
prankon) # Signal from Motion that event has started
prankoff) # Signal from Motion that event has ended
*) # Normal start up of script
for i in `seq $MOVIE_LOOPS` # Play creepy movie in a loop the
number of times specified
sleep "$MOVIE_SLEEP" # Sleep the number of seconds specified
start_webcam_prank # Begin prank phase 2

Don't forget to give the script executable permission using chmod +x ~/

As you can see, we're starting Motion with a special configuration article for the prank, called ~/.motion/prank.conf. This is a copy of your previous single thread configuration, except for two configuration directives: on_event_start /home/pi/ prankon and on_event_end /home/pi/ prankoff. This allows us to use our script to react to the Motion events.

Special prank Motion configuration

Now all we need to do is adjust /etc/rc.local to set a timer for our script using the at command. Type in sudo nano /etc/rc.local to open it up for editing, and adjust the following block:

if [ -x /home/pi/ ]; then
sudo -u pi at now + 9 hours -f /home/pi/

So if you plug in the Pi at your friend's house at 6 P.M., strange things should start happening right around 3 A.M. in the morning.

As for what creepy movie to play, we leave that entirely up to you. There's a tool called youtube-dl, which you might find useful. Install it and update it (yes, twice) with the following sequence of commands:

pi@raspberrypi ~ $ sudo apt-get install youtube-dl
pi@raspberrypi ~ $ sudo youtube-dl -U
pi@raspberrypi ~ $ sudo youtube-dl -U

Now you could use it to fetch videos like this:

pi@raspberrypi ~ $ youtube-dl


In this article, we got acquainted with the two components involved in webcam handling under Linux—the USB Video Class drivers and the Video4Linux framework. We learned how to obtain important information about our webcam's capabilities; we also learned a bit about pixel formats, image resolution, and frame rates.

We proceeded to set up an MJPG-streamer video feed, accessible directly via a web browser or through VLC media player, which we could also use to record the stream for permanent storage.

Then we dove head first into motion detection systems with the introduction of the Motion application. We learned how to create an initial configuration suitable for verifying and tweaking the motion detection mechanism, and how to set off alarms upon detection. After a successful first run, a second configuration was made, which added evidence collection capabilities; we also explored how to view that evidence. Not content with letting any unused webcams in the home go to waste, we explored how to hook up additional camera streams to the Motion system and how to show this setup off with a simple HTML security monitoring wall.

We also looked at how to make use of CEC technology to remotely control the TV connected to the Pi, a neat trick that came in handy for our last and boldest prank—the creepy playback scare.

Resources for Article:

Further resources on this subject:

You've been reading an excerpt of:

Raspberry Pi for Secret Agents

Explore Title