LJ Archive

The Open-Source Classroom

BirdCam, Round Three

Shawn Powers

Issue #260, December 2015

BirdCam 3.0? Check out Shawn's latest improvements to BirdTopia.

I've been writing for Linux Journal since 2007 when I shared the process I used to make my own MAME arcade cabinet. Out of all the projects, how-tos, reviews and silliness I've written, nothing has gotten more feedback and discussion than my BirdCam. It's been more than a year since I last wrote about my setup, and since that time, I've moved to a new city and upgraded my cameras and software significantly. So to answer many of the questions I get about the current state of BirdCam, I figured I'd write about the technical details and hopefully inspire similar projects or upgrades for others. Plus, I get to talk about BirdCam, and that's just pure fun!

A Short Refresher

If you weren't with LJ two years ago when I first wrote about BirdTopia, I'll quickly catch you up. I have a bunch of bird feeders in my backyard, right outside my office window (Figure 1). I decided it would be awesome to put a public Webcam on them, but I didn't want to pay for LiveStream or anything like that. In fact, I wanted it to be strictly image-based instead of video. The initial article is at www.linuxjournal.com/content/its-bird-its-another-bird. Like most folks, I fiddle with things constantly, and BirdCam changed so much, I followed up later with an article on my improvements, including how I create a daily video archive: www.linuxjournal.com/content/birdcam-round-two.

Figure 1. BirdCam now has far less clutter, but way more appeal.

If you don't want to take the time to read those articles, no worries. The TL;DR version is that I take periodic snapshots of my bird feeders, and have an auto-refreshing Web page that shows a 1–2FPS “video”, which is hosted at birds.brainofshawn.com. (Don't worry about swamping my home connection; the feed is scaled to the cloud—the details of which are also in the initial article!)

New Hardware

This is by far the most frustrating development with my BirdCam setup. I want to move the bulk of the cameras outside so my office window isn't cluttered with wires, and also so the reflection of my new south-facing window doesn't cause J.J. Abrams-like lens flare. Unfortunately, finding an outdoor camera with the same image quality as my repurposed Galaxy S2 phone is difficult. I'm sure there are $500 Axis-brand cameras that have great image quality and an ability to pull still images, but that's way beyond my price range.

I have had decent luck with the $79 Foscam FI9803P camera. It does 720p, and with a convoluted URL, it's possible to pull still images from it. It struggles with lens flare much like my cameras pointing through the window, but it's tolerable. With an outdoor camera, I don't have the problem of window reflection recording me in my office as evening approaches. Nobody wants to stare at me in the reflection, but with window-based cameras, that happens most evenings. I've contacted several companies selling outdoor-rated cameras, and most of them require the use of a proprietary app to view images.

I also attempted to use a Dropcam (Nest cam now I guess), and although the super-wide angle is nice, and it is possible to pull still images, the cloud-only factor is a showstopper for me. I don't want to use constant bandwidth to send video to the cloud when all I want is to pull still images. Perhaps there's a way to hack the firmware, but out of the box, a Dropcam uses too much bandwidth for my purposes. If anyone knows of an affordable 720p or 1080p outdoor security camera with optical zoom and the ability to pull stills via http(s), please let me know. I'm actually considering building a small heated box with a window in order to put an old Android phone outside. The photo quality on cell phones is so amazing, it will be hard to beat an Android device running IP Cam.

HTML Updates

You may recall one of the problems I had with BirdCam was to get JavaScript that would regularly refresh the page and work across multiple browsers and platforms. The code I posted last time did mostly work, but I managed to come up with JavaScript that is seemingly foolproof. I also updated the CSS to handle resizing of the main page better and split BirdCam into three separate pages. The result is clickable thumbnails that “refocus” the page. Listing 1 shows the format of each page, the only difference being that with the other two pages, the links and images are rearranged. I've added comments to each section explaining the functionality.

Image Changes

If you visit birds.brainofshawn.com, you might notice there no longer are text overlays with sunset info and so on. I might add the temperature back, but I found the rest to be overkill. Instead, there is a timestamp on each photo in the corner, and that's it. That means my daily archive videos have a really nice “clock” you can watch while they play. If you head over to the BirdCam YouTube channel, you can see what I'm talking about (snar.co/windowcam). I've noticed with frustration that most of the video footage in the new house is “DogCam”, because my dogs wander back and forth in front of the cameras constantly. We're planning to change where the dogs are allowed in the yard, so hopefully that will end soon.

With the simplification of images, I hope to add two more cameras eventually, if I find cameras I like. I think adding thumbnails to the bottom corners will keep the display fairly neat and provide easy access to more bird action. At least one of the new views will be a hummingbird camera once spring arrives, so check the feed periodically to see what happens in the future!

YouTube Updates

If you've tried to create an automated YouTube script based on my last BirdCam article, you probably noticed it no longer works. In fact, I didn't pay attention to the warning e-mail messages YouTube sent me, and I ended up getting locked out of my Google account for using an old API. Thankfully, I was able to recover my account without too much trouble, but still, it was scary. The ytu program (a script that uploads video to YouTube) itself needs to be updated, and the Google authentication process is different. Also, the command-line options for ytu have changed, and by default, videos are marked private. So in order to get an automated process, you'll need to follow these steps:

1) Head over to TASVideos and download YTU version 2: tasvideos.org/YoutubeUploader.html.

2) Extract the tar.bz2 file and read the “Obtaining Credentials.pdf” file. It will walk you through the (required!) process of getting the credentials that will allow ytu to work. It requires you to create a new Google developers project. Thankfully, the instructions are easy to follow.

3) Modify (or create!) your scripts to upload the video to YouTube. Here is what my modified code looks like:


#!/bin/bash
/usr/local/bin/ytu/ytu \
     -permission ap \
     /processed_video/birdvideo.mp4 \
     "Video Title Here" \
     "Tags,comma,separated" \
     1 \
     < /usr/local/etc/description.txt

Notice the -permission ap, which makes the video public. Supposedly videos are public by default, but that wasn't the case for me, and I had to add that option manually. Also, the 1 on the line by itself is the category ID. 1 is film and animation, but ytu will give you a listing in the documentation if you want something different.

The mencoder stuff is all exactly the same as before. Luckily, turning thousands and thousands of images into a video is still really easy. Be sure to read my last BirdCam article for more details.

Compensating for the Earth's Tilt

It has annoyed me for a couple years now that I basically had to guess when to turn the cameras on and off for the night. In fact, I usually just leave things on overnight, and hope the lack of light stops the cameras from recording any motion. A few 12-hour videos of my screensaver reflected in the window caused me to research the problem a little more. Here's what I came up with.

There's a cool program called sunwait developed by Dan Risacher in 2004 that calculates sunrise/sunset times based on latitude and longitude. It's no longer being developed, but it compiles easily and works well even with modern distributions. You can get the program from https://www.risacher.org/sunwait.

The program does two things for me:

1) It gives the sunset/sunrise data, which I then can update daily and store in my /etc folder, which I use as a test to determine whether I should download images from my cameras.

2) It literally will “wait” on the command line when invoked until sunrise or sunset. This is useful because I have it “wait” for sunset, then kill off the motion program. Then in the morning, I have it “wait” for sunrise and start motion back up.

The simplicity is brilliant, and it has required me to change my scripts a bit. Here's the script I use to get sunrise and sunset times. Specifically, I pick “Civil” sunrise and sunset, which aligns with “when you can still see” rather than the actual time the sun sets. For camera purposes, it's far more useful. I call the program “sun” in the /usr/local/bin folder:

#!/bin/bash
if [ $1 == "-rise" ]
then
/usr/local/bin/sunwait -p 45.3733N 84.9553W | 
 ↪grep Civil | awk -F" " '{print $4}'
elif [ $1 == "-set" ]
then
/usr/local/bin/sunwait -p 45.3733N 84.9553W | 
 ↪grep Civil | awk -F" " '{print $7}'
else
echo 'Type either "sun -rise" or "sun -set"'
fi

Then in the root user's crontab, I have these two entries:

1 4 * * * /usr/local/bin/sun -rise > /etc/sunrise
2 4 * * * /usr/local/bin/sun -set > /etc/sunset

So every morning around 4am, the sunrise and sunset data is updated on my computer. Then I have two crontab entries as my normal birdcam user, which starts and stops motion at the proper time:

0 16 * * * /usr/local/bin/sunwait civ down 45.3733N 
 ↪84.9553W; pkill motion
0 5 * * * /usr/local/bin/sunwait civ up 45.3733N 84.9553W; 
 ↪pkill motion; sleep 10; motion

Those lines start sunwait well in advance of any sunset or sunrise, and start or kill motion accordingly at the right time. (The start script kills off motion, in case the computer was restarted and motion already is running.) Finally, the birdcam user has one more cronjob that puts “off-line” photos for the Web server to use:

2 16 * * * /usr/local/bin/sunwait civ down 45.3733N 84.9553W; 
 ↪sleep 30; cp /offline.jpg > /dev/shm/house.jpg

As far as the script that fetches images from my IP camera, I have a conditional loop that runs like the following:

#!/bin/bash

#Variables -- change to fit your needs
TEMP_PHOTO=/dev/shm/.housetemp.jpg
SUNRISE=`cat /etc/sunrise`
SUNSET=`cat /etc/sunset`
TIME=`date +%k%M`
# Get Photos, or offline photos if cameras offline

if [ $TIME -gt $SUNRISE -a $TIME -lt $SUNSET ]
then
   if eval "ping -c 1 192.168.1.178 > /dev/null"
   then
     /usr/bin/wget -r --timeout=5 --quiet -O \
     $TEMP_PHOTO \
     "http://192.168.1.178:88/cgi-bin/CGIProxy.fcgi?cmd=
↪snapPicture2&usr=admin&pwd=passwd"
     mv $TEMP_PHOTO /dev/shm/house.jpg
   fi
sleep 2
rm -rf /dev/shm/.house*
fi

What does all that do? Well, if you follow the logic in the cronjobs and scripts, you should find that at sunrise every day, the motion program is started, and my script for downloading images from the IP camera starts fetching images. At sunset, motion is killed off, and the off-line image is put in place. Since this updates every day, my camera follows the pattern of the sun throughout the year, even honoring Daylight Savings Time!

Your Own Project

It's very unlikely you're as nuts about birds as I am. Thankfully, much of the stuff I use for BirdCam easily can be adapted to other projects. I'm absolutely loving the ability to schedule things according to the sunrise and sunset at my locale. If nothing else, that is a powerful tool for managing scripts. Hopefully you're able to get as much joy from creating your own projects as I get from BirdCam! (And really, don't hesitate to e-mail me about good IP cameras, I'm having a tough time coming up with decent options.)

Shawn Powers is the Associate Editor for Linux Journal. He's also the Gadget Guy for LinuxJournal.com, and he has an interesting collection of vintage Garfield coffee mugs. Don't let his silly hairdo fool you, he's a pretty ordinary guy and can be reached via e-mail at info@linuxjournal.com. Or, swing by the #linuxjournal IRC channel on Freenode.net.

LJ Archive