PupPiCam
Full HD video streaming with a Raspberry Pi 2B
I was frustrated with the security nightmares of all the IP-webcams I tried, so I decided to build one myself. My usecase is purely indoor, the camera will only be used to observe the puppies of our bitch, when we are not in the same room - hence the creative name PupPiCam.
I don’t care for motion-detection or recording, but this could be done on another host, which has more power.
I will spare you with my failed ideas and attempts and document only the working solution. Also I will not explain how to physically mount the camera to the device.
The camera
You want to enable the legacy Raspicam camera stack, because it may perform better on Raspberry Pi 2 and Raspberry Pi Zero devices, as it offloads more to the GPU.
I bought a Pi NoIR Camera V2, plugged it in an RPi4 and played around with it.
$ ffmpeg -f v4l2 -list_formats all -i /dev/video0
ffmpeg version 4.3.3-0+rpt2+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 10 (Raspbian 10.2.1-6+rpi1)
---8<--- snip out boring build-configuration info --->8---
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
[video4linux2,v4l2 @ 0x1049cd0] Raw : yuv420p : Planar YUV 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : yuyv422 : YUYV 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : rgb24 : 24-bit RGB 8-8-8 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Compressed: mjpeg : JFIF JPEG : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Compressed: h264 : H.264 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Compressed: mjpeg : Motion-JPEG : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : Unsupported : YVYU 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : Unsupported : VYUY 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : uyvy422 : UYVY 4:2:2 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : nv12 : Y/CbCr 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : bgr24 : 24-bit BGR 8-8-8 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : yuv420p : Planar YVU 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : Unsupported : Y/CrCb 4:2:0 : {32-2592, 2}x{32-1944, 2}
[video4linux2,v4l2 @ 0x1049cd0] Raw : Unsupported : 32-bit XBGR 8-8-8-8 : {32-2592, 2}x{32-1944, 2}
/dev/video0: Immediate exit requested
The interesting part is:
[video4linux2,v4l2 @ 0x1049cd0] Compressed: h264 : H.264 : {32-2592, 2}x{32-1944, 2}
the camera supports h264 output natively! This means, I don’t have to encode anything on the CPU to get a Full HD video! Finally I can do something useful with one of my old Raspberry Pis!
Increase the memory for the GPU
You have to increase the amount memory for the GPU. I did not get the camera working in Full HD with less than 256MiB memory for the GPU.
Unfortunatelly this means, I can’t use my first old Raspberry Pi 1 Mod. B, which was manufactured with only 256MiB of RAM, but had to try a later model (after Oct. 2012) with 512MiB. But because the feeble Pi1 with its single core, can either handle enough bandwidth for the camera or the ethernet interface (which is internally connected via USB).
That’s why I use my “new” Raspberry Pi 2 B.
The server
Now we need a server which provides the video-stream on the network.
Nginx supports rtmp:// with an additional module.
$ sudo apt install libnginx-mod-rtmp nginx ffmpeg
Just add this at the end of your /etc/nginx/nginx.conf:
rtmp {
server {
listen 1935;
chunk_size 1024;
application webcam {
live on;
record off;
exec_static /usr/bin/ffmpeg
-f v4l2
-input_format h264
-s 1920x1080
-i /dev/video0
-vcodec copy
-f flv
rtmp://localhost:1935/webcam;
}
}
}
Now give the user, which runs nginx the permissions to use the video-devices:
$ sudo adduser www-data video
and restart your nginx:
$ sudo systemctl restart nginx.service
That’s it!
Run a video-player on your workstation/laptop, to enjoy the video:
$ mpv rtmp://<puppicam.my.local.network>/webcam
Because the video is quite noisy, my prefered way is to use ffplay with a denoise filter:
$ ffplay -vf atadenoise rtmp://<puppicam.my.local.network>/webcam
Day
Night
Yes, that’s the wrong dog, but he likes the whelping box (as long as there are no scary puppies inside).