Here I describe how to set up secure video streaming using Raspberry Pi and a dedicated camera with UV4L. This post is written in tutorial–like form and the set–up presented here will be used in my other projects.
Retrieving video from camera is not that hard. For this you can use UV4L. It is an open source initiative which aims to deliver user space for real or virtual video input or video output (after UV4L project website). In other words, it will create a device inside /dev/ which can be directly accessed to get video from it. So let’s jump straight to installing the required software.
First, we need to add UV4L repository keys:
curl http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add -
add project repositories to our local source list:
sudo bash -c "echo \"deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main\" >> /etc/apt/sources.list"
Now we can update local repository list and install necessary packages:
sudo apt-get update && sudo apt-get install uv4l uv4l-server uv4l-raspicam uv4l-raspicam-extras
To start UV4L you need to run following command:
sudo service uv4l_raspicam start
Analogically to stop the server you can run following command:
sudo service uv4l_raspicam stop
Starting server at boot time
To facilitate management of UV4L we can start the UV4L service at boot. There are two ways of doing it. One is to modify rc.local file like this:
sudo bash -c "echo \"sudo service uv4l_raspicam start\" >> /etc/rc.local"
The other possibility is to use update-rc.d to start UV4L server at boot using udpate-rc.d. This is how you would do this:
sudo update-rc.d -f uv4l_raspicam enable
Also do stop UV4L from starting at boot you would do something like this:
sudo update-rc.d -f uv4l_raspicam disable
Enabling camera interface
There is also a preliminary step which has to be done before working with the camera. The camera interface has to be turned on. Unless it is already turned on you have to use raspi-config command, like this:
There you can navigate through the interface and set camera interface to Enabled. After that reboot RPi and you are good to go. I assume that the camera is already connected to the mini computer.
Accessing UV4L web server
Now, you can test if the UV4L is working properly. If you have installed uv4l-server then there is a small web server which will allow you to test UV4L installation. By default the server is working on port number 8080. To test the server you need to enter this URL address inside your browser:
if you are accessing RPi from local network at a different computer. The RPI_LOCAL_IP is IP address of Raspberry PI, probably but not limited to something like this 192.168.0.x.
if you are running it on your Raspberry Pi. However, I recommend testing it on a different computer.
You should see something similar to:
what you are interested in are two tiles: “MJPEG/Stills stream” and “Control panel”. Let’s start with the later. If you click on the nice two gears you should see something like this:
You can set resolution of the video and some other parameters like brightness or rotation. In my case, I had to rotate the image because I have mounted the camera upside down. After saving the configuration go to MJPEG/Stills stream. There you will see a live stream from the camera. There is one thing worth noting, when you have live stream active, it is open on another tab in your browser, you will not be able to save the configuration. First you have to close the live stream, save configuration and then reopen the video tab.
The MJPEG/Stills stream is used to display live stream. What is nice about it is that you can use a direct URL for this http://localhost:8080/stream.
Since sharing live stream publicly is not necessarily a good idea we should do two things:
- add some authorization, so people who do not know the password won’t be able to log into uv4l server and change something,
- encrypt the connection itself, thus even if someone is sniffing your network, the traffic will be safe.
Let’s start with the first one. U4VL can have up to three predefined user types:
- admin, this user can to everything, change parameters, start live stream, everything what UV4L is capable of,
- config, he can change configuration file,
- user, he can only start live stream without modifying the parameters.
The password is not stored in open form it is encrypted as md5 hash. To create a md5 hash you can use Python and those lines:
import hashlib import getpass password = getpass.getpass("Enter password: "); hashlib.md5(str.encode(password)).hexdigest();
For example, hash for password ‘mysecretpassword’ will be ‘4cab2a2db6a3c31b01d804def28276e6’.
When you generate those three password you can edit the configuration file. It can be found under /etc/uv4l/uv4l-raspicam.conf. Inside this file you should find lines:
server-option = --user-password=AAAAA server-option = --admin-password=BBBBB server-option = --config-password=CCCCC
If there are commented out remove ‘#’ at the beginning of each line and substitute AAAAA, BBBBB, CCCCC with md5 hashes. Also alter this line
server-option = --md5-passwords=no
server-option = --md5-passwords=yes
After restarting uv4l service the server will be protected. The next thing is to use HTTPS instead of HTTP to encrypt the traffic. This can be done by altering three lines:
### HTTPS options: server-option = --use-ssl=yes server-option = --ssl-private-key-file=/etc/uv4l/privkey.key server-option = --ssl-certificate-file=/etc/uv4l/cert.pem
First one says that HTTPS should be used and the last two are paths to SSL private key and certificate respectively. There are two ways of obtaining the certificate: you can generate a self-signed one but each web browser will warn about that saying that this kind of certificate is untrusty but it will work! You can generate it with following commands:
Generate and save CSR (Certificate Signing Authority), it will prompt you for passphrase to secure the private key which will be saved to privkey.pem.
sudo openssl req -new > new.ssl.csr
Generate key for signing:
sudo openssl rsa -in privkey.pem -out new.cert.key
Generate certificate and key. The certificate will be valid for 100 days:
sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 100
Copy certificate and private key:
sudo cp new.cert.cert /etc/uv4l/cert.pem sudo cp new.cert.key /etc/uv4l/privkey.key
The other option is to generate Letsencrypt certificate. It is as easy as this single line:
letsencrypt certonly -d EXAMPLE.COM --agree-tos --email [email protected] --no-redirect --non-interactive --apache
But it requires you to have registered domain EXAMPLE.COM. Also you should pass a valid email [email protected]. Renewing a certificate is also very straightforward:
The certificates can be found under /etc/letsencrypt/live/EXAMPLE.COM/. You should be interested in files cert.pem and privkey.pem (remember to change its name to privkey.key to match the configuration in configuration file).
To set up different port change following line
server-option = --port=8080
Default encoding, resolution and frame rate can be changed with those lines:
encoding = mjpeg width = 640 height = 480 framerate = 30
Some image parameters like sharpness, contrast, brightness and saturation can be adjusted with:
sharpness = 0 contrast = 0 brightness = 50 saturation = 0
Also if you would like to rotate the image you can pass the number of degrees:
rotation = 180
Or you can flip the image horizontally or vertically:
hflip = no vflip = yes
There are many more options. Just remember those are default parameters and can by changed with web interface!