As some of you may know, I have wireless surveillance cameras around my home. Many years back I even released an Android application called SpyFi to be able to view the video feed from these cameras. Up until recently I would have these cameras upload a sequence of images to a remote FTP server every time there was motion. The problem with this is that these were only a sequence of still-images rather than video, and the server was not free or necessarily cheap.
Being that I own a few Raspberry Pi computers, I figured it might be a good idea to utilize them for surveillance storage. The cool thing about this approach is that it is cheaper and that I can record video rather than pictures.
We’re going to take a look at how I’m recording video on a Raspberry Pi device to keep my home safe.
Before going forward it is probably a good idea to share my setup. While I’ll be discussing what I’m using, it should work fine in other scenarios as well.
I’ve tested this on one of my Raspberry Pi first generation units and it works with a few limitations. On my first generation unit, the frame-rate is a bit wild, and likewise with the quality. This is because the recording tools default at lower quality to accommodate the low specs. I didn’t experience these problems with the Raspberry Pi 3.
The IP camera I’m using is cheap and it works well. Amazon has a ton of other IP cameras you can buy. Just make sure you get one that exposes the URL for accessing the video.
I’m going to assume your Raspberry Pi has been flashed and is running correctly at this point. If you’re not sure how to get Raspbian on your unit, check out the previous tutorial I wrote on the topic.
Since I’m using Raspbian Jessie Lite, we’re going to be using Libav for recording the video. We’re doing this because Jessie has repositories for Libav. If you’re feeling adventurous or are using a flavor of Raspberry Pi Linux that makes it easy to install FFmpeg, you can use that as well. While the internet will claim that FFmpeg performs better than Libav, benchmarking is not the point of this guide. Both software uses the same command line parameters as we’ll see later on.
To install Libav on your Raspberry Pi, execute the following:
sudo apt-get install libav-tools
You shouldn’t need anything else if you’re using Raspbian Jessie or more recent.
If you’re using the same camera that I’m using, you may or may not know that the stream URLs are exposed and can be accessed via your web browser. Take the following for example:
http://IP_HERE:PORT/video.cgi
Of course you’ll want to include your own IP and port in the above example. If you navigate to the URL it will ask you for a username and password. This is something you should have configured in the local dashboard of your IP camera.
The video stream is actually in Motion JPEG (MJPEG) format, not that of typical video formats.
Sign into your Raspberry Pi, if you’re not already connected and execute the following from the Terminal:
avconv -f mjpeg -re -t 3600 -i http://USERNAME:PASSWORD@IP:PORT/video.cgi -an -r 10 -vcodec mpeg4 ./dlink.mp4
The above command will treat the input video as MJPEG and record it for 3600 seconds or 1 hour at the original frame-rate. The video will be output without audio and encoded at 10 frames per second using the xvid MP4 codec. You can fiddle with these settings however you’d like.
Notice though that this time I’ve included the username and password in the input source URL. This will prevent a popup from showing up, something that the Terminal won’t recognize.
The command line alone wasn’t good enough for me. I don’t want to keep running the recording manually. Instead it should be part of a CRON script.
Let’s take a look at a possible script:
#!/bin/bash
now=`date '+%Y-%m-%d:%H:%M:%S'`
avconv -f mjpeg -nostats -loglevel 0 -re -t 3600 -i http://USERNAME:PASSWORD@IP:PORT/video.cgi -an -r 10 -vcodec mpeg4 /home/nraboy/dlink_$now.mp4
In the above record.sh file there are a few differences from what we already saw. For one, notice the use of -nostate
and -loglevel
tags. This will mute the output of the recording process.
Also note the use of the timestamp. Because this will happen on a CRON at 1 hour intervals, it is probably a good idea to include a timestamp in the filename.
Now let’s say we want to add this to CRON and run it every hour on the hour. Execute the following to edit our CRON schedule:
crontab -e
At the end of this file, add the following line:
0 * * * * /path/to/record.sh
Now the recording script will be run every hour. The script itself will only record 1 hour chunks so by the end of the day we should have 24 videos.
Running out of space on your Raspberry Pi storage? Why not include some cleanup to your record.sh file? Include the following somewhere in your script:
find /home/nraboy -type f -mtime +5 -exec rm {} \;
The above line will remove all files older than 5 days. Now you’re probably going to want to create a directory for your videos to live, otherwise the above will remove your script over time. Just fiddle with things until you find something that works for you.
You just saw how to use a Raspberry Pi to record a stream of video from an IP surveillance camera. Using FFmpeg or Libav makes it very easy to encode your videos even on low end hardware like the Raspberry Pi.
Now there are a few things that can be done to make things even more efficient. Instead of recording all day, every day, maybe you want to record only if there is motion detected. There is a library called motion that can do this, but that is best saved for another article.