* switch the config interface over to use Retina and make the test button honor rtsp_transport = udp. * adjust the threading model of the Retina streaming code. Before, it spawned a background future that read from the runtime and wrote to a channel. Other calls read from this channel. After, it does work directly from within the block_on calls (no channels). The immediate motivation was that the config interface didn't have another runtime handy. And passing in a current thread runtime deadlocked. I later learned this is a difference between Runtime::block_on and Handle::block_on. The former will drive IO and timers; the latter will not. But this is also more efficient to avoid so many thread hand-offs. Both the context switches and the extra spinning that tokio appears to do as mentioned here: https://github.com/scottlamb/retina/issues/5#issuecomment-871971550 This may not be the final word on the threading model. Eventually I may not have per-stream writing threads at all. But I think it will be easier to look at this after getting rid of the separate `moonfire-nvr config` subcommand in favor of a web interface. * in tests, read `.mp4` files via the `mp4` crate rather than ffmpeg. The annoying part is that this doesn't parse edit lists; oh well. * simplify the `Opener` interface. Formerly, it'd take either a RTSP URL or a path to a `.mp4` file, and they'd share some code because they both sometimes used ffmpeg. Now, they're totally different libraries (`retina` vs `mp4`). Pull the latter out to a `testutil` module with a different interface that exposes more of the `mp4` stuff. Now `Opener` is just for RTSP. * simplify the h264 module. It had a lot of logic to deal with Annex B. Retina doesn't use this encoding. Fixes #36 Fixes #126
Introduction
Moonfire NVR is an open-source security camera network video recorder, started
by Scott Lamb <slamb@slamb.org>. It saves H.264-over-RTSP streams from
IP cameras to disk into a hybrid format: video frames in a directory on
spinning disk, other data in a SQLite3 database on flash. It can construct
.mp4
files for arbitrary time ranges on-the-fly. It does not decode,
analyze, or re-encode video frames, so it requires little CPU. It handles six
1080p/30fps streams on a Raspberry Pi
2, using
less than 10% of the machine's total CPU.
Help wanted to make it great! Please see the contributing guide.
So far, the web interface is basic: a filterable list of video segments, with support for trimming them to arbitrary time ranges. No scrub bar yet. There's also an experimental live view UI.
![]() |
![]() |
There's no support yet for motion detection, no https/TLS support (you'll need a proxy server, as described here), and only a console-based (rather than web-based) configuration UI.
Moonfire NVR is currently at version 0.7.2. Until version 1.0, there will be no compatibility guarantees: configuration and storage formats may change from version to version. There is an upgrade procedure but it is not for the faint of heart.
I hope to add features such as video analytics. In time, we can build a full-featured hobbyist-oriented multi-camera NVR that requires nothing but a cheap machine with a big hard drive. There are many exciting techniques we could use to make this possible:
- avoiding CPU-intensive H.264 encoding in favor of simply continuing to use the camera's already-encoded video streams. Cheap IP cameras these days provide pre-encoded H.264 streams in both "main" (full-sized) and "sub" (lower resolution, compression quality, and/or frame rate) varieties. The "sub" stream is more suitable for fast computer vision work as well as remote/mobile streaming. Disk space these days is quite cheap (with 4 TB drives costing about $100), so we can afford to keep many camera-months of both streams on disk.
- off-loading on-NVR analytics to an inexpensive USB or M.2 neural network accelerator and hardware H.264 decoders.
- taking advantage of on-camera analytics. They're often not as accurate, but they're the best way to stretch very inexpensive NVR machines.
Documentation
- Contributing
- License — GPL-3.0-or-later with GPL-3.0-linking-exception for OpenSSL.
- Change log / release notes.
- Guides
- Design documents
- Wiki has hardware recommendations, notes on several camera models, etc. Please add more!