I built RUSEON Core — a self-hosted server for working with RTSP cameras, video streaming, archive recording, and connecting AI pipelines.
The project came out of a work-related task. We needed to stream surveillance cameras to the website of a government organization. The cameras themselves are portable: they are installed with IoT routers and constantly move between different sites. Therefore, a traditional NVR at each site was not suitable — the video infrastructure had to be centralized. The task was simple: receive RTSP and deliver it as HLS (or any format that can be played in a browser without problems). We also needed 24/7 recording with at least two weeks of storage.
For the first three years — Wowza, everything worked well, but with huge resource consumption. Then — Flussonic, which was better, but even now 60 permanently active cameras and 15–20 occasionally active cameras consume around 10 GB of RAM.
At first I looked at MediaMTX, which seemed to be as close as possible to what I needed. But around the streaming layer, there were still many other things needed — UI, archive handling, camera-specific data, monitoring, AI integration.
Instead of forking MediaMTX, I took gortsplib as the foundation and started building my own system on top of it. The pipeline looks roughly like this: RTSP – RUSEON Core – WebRTC/HLS/Recording – gRPC – AI worker – AI Metadata. At the moment there is a web UI, Prometheus metrics, RBAC, camera tags and folders, camera history, traffic accounting, fragmented archive with timeshift, MQTT and gRPC integration.
For WebRTC/HLS, no unnecessary work is done. In 90% of cases, the Zero-Alloc and Zero-Transcoding principles are followed. In particular, one of the features is that when a codec is not supported, WebCodecs is used on the client side. As well as AI detection through ONNX Runtime in the browser (while still retaining the option of using traditional AI).
Some things in the implementation also turned out to be quite interesting, for example using the OS page cache so that the archive does not have to be kept in memory, and implementing batching through sendmmsg() for WebRTC, which reduced CPU load by about 27% in my tests. Speaking of tests, during an 8-hour test with 600 incoming RTSP streams, 18,000+ incoming FPS, 1,800 HLS viewers, 240 WebRTC peers, 10 API workers, 20 gRPC AI workers, and an event bus — average memory consumption was 707 MB, average CPU usage was 52.4%, with a peak of 98.1%. On average, about 3.2 cores out of 12 were used. (12 cores, 32 GB RAM)
An important clarification — the load generator and RUSEON Core were running on the same machine. This is not a distributed benchmark. Logically, the numbers should be better without competition for resources.
I don't consider the project finished yet. I especially want to understand whether the architecture itself makes sense and whether I am trying to solve too many things with a single server. I would be especially interested in feedback from people who have worked with RTSP/media servers, WebRTC, NVRs, or computer vision pipelines.
Top comments (0)