In this post you’ll learn how to turn a webcam and a cheap Raspberry Pi into a powerful CCTV setup that allows you to stream video into any VLC compatible device. For this guide I picked a C920 HD camera and a Raspberry Pi 4, my goal was to be able to access a stream of that camera anytime from my phone / laptop.
The quickest way to go about this is to use Nginx to host an RTMP video stream that VLC can play. Later on we will run ffmpeg and publish the webcam video to the stream. To accomplish this we need to:
- Install nginx
apt install libnginx-mod-rtmp
- Append the following to
/etc/nginx/nginx.conf
:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
record off;
}
}
}
systemctl restart nginx
- Run ffmpeg and point it to the Nginx server:
ffmpeg -f v4l2 -input_format h264 \
-video_size 1920x1080 \
-i /dev/video4 \
-copyinkf -codec copy \
-f flv rtmp://127.0.0.1/live/stream
Now pick any device with VLC, go into “Open Network Stream” and connect your RTMP stream, for example: rtmp://10.0.0.2/live/stream
. Now you’ve a working stream that can be viewed form anywhere!
You may adjust ffmpeg settings:
-i
is the path of your camera: you may find it by listing your video devices before you connect the webcamto the board with ls /dev/video*
. The majority will be shown as more than one video device, you’ve to test what is the correct one;video_size
is the resolution;input_format
to h264 which is supported by both my webcam and the VLC clients so my RPi doesn’t waste CPU transcoding the video.
In the example above I’ve set the video to h264 and the format do flv. Please note that some cameras might not support this, for instance a cheap chinese webcam may only support mjpeg
:
ffmpeg -f v4l2 -list_formats all -i /dev/video0
[video4linux2,v4l2 @ 0x1b5ecd0] Compressed: mjpeg : Motion-JPEG : 1920x1080 1280x720 640x480 352x288 320x240 176x144 160x120
[video4linux2,v4l2 @ 0x1b5ecd0] Raw : yuyv422 : YUYV 4:2:2 : 1280x720 640x480 640x360
Video on Demand
The setup above works however it requires you to run ffmpeg manually and the webcam will always be streaming video, wasting CPU, energy. Fortunately Nginx is also capable of managing ffmpeg, let’s change our Nginx:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
exec_pull /usr/bin/ffmpeg -f v4l2 -input_format h264 -video_size 1920x1080 -i /dev/video4 -copyinkf -codec copy -f flv rtmp://127.0.0.1/live/stream;
record off;
}
}
}
We also need to add the www-data
user to the video group
:
sudo usermod -a -G video www-data
Now Nginx is dynamically launch ffmpeg when a client connects and kill it when nobody is connected. This is turn the camera on/off automatically as needed.
Enjoy!