A simple multi-webcam framegrab grid display service for Wyze RTSP or other HD-only cam streams that runs reliably on a Raspberry Pi 3b
To install the picamframegrid
service, you can copypasta the following line into your SSH terminal session:
git clone https://github.com/free5ty1e/picamframegrid.git && pushd picamframegrid && ./scripts/camgridinstall.sh && popd
This will only work on an xfce
desktop right now so if you have another installed it may not work. YMMV, and feel free to submit improvements - like other desktops support with a setting in the conf
file, or perhaps without a desktop...
- Is a service that utilizes multiple (give it a list) ffmpeg RTSP streams from Wyze cams (1080p only, no low-res streams are available via RTSP as far as I know so this breaks all other Pi cam grid repos that I am aware of - such as
camplayer
https://github.com/raspicamplayer/camplayer and which utilizesomxplayer
and also two customvlc
configs, mosaic implementation and multi-window - as soon as it tries to display two of my Wyze cams simultaneously it blanks out or flashes horribly in a seizure-inducing manner). - (DIRECT TO FRAMEBUFFER METHOD - NEW) These
ffmpeg
instances write their frames directly to the provided position on the screen / in the framebuffer (positions are provided in lists in the conf file along with the stream URLs in 2 additional arrays), which displays directly without an intermediate file or a need to compile multiple framegrabs into a single image. - (DESKTOP METHOD - OLD) These
ffmpeg
instances write their frames to the/ramdisk
folder, which is currently a30MB
RAM drive set up with the following/etc/fstab
entry:
cambuffer /ramdisk tmpfs size=30M,noatime,nodev,nosuid,noexec,nodiratime 0 0
- (DESKTOP METHOD - OLD) The frames are by default captured in
.tiff
format as it seemed to be the most reliable and fastest so far but can easily choose.jpg
or.bmp
. The format you choose in the conf file (/home/pi/.camgrid/camgrid.conf
) will be also utilized for the grid image format. - Capture size for each frame is by default
640x480
but you can change it in the conf file. gpu_mem=64
specifies the size of the GPU memory I am allocating in/boot/config.txt
- I've disabled the swapfile entirely with the following commands:
sudo dphys-swapfile swapoff && sudo dphys-swapfile uninstall && sudo update-rc.d dphys-swapfile remove && sudo systemctl disable dphys-swapfile
- I've installed
log2ram
( https://github.com/azlux/log2ram ) to really minimize SD card write cycles, and adjusted the log size to30MB
and enabled theram compression with the following setting in
/etc/log2ram.conf`:
SIZE=30M
# **************** Zram backing conf *************************************************
# ZL2R Zram Log 2 Ram enables a zram drive when ZL2R=true ZL2R=false is mem only tmpfs
ZL2R=true
# COMP_ALG this is any compression algorithm listed in /proc/crypto
# lz4 is fastest with lightest load but deflate (zlib) and Zstandard (zstd) give far better compression ratios
# lzo is very close to lz4 and may with some binaries have better optimisation
# COMP_ALG=lz4 for speed or Zstd for compression, lzo or zlib if optimisation or availabilty is a problem
COMP_ALG=Zstd
# LOG_DISK_SIZE is the uncompressed disk size. Note zram uses about 0.1% of the size of the disk when not in use
# LOG_DISK_SIZE is expected compression ratio of alg chosen multiplied by log SIZE
# lzo/lz4=2.1:1 compression ratio zlib=2.7:1 zstandard=2.9:1
# Really a guestimate of a bit bigger than compression ratio whilst minimising 0.1% mem usage of disk size
LOG_DISK_SIZE=40M
inotifywait
is utilized in another thread to watch for changes to the framegrab files, which triggers the frames to be assembled- frames are being assembled via the
imagemagick
montage
command in an a/b file pattern to/ramdisk
and then these a/b images are being set as thexfce
desktop background for a seamless frame update experience - The system auto logs into the desktop and starts the service, triggered by a custom
xsession.trigger
that I added to kick off the service once the desktop session has started - can just connect up to a monitor and watch your cameras after booting it up anywhere with network. - Can use the standard
/boot/wpa_supplicant.conf
to tell a Pi with wifi to auto connect to your network, here's an example article on how to do this: https://www.raspberrypi-spy.co.uk/2017/04/manually-setting-up-pi-wifi-using-wpa_supplicant-conf/
The direct_to_framebuffer
method (NEW):
- I am displaying 4 of my Wyze cams in a 2x2 configuration, top-left / top-right / bottom-left / bottom-right of the screen (positions and resolution of each frame configurable in the conf file)
-
- Handles 1/2fps (2 seconds per frame) each for the top 2 HD Wyze cam streams, and 1/15fps (15 seconds per frame) for the bottom 2 HD Wyze cam streams (so far that is what I have tested successfully)
- Each
ffmpeg
instance appears to eat up ~8-15% CPU time / ~4-5% memory in this configuration (on a Pi 3b at stock clock)
The desktop_xfce
method (OLD, was before I added option to only process non-keyframes):
- I am displaying 2 of my Wyze cams in a side-by-side grid
- Handles 4 seconds / frame without thermal throttling on a Raspberry Pi 3b with passive cooling / stock clock with ambient room temperature (~70*F)
- Thermal throttling occurs at anything faster than 3 seconds / frame in this configuration, but it still seems to work even at 1fps (fastest I've tried so far)
I will post more info about my findings on how reliable / performant this is on various Raspberry Pi's as I get a chance to test them. I even have a Pi Zero W here that should be able to handle this task in some capacity.
https://www.facebook.com/plugins/post.php?href=https%3A%2F%2Fwww.facebook.com%2Fchristopher.paiano.5%2Fposts%2F10157674178661879 https://www.instagram.com/p/CPwwF_SMJ89/
If desired, you can install the xfce desktop with the camgridinstallxfce.sh
script, which will prompt you to also set your desktop to auto login at the end via the raspi-config
command. This script will also set up the trigger needed to auto start the camgrid service once the xwindow session has started. You don't need any of this if you just use the default direct_to_framebuffer
method instead.
- Pre-built Raspberry Pi image, just edit the
/home/pi/.camgrid/camgrid.conf
file to set it up and thencamgridrestartservice.sh
- Better documentation, I guess
- Testing various potential improvements such as:
- attempting to optimize ffmpeg settings to use less memory / cpu
- trying various frame capture sizes and montage arrangements
- Anything else people may suggest