Motion: Your Eye in the Sky for Computer Room Surveillance
Let's say you have a room full of thousands of dollars' worth of computer equipment. That's probably something you want to keep an eye on, right? With that in mind, you install a network-connected camera. Now, you can surf over to the camera's Web page and see what's going on in the server room at any time of day or night. That's an improvement, but you quickly realize some sort of recording facility is needed, in case you need to figure out who was in the room last Tuesday. So, you start saving the video to another system on the network for possible viewing at a later time. Maybe you write a few scripts to rotate the video after a week or so to keep from filling up your hard drive.
After wading through hours of video to find out who “borrowed” your favorite screwdriver, you realize further refinements are necessary. Wouldn't it be great if the computer could keep only the interesting video and throw out everything else? Enter Motion, a free motion-detection program. Process your video through it, and 24 hours of daily video becomes 15 minutes of video clips documenting every time something moved in that room—technology to the rescue.
Motion works with either standalone netcams, such as those offered by Axis (see the on-line Resources), or any camera connected to a video4linux-compatible video capture card. I concentrate here on using a standalone camera, the Axis 2100, because it's simpler to set up. In any case, you need a Linux system to save the video and to run Motion as well. Motion can require quite a bit of processing power, but a system with a Pentium III CPU or higher should work okay if the machine is dedicated to running only Motion.
Installation and configuration of the Axis camera is straightforward. Pick a location for it in the room you want to monitor, and run power and Ethernet cables. In my experience, a camera mounted slightly above eye level, seven feet up or so, in a corner of the room provides the best coverage. Follow the camera install instructions to assign it an IP address on your network. Then, verify that the camera works by pointing your Web browser at the camera's Web page.
The computer system that is going to save the video and run Motion can be situated anywhere you like. It's probably best to keep it on the same logical and physical network as the camera, for simplicity's sake.
Any modern Linux distribution should work fine. I use Fedora Core 1 in my setup.
Obtain Motion from the Motion Web site (see Resources). The current version at the time of this writing is 3.1.16. You can use either the RPM supplied on the Motion Web site or build from source. I don't recommend using RPMs or Debian packages from elsewhere as they tend to be out of date and lacking features. Numerous important changes have occurred in Motion development in a few months' time.
The only other software dependency is the ffmpeg library, which Motion uses to generate MPEG videos. You must use the released version 0.4.8 of ffmpeg, as newer development versions do not work well with Motion. Download ffmpeg source (see Resources); you must have ffmpeg built and installed before building Motion. Otherwise, Motion attempts to use an older tool called mpegplayer to create videos. You probably don't have that installed either, so Motion won't work very well.
After you have downloaded both Motion and ffmpeg, untar them in a directory such as /tmp. Then, cd to the ffmpeg source directory and run:
$ ./configure $ make # make install
The last command must be run as root.
These commands install the ffmpeg libraries under /usr/local/lib. Then, cd to the Motion source directory and again run ./configure. This time, make sure to check the results. In particular, under Configure Status, FFmpeg Support must say Yes. If not, Motion didn't find the ffmpeg library on your system. This is the number one cause of problems and confusion when installing Motion. Don't continue until you resolve this problem. Figure out where on your system the file libavcodec-0.4.8.so is located, and rerun configure in the Motion directory as follows:
$ ./configure --with-ffmpeg=/some/random/path
Once you are able to run configure and see it report FFmpeg Support: Yes, you can build and install motion:
$ make # make install
Again, the final command must be run as root. After all of this completes, you will have a /usr/local/bin/motion executable on your system.
Refer to the Motion Guide (see Resources) if you encounter any problems building or installing Motion. Some of the guide is outdated, but it contains a useful explanation of how to install and operate Motion.
Motion runs as a dæmon, constantly analyzing and storing video. It is controlled by a configuration file, per the standard UNIX paradigm. Copy the file motion-dist.conf from the source directory to /etc/motion.conf, and edit a few parameters. The first thing you need to change is the netcam_url setting. Motion retrieves JPEG images from the camera through this URL. For the Axis 2100 camera, this takes the form http://netcam.example.com/axis-cgi/jpg/image.cgi?resolution=640x480. When you set the netcam_url variable in motion.conf, all the settings pertaining to directly connected video cameras, such as video device, rotate, height and width, are ignored.
You should be aware of one limitation between netcams and standard video capture devices. Motion at this time knows how to request images from netcams only one JPEG snapshot at a time. The overhead of this limits your video to a maximum of 12–15 frames per second (fps). Some work has been done to pull the images from the cameras in motion-jpeg streams, but that effort is not yet complete. In practice, 10 or 12fps is perfectly adequate for surveilling a room.
You need to decide where to keep your Motion-generated videos. I generally use the directory /var/log/vcr on my Linux server. The location you use depends on your disk-space situation. Ideally, you should create a new filesystem exclusively for the Motion videos in order to avoid filling your root or /var filesystem with video files. This directory is set with the variable target_dir in motion.conf.
Next, decide on the type of video you want to create. Motion 3.1.16 supports MPEG1, MPEG4 and MS-MPEG4. MPEG1 has the advantage of being a simple and well supported format. However, MPEG4 offers better video and better compression. The final format, MS-MPEG4, is understood by Microsoft Windows Media Player without any special plugins.
One warning: MPEG4 and MS-MPEG4 support were introduced in Motion 3.1.16, so they have not been tested as extensively as MPEG1 video has been. I have found MS-MPEG4 to work fine, however, and it is much easier for Windows users to view. MPlayer or any other modern video player can be used to watch video in any format on Linux systems.
The video type is controlled by the motion.conf variable ffmpeg_video_codec.
This should be enough basic configuration for you to start using Motion. You should check that output_normal is off; otherwise, JPEG images of all the frames are stored in target_dir. This may be useful later on for debugging, but right now it is unnecessary clutter.
Run Motion from the command line, as root, with the command /usr/local/bin/motion. Motion should start up and continue running. If it aborts immediately, there probably is an error in your config file. Follow the error messages to troubleshoot. Once you have it fixed so that Motion starts and continues to run, generate some input. Walk in front of the camera or, better yet, have an assistant do it. Remember to turn the lights on in your server room, or the camera might not pick up much action.
As the activity in front of the camera starts, Motion begins to generate an output file. After the activity stops, check your targer_dir for the resulting output file. Examine the file with your video player. The video may appear jerky because of the limitations of pulling the still images from the netcam. Motion fills in the missing frames so that the video runs at normal speed, and it may have the stop-motion quality you see on convenience store cameras. If everything looks good, it's time to set up Motion to run on system startup.
To make Motion run on every system boot, set up an init script. On Red Hat-based systems, copy motion.init from the Motion source directory to /etc/init.d/motion and run, as root:
# /sbin/chkconfig --add motion # /sbin/chkconfig motion on
Then, test that the initscript works by running it manually with /etc/init.d/motion start. Finally, if you are paranoid, reboot the system and verify that motion is up and running after system boot.
Like any good Linux program, Motion has many tuning variable. The best advice when you tune Motion is to change one variable, restart Motion and test. Some of the configuration variables can have non-obvious interactions with one another.
As a first step, you might want to turn on the locate and text_changes motion.conf variables. Locate draws a box around the motion detected in each frame, and text_changes prints the number of changed pixels in each image in the corner of the image. These two settings allow you to determine where Motion thinks the motion in the image is, and how much motion there is—how many pixels have changed in the image.
Right off the bat, I recognized I probably placed my camera in the wrong spot in my server room. The room has a window that looks into another office space. It took me a while to figure out why I was getting so many tiny Motion movies when the only change would be a slight brightening and dimming of the room. I finally realized that occasionally a light-colored door in the other room would open and reflect light through the window into my server room. Then, that light would reflect off a shiny metal air-conditioning unit into the camera. So even though the camera couldn't see the window at all, light bouncing through it would produce occasional spurious results.
In retrospect, I should have mounted the camera to point away from possible external light sources and away from shiny metal surfaces. However, I decided to leave it where it was, because that really was the best view of what was going on in the room. Instead of moving the camera, I adjusted Motion to compensate.
The first thing I did was create a mask file. This simply is a black-and-white image the same size as the camera output images, 640×480 for the Axis camera. Any black areas are ignored by Motion. I created this file in The GIMP and blacked out the area corresponding to the metal surfaces of the A/C unit. Unfortunately, Motion is picky about this file; you must save it as a raw, not ASCII, portable graymap (PGM) file.
Motion doesn't like PGM files because they are generated by The GIMP. If you use one, Motion starts but then exits a few moments later with the message:
This is not a ppm file, starts with 'P6'
A few minutes of source code digging revealed the fix. Motion expects the PGM file version number at the start of the file to be P5, not P6. Edit your mask file and change the magic number at the start from P6 to P5. You can edit this file safely in vi. After that change, Motion loads the mask file without incident.
This reduced, but did not eliminate, the empty motion capture videos. I then moved on to other adjustments. I tried turning the light switch variable, which the comments in motion.conf indicate might help filter out sudden light changes. I found this to be ineffective. I also experimented with lowering the threshold, the number of changed pixels required to trigger motion detection. The text_changes output is useful for this as it prints the number of changed pixels on each motion output frame. If too many bogus movies are output by Motion, you can try to raise the threshold to a number higher than what's printed by text_changes.
Ultimately, the best tweak I found was to increase motion_minimum_frames. This is the number of frames that must contain motion before Motion starts generating a movie. I set this variable to three and found that most of my spurious movies from the light changing disappeared. Most of those movies were only a few frames long, because the light level change happened quickly. Conversely, real motion-capture events tended to be many frames long. Thus, if you see many tiny movies with a duration of one second or so, my advice is to increase motion_minimum_frames to at least three and possibly more.
One non-software tweak I have considered but not yet implemented is a motion sensor for the light in my server room. This neatly solves the problem of making sure there is enough light in the room when Motion records an event. Something moves in the room, the lights come on and Motion records. Motion-sensitive light switches can be found at hardware stores for around $15 and require only basic wiring skills.
For now, I simply let my storage area /var/log/vcr fill with movies and delete them manually on occasion. It probably makes sense to set up an automated mechanism to handle this. My current thinking is that movies should be deleted after 30 days. Obviously, this depends on your particular needs.
Several experimental mjpeg support patches have appeared on the mailing list recently. As I mentioned earlier, mjpeg means that Motion pulls a continuous stream of images off the camera instead of requesting them one by one. This should provide much smoother resulting videos, although current Motion videos from netcams do have an enjoyable Keystone Kops feel to them.
Active development continues on Motion. The mailing list (see Resources) is an excellent place to ask questions and find out about current development. Most of what I've learned about Motion has come from reading the mailing-list archives.
Motion provides a solution for one of the most vexing problems we face in the computer industry, too much data. What good is information such as video imagery if there's more of it than you ever could watch? With a little bit of image analysis, Motion quickly eliminates the boring, unchanging video you don't care about. The results are more effective server room monitoring and more time for you to work on other projects.
Resources for this article: www.linuxjournal.com/article/7966.
Phil Hollenback is a Linux system administrator at Telemetry Investments in New York City. He spends his time skateboarding the streets of Manhattan when he's not writing Perl scripts. Visit him at his Web site, www.hollenback.net.