This is a collection of scripts to handle home surveillance cameras. It is in active development.
It is the embryo of my own "Zoneminder" replacement. Seriously, it is not a true replacement to Zoneminder or similar all-in-one surveillance solutions.
I have a personal preference for CLI tools and solutions, since they can be run anywhere (from Raspberry Pi Zero to cloud instances), it is simpler to understand how they are doing as well as doing incremental improvements.
Zoneminder is perfect when there is someone actually looking to the screen, and/or when there is a variety of video sources. My use case is different: all my cameras are IP; I just want to record them, rarely checking the footage. Live video is supplied by connecting directly to the cameras.
The following scripts are made to work independently, in a crude pipeline, each script generating data for the next one.
The scripts may look simple, they indeed are simple, but they already accumulate many hours of testing and debugging until they would work unattended for many days in a row.
This script records a RTSP stream in fixed time segments using ffmpeg. It handles many failure modes e.g. ffmpeg hangs.
The chosen video format is MKV since MP4 is corrupted if either ffmpeg or the camera stream is interrupted.
Ffmpeg uses relatively little CPU while recording RTSP, so you can record many cameras from the same computer, as long as the I/O can cope.
I set up my 1080p cameras as 10fps, H.265+, 2Mbps bitrate and VBR with maximum quality. Under these settings, the average bitrate of a mostly standstill environment is 256-300kbps (~3Gb/day) while still keeping very good image quality.
This script sweeps the current directory it is running in, and removes videos as the storage becomes nearly full (in default version, less than 10% free space).
I am still improving this script. It was written when only record_ffmpeg existed.
The interaction with concat and scanner is still pending.
The original idea was to have "black boxes", a couple hidden Raspberies with big SD cards,
with record_ffmpeg generating new content and janitor removing the oldest content.
Now I am moving towards cloud storage and processing.
This script uses the venerable DVR-Scan program to scan raw footage generated by record_ffmpeg,
detect movement, and produce a compact video with the "interesting" parts.
As you may guess, this process is very CPU-intensive. With the current settings, it achieves up to 120fps in an Intel NUC (Celeron J4125) for 1080p video, which I believe is satisfactory.
Original files are moved to raw/ if sucessfully processed, or to nok/ if they seem corrupted.
Footage with detected movements, hopefully much more compact than the original,
is written to ok/ folder in AVI format.
Hopefully the compact footage takes much less space than the original MKVs, so the same disk space can be stretched much further. (I still recommend storing a few days worth of raw footage, in case DVR-Scan missed something, or an event of interest must be scrutinized.) Note that, if there is movement in most of the raw footage, the "compact" AVI may be actually bigger than the original.
You can play with DVR-Scan parameters. In my example, the upper strip of the video is
disregarded (using -roi) since I prefer to keep the camera-generated
date and time labels.
The default sensitivity (parameter -t) is 0.15, I set it to 0.4 that works for me but
this can be different for your use case and I may tune it further in the future.
I also chose to record very little footage before and after the detection events
(-tb and -tp).
The -df parameter reduces the video size for the purpose of motion detection. It may
help with sensitivity calibration, but the major effect of this pre-reduction is
to increase analysis speed. I use the level -df 3.
DVR-Scan has experimental support for GPU-accelerated analysis (with NVidia cards, at least), so this is something one should experiment with, if dozens of cameras are to be analyzed in real-time.
Another possible trick (used by Zoneminder folks) is to run motion detection on an auxiliary, low-resolution RTSP stream (available in many IP cameras, mine included). If interesting events are detected an triaged, then the operator goes to the full-res footage.
Given the video encoder used by OpenCV, the compact videos can take more space than
the originals if they are long. The (re)encoding also consumes CPU.
The ideal would be to use -m copy but this generated mangled videos
for me. It may be fixable by tuning the I-frame interval in the camera, but I didn't dig
that deep yet.
The AVI videos generated by scanner may be very short. This script concatenates the
videos with events (again using ffmpeg) up to a predefined size (50MB), retaining
the name of the first AVI of the series. This makes them nicer to watch.
- test
scannerparameters with cameras in several different environments, internal and external - make
scannerwork with-m copyto avoid video reencoding costs - improve
janitorto remove old movement footage as well - try other methods of movement detection and object detection to further refine the results of
scanner - record the DVR-Scan text data (with event timestamps and durations) in a database or text file, so textual event reports can be compiled.
- Improve
concatfor the case of multiple cameras.