MiBee NVR
Turn any low-power ARM device into a professional NVR in 60 seconds.
Single binary, zero dependencies, no cloud required. Runs on low-power ARM devices with a 512MB memory budget.
!Idle RSS !Cold start !Capacity !Low tier
Self-measured — methodology and full curves in Performance.
中文 — English
Screenshots
!Surveillance grid Surveillance grid: multi-camera live view (WebCodecs / MJPEG) with health scores and AI overlay
!Recordings timeline Recordings: per-camera timeline with AI event markers; list and timelapse views available
!Cameras page Cameras: discovery scanning, drag-and-drop groups, start/stop, and push-out relay management in one place
Quick Start
One-click Install (Recommended)
curl -fsSL https://raw.githubusercontent.com/Mi-Bee-Studio/MiBeeNvr/main/install.sh | sudo bash
Downloads the binary, creates a system user (nvr), generates a config, installs a systemd service, and starts it. Data directory: /var/lib/mibee-nvr. Open http://localhost:9090 for the Web UI.
Docker
docker compose --project-directory . -f deploy/docker/docker-compose.yml up -d
To store recordings on an external drive, edit the volume mount and set NVR_DATA_DIR=/data to match (see the commented block in docker-compose.yml).
Other options: pre-built binary, build from source
# Pre-built binary (AMD64 / ARM64 / ARMv7)
wget https://github.com/Mi-Bee-Studio/MiBeeNvr/releases/latest/download/mibee-nvr-amd64
chmod +x mibee-nvr-amd64
./mibee-nvr-amd64 init --password yourpassword
./mibee-nvr-amd64 -config mibee-nvr.yaml
# Build from source
git clone https://github.com/Mi-Bee-Studio/MiBeeNvr.git
cd MiBeeNvr && make build
For detailed setup, see Getting Started.
Why MiBee NVR?
- Single Binary: Zero dependencies, embedded Svelte 5 SPA,
CGO_ENABLED=0 - Low-Power ARM Ready: Runs on 1GB RAM with a 512MB memory budget (validated on Raspberry Pi 3B as the minimum baseline)
- Plug-and-Play Auto-Discover: ONVIF cameras joining the LAN are enrolled automatically in the background — no manual scan; authenticated ones wait as pending activation until you supply credentials
- IP Self-Healing: Cameras that change IP (Wi-Fi roaming across APs) are auto-relocated by serial number and reconnected
- Adaptive Recording: Timelapse baseline that drops to sparse keyframes when calm and resumes full rate on motion or loud audio
- Browser-Side AI Detection: ONNX Runtime Web with WebGPU acceleration — no backend inference server
- Modern Web UI: Dark/light themes, Chinese / English / Russian, responsive; WebCodecs H.265 playback
- No Cloud Required: Self-hosted, no subscriptions, no vendor lock-in — remote access via Tailscale / Cloudflare Tunnel / WireGuard today, with a built-in encrypted remote mode on the way
Performance
Self-measured across three hardware tiers — methodology, judging criteria, and full resource curves are published in the benchmark report. Default configuration throughout; no manually-enabled optimization switches.
| Hardware | Load | Result | |---|---|---| | Any (idle) | — | 38 MB RSS, 122 ms cold start | | x86 desktop (i5-12600KF) | 68 cams · 226 Mbps recording, +32 concurrent viewers | 24% CPU, API p50 < 11 ms, zero failures | | RK3399 NAS (low tier) | 28 cams recording | 20–23% CPU (storage-bound, eMMC) | | Banana Pi M5 (production) | 18 cams, 80% iowait storm | health API p50 13.5 ms |
Supported Protocols
| Protocol | Direction | Notes |
|----------|----------|-------|
| RTSP | Camera → NVR | H.264/H.265/MJPEG |
| HTTP JPEG | Camera → NVR | Snapshot streaming |
| ONVIF | Camera ↔ NVR | Discovery, PTZ, stream URI, MotionAlarm events |
| Xiaomi (CS2 + TUTK) | Camera → NVR | CS2 P2P + legacy TUTK (7 models), cloud auth |
| GB/T 28181 | Camera → NVR | SIP platform, auto-enrollment, audio + talk, PTZ, device-side playback |
| SRT / RTMP (ingest) | Publisher → NVR | Push-in: remote publishers, low-latency transport |
| WHIP | Publisher → NVR | WebRTC push from browsers, phones, OBS 30+ (H.264 + Opus) |
| HLS | NVR → Viewer | On-demand with LL-HLS support |
| WebRTC (WHEP) | NVR → Viewer | Sub-second latency |
| HTTP-FLV | NVR → Viewer | Browser-friendly streaming |
| RTSP (output server) | NVR → External | Every camera re-served at rtsp:// |
| RTMP / RTSP (relay) | NVR → External | Native Go push-out to remote targets |
Documentation
Full index with one-line descriptions: docs/en/README.md. Most-visited entry points:
- Getting Started · Configuration · CLI · API Reference
- Deployment (incl. NAS guides: unRAID / fnOS / Synology / QNAP / iStoreOS / ZSpace) · Remote Access
- Troubleshooting · Upgrade Guide
docs/en/. Content published elsewhere — reprinted tutorials, "reviews", SEO aggregators — is not reviewed by us and frequently contains invented version numbers and benchmarks. If something you read elsewhere does not match the docs, trust the docs and please open an issue.
WeChat official account: 蓝宝石的傻话 (release announcements, in Chinese)
Contributing
- Run
make lintbefore submitting (golangci-lint v2;make lint-installfirst) and add tests for new features - Web SPA: Node 22,
cd web && npm run build && npm run test - Write clear commit messages
cmd/mibee-nvr/ CLI entry, internal/ core packages, web/ Svelte 5 SPA, deploy/ service files, docs/ bilingual documentation, tests/ + e2e-tests/ integration and Playwright tests. Details in the architecture overview.
Thanks to everyone who has contributed:
License
AGPL-3.0-only © Mi&Bee Studio, with a linking exception for pkg/:
- Using MiBee NVR (running it, recording cameras, watching streams): no obligations — use it freely, including commercially.
- Modifying and distributing it: your modified version must be released under AGPL-3.0.
- Building on
pkg/in your own program: allowed under the linking exception; your program's license is your choice. - Separate programs talking to a running NVR over its HTTP/WebSocket APIs: never affected by the license.