BirdCam, Round Two
Motion: Choosing a USB Camera
You want a camera that is UVC (USB Video-Compatible). It would be nice if cameras had a nice "USB Video-Compatible!" sticker on the box, but sadly, they never do. The good news is that many cameras are compatible, even if they don't brag about it. You can google for a specific camera model to see if other folks have used it, or you can check an on-line database before buying. See http://www.ideasonboard.org/uvc for a list of devices known to work, but if you're getting an off-brand model, you might just have to try it to find out. Interesting to note, if you see a "Certified for Windows Vista" sticker, the camera is UVC-compliant, as that's a requirement for Windows Vista certification.
I chose the Logitech C920 USB camera, which supports 1920x1080 (1080p) video at 30fps. By default, the camera autofocuses, which sounds like a great idea. Unfortunately, I found the camera almost never focuses on what I want, especially if it's very close to the camera, which the birds tend to be. If you have issues with autofocusing, you might want to try tweaking the camera on the command-line. I have the following added to my startup scripts to turn off autofocus, and I set the manual focus to just outside my window:
uvcdynctrl -s "Focus, Auto" 0 uvcdynctrl -s "Focus (absolute)" 25
You'll need to play around with the focus value to get it just right, but if your camera supports manual focus, you should be able to tweak it for sharp images that don't need to autofocus every time a bird lands.
Motion: Configuring the Config
Installing motion is usually nothing more than finding it in your repositories and installing. You'll probably have to edit a file in order to get it to start at boot (like the /etc/default/motion file in Ubuntu), but it's not too painful. It's important to understand a few things about the default config:
Usually the "root" folder motion uses by default is in the /tmp folder. This could cause issues on your system if you just leave it alone and let it run—it could fill your /tmp partition and make your system break.
Motion uses /dev/video0 by default. This is good, as it most likely is the device name of your USB camera. If you have a funky camera though, you might need to change the device setting.
When you make a change to the configuration file, you need to restart motion for it to take effect. That generally means running
sudo service motion restartor something similar.
Next, open the config file (as root), and make some changes. I'll name the directive to search for below, then talk a bit about the settings. These configuration directives should all be in your /etc/motion/motion.conf file. You'll just need to modify these values:
width: I use
width 1280for my camera. Even though it supports 1080p, I actually only record at 720p (1280x720). It saves space and still produces HD quality content.
height: in order to get the proper aspect ratio, I set this to
height 720. Note, my camera will take photos only with the 16x9 aspect ratio, even if I set it to something else.
framerate: this is how many frames are captured per second. I use
framerate 15, which provides fairly smooth motion while saving the most disk space. With the Raspberry Pi, I could get around 5fps with a 640x480 camera before the CPU load maxed out.
threshold: this is how many pixels must change before the program triggers a motion event. I left the default, then tweaked it later. My setting currently is
minimum_motion_frames: by default, this is set to 1. I found that occasional camera glitches would fire off a motion event, even if nothing moved. Setting this to 2 or 3 will make sure there's actual motion and not a camera glitch. Mine is
quality: the default quality of 75 is probably fine, but I really wanted a sharp image, especially since I spent almost $100 on a camera. I set this to
ffmpeg_cap_new: this is the setting that will tell motion to record videos. I had this "on" at first (it defaults to "off"), but I ended up with hundreds of short little videos. If you turn it on, fiddle with the other ffmpeg options as well.
snapshot_interval: this will capture a single image every N seconds. I have it set to
snapshot_interval 1and use the image for embedding into BirdCam.
target_dir: this setting is very important. This directory will be the "root" directory of all files created by motion. Both photo and video files are kept in this directory, so although using the ramdisk might sound like a good idea, it probably will fill up quickly.
snapshot_filename: this will be the periodic snapshot filename. I set it to a single filename so that it is overwritten constantly, but you can leave it with the datestring stuff so it will keep all the files. This filename is relative to
target_dir, so if you try to set an absolute path, it still will be relative to
target_dir. You can, however, add a directory name. On my system,
target_diris /home/birds, and I have a symbolic link inside /home/birds named ram, which points to a folder inside the /dev/shm ramdisk. I then set
snapshot_filename ram/windowcam, and it overwrites the windowcam.jpg file in my ramdisk every second. This saves wear and tear on my hard drive.
jpeg_filename: this directive is similar to
snapshot_filename, but instead, it's where the 15 images per second are stored. This is one you don't want to redirect to a ramdisk, unless you have an enormous ramdisk. I kept the default string for naming the files. My setting puts the photos in a separate folder, so it looks like this:
movie_filename: this is what determines the name and location of the ffmpeg videos. I'm not saving ffmpeg videos anymore, so my setting is moot, but this is where you assign folder and name location. Even though mine isn't used anymore, my setting from when I did record video is
webcam_port: by default, this is set to 0, which means the Webcam is disabled. On a Raspberry Pi, I don't recommend turning this on, but on my Intel i5-based system, I have it set to port 8081. It creates a live MJPEG stream that can be viewed from a browser or IP camera-viewing software (like from an Android tablet).
webcam_maxrate: this determines frames per second. I have this set to 10, which is fast enough to see motion, but it doesn't tax the server.
webcam_localhost: by default, this is set to "on", which means only the localhost can view the Webcam stream. If you want to view it remotely, even from other computers on your LAN, you'll need to change this to "off".
Although that seems like a huge number of options to fiddle with, many of
the defaults will be fine for you. Once you're happy with the settings,
sudo service motion restart, and the server should re-read your
config file and start doing what you configured it to do.
I probably could talk about the fun things I do with my BirdCam server for two or three more articles. Who knows, maybe I'll visit the topic again. Before I close this chapter though, I want to share a cool thing I do to archive the bird visits for a given day. I mentioned that I end up with more than 100,000 photos a day from detected motion, and quite honestly, looking through that many photos is no fun. So at the end of every day, I create an MP4 video using the images captured. I've tried a few different tools, but the easiest to configure is mencoder. If you get mencoder installed (it should be in your repositories), you can turn those photos into a movie like this:
mencoder "mf:///home/birds/photos/*.jpg" \ -o /home/birds/archive/`date +"%Y-%m-%d"`-WindowCam.avi -fps 15 \ -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell:vbitrate=7000
I run that command from cron every evening after sundown. Then I delete the images, and I'm ready for the next day. What I end up with is a 2–3 hour video every day showing all the bird visits at my window. It might seem like a lame video, but I usually scrub through it the next morning to see if there are any new or exotic birds visiting. The videos are 4–6GB each, so if storage space is an issue for you, it's something to keep in mind—which brings me to the next, and final, cool addition to BirdCam.
The Most Boring YouTube Channel Ever
I want to be able to watch my archived video from anywhere. It's possible to stream my local media via Plex or something direct like that, but it would mean I had to connect to my home network in order to see the birds. Now that YouTube has removed the 10 or 15 minute limit on YouTube accounts, it means I can upload a three-hour archive video of birds at my window to YouTube, and have them store and display my video in the cloud—and for free!
Because this is Linux, I wanted to find a way to script the uploading and naming of my daily video. Thankfully, there's a really cool program called ytu, which stands for YouTube Uploader. It's simple, but very powerful. Download it at http://tasvideos.org/YoutubeUploader.html.
The most difficult part of running ytu is that you need a developer key. You can become a developer and get a developer key at https://code.google.com/apis/youtube/dashboard/gwt/index.html. It's not difficult, but the URLs keep changing, so I can't give you a more specific link. Once you have your developer key (a long string of letters and numbers), you can fill out the credentials.txt file with:
Google e-mail address.
Google password in plain text.
Make sure only the account executing the ytu binary has access to the file, as your password is stored in plain text. If this security problem isn't acceptable, you can, of course, upload videos to YouTube manually. I actually have a separate Google account for uploading BirdCam videos, so I'm not as concerned with the security.
Once the credentials file is set, you invoke ytu from the command line, or in my case, from the same cron job that creates the video. After the video is created, I immediately start ytu to upload it to YouTube. After several hours of uploading and processing, the video is ready to watch. If you'd like to see my archived videos, just surf over to http://snar.co/windowcam and see all the past videos.
It Doesn't Have to Be Birds!
Obviously, I have a mild obsession with birdwatching. We all have our quirks. With this article, and my last BirdCam article, hopefully you can figure out a way to adapt the power of Linux to scratch that video-capturing itch you have. If you do end up with something similar, or even something drastically different (dogcam on the local fire hydrant?), I'd love to hear about it! Well, maybe not the fire-hydrant cam...that's a little too strange, even for me.
BirdCam Script: http://snar.co/birdcamscript
WindowCam Archive Channel: http://snar.co/windowcam
YTU Program: http://tasvideos.org/YoutubeUploader.html
YouTube Developer Dashboard: https://code.google.com/apis/youtube/dashboard/gwt/index.html
- Smoothwall Express
- Machine Learning Everywhere
- Own Your DNS Data
- Bash Shell Script: Building a Better March Madness Bracket
- Simple Server Hardening
- Returning Values from Bash Functions
- Understanding Firewalld in Multi-Zone Configurations
- From vs. to + for Microsoft and Linux
- Understanding OpenStack's Success
- Tech Tip: Really Simple HTTP Server with Python