Raspberry Pi as Surveillance Cam

Configure MJPG Streamer

But there are some drawbacks that need to be overcome. At this point you need to log on and start MJPG Streamer. So if you have a power failure your webcam wil not start streaming. If you accidentally unplug the webcam and plug it back in, de pi will not start streaming again.

You can run MJPG Streamer multiple times. So in my case I have 2 webcams. Depending on which webcam you plug in to the pi first will become /dev/video0. But for a security cam, i want the same webcam at the same IP and port every time.

In Linux you can write bash scripts to solve these problems, but script needs to be run when a USB device is detected by Linux. The solution is writing an udev rule. A site which helped my a lot was http://www.reactivated.net/writing_udev_rules.html written by Daniel Drake.

Step 1 - Writing udev rule

Udev rules are stored in the directory /etc/udev/rules.d/. Create a new file named 91-webcamdetect.rules.

nano /etc/udev/rules.d/91-webcamdetect.rules

The rule exists out of three parts:
The first part is a condition. If KERNEL is a video device. It doesn't matter if its /dev/video0 or /dev/video1 because of the wildcard ?. The second part is also a condition. If the ACTION is add. This is because we are only interested when an USB device is detected by the operating system. The last part is a command to run a script. The script /bin/startmjpgstreamer will be run with the option -d and variable $kernel which is video0 or video1. Copy this line and paste in putty by right clicking in the terminal(Putty).

KERNEL=="video?", ACTION=="add",  RUN+="/bin/startmjpgstreamer -d '$kernel'"

Use Ctrl+O to save the file and press Enter to confirm
Press Ctrl+X to exit nano.

Step 2 - Script to start MJPG Streamer

Since the udev rule is staring the script startmjpgstreamer we will have to put this scrip into the right place. Create a new file named startmjpgstreamer.

nano /bin/startmjpgstreamer

Copy this script and paste in putty by right clicking in the terminal(Putty).

#!/bin/bash

function usage
{
        echo "usage: startmjpgstreamer -d [videodevice]"
        echo "e.g.: startmjpgstreamer -d video0"
}

### Main

device="none"

#for each argument which is given to this script.
while [ "$1" != "" ]; do
        #if $1 is the first argument witch is given
        case $1 in
                #if it matches -d or --dev $1 will be shifted to the next argument which will be video0 or 1 hopefully.
                -d | --dev)     shift
                                device=$1 #video0 or video1 is stored in variable device
                                ;;
                #if it matches -h or --help the usage of this script will be displayed and this script will exit.
                -h | --help)    usage
                                exit
                                ;;
                #if it matches * the usage of this script will be displayed an this script will exit.
                * )             usage
                                exit 1
        esac
        shift #shift to the next argument.
done

#if the variable device is still none no argument is given to this script
if [ $device = "none" ]; then
        usage #print the usage of this script
        exit 1 #exit this script
fi

#echo "$device is found" >> /home/pi/log.txt

#additional information of /dev/$device is given by the command 'udevadm info -n /dev/$device --attribute-walk'.
#The result is given to the program grep, which only grabs the line which matches to 'ATTRS{devpath}=="1\.'.
#The result will be ATTRS{devpath}=="1.2" or ATTRS{devpath}=="1.3".
result="$(udevadm info -n /dev/$device --attribute-walk | grep 'ATTRS{devpath}=="1\.')"

#Since we are only interested in the port number we give the string to the program cut, which cuts the string where it finds a ".
#The second result is the portnumber which will be 1.2 or 1.3. This can be different if you use an additional USB hub.
port=`echo $result| cut -d'"' -f 2`

#echo "port is \"$port" >> /home/pi/log.txt

#if you connect the USB webcams to the pi via an USB hub, you will have to change the port value
if [ $port = '1.2' ]; then
        #echo "$device is connected to port 8080" >> /home/pi/log.txt
        #mjpg_streamer -b -i "/usr/local/lib/input_uvc.so -d /dev/$device -r 960x720 -f 15" -o "/usr/local/lib/output_http.so -p 8080 -w /usr/local/www"
        mjpg_streamer -b -i "/usr/local/lib/input_uvc.so -d /dev/$device" -o "/usr/local/lib/output_http.so -p 8080 -w /usr/local/www"
else
        #echo "$device is connected to port 8081" >> /home/pi/log.txt
        #mjpg_streamer -b -i "/usr/local/lib/input_uvc.so -d /dev/$device -r 960x720 -f 15" -o "/usr/local/lib/output_http.so -p 8081 -w /usr/local/www"
        mjpg_streamer -b -i "/usr/local/lib/input_uvc.so -d /dev/$device" -o "/usr/local/lib/output_http.so -p 8081 -w /usr/local/www"
fi

Use Ctrl+O to save the file and press Enter to confirm.
Press Ctrl+X to exit nano.

This file must be allowed to be executed.

chmod 755 /bin/startmjpgstreamer

Step 3 - Time for testing

If your webcam is in the upper USB port of the Raspberry Pi open http://192.168.0.200:8080
If your webcam is in the lower USB port of the Raspberry Pi open http://192.168.0.200:8081
If you have two webcams connected at the same time they both should work.

Step 4 - Tweaking resolution and frame rate

Open startmjpgstreamer file in nano.

nano /bin/startmjpgstreamer

Go to the lines where mjpgstreamer is started tweak with the resolution and frame rate to get the best quality stream. Use Ctrl+O to save the file and press Enter to confirm. Unplug your webcam and plug it back in to start streaming with the new settings.
When the resolution gets bigger and frame rate goes higher more CPU power is needed. You can open a second Putty instance and logon to you Pi. When you run the command top you will get an overview what the CPU power is per mjpgstreamer process.
you may want to test "-y" or the "-q" option for input_uvc.so. It uses a lot more CPU power.
Don't for get to increase the number of browsers that all stream form the Raspberry Pi. This also increases the CPU load.
Top can be closed by pressingCtrl+C.


steinvoorte.nl © 2017