System requirements
EdgeSite NVR runs on hardware you own. The recording and streaming core is a single native binary; AI detection uses your platform's hardware acceleration when available.
| Platform | Acceleration | Notes |
|---|---|---|
| macOS (Apple Silicon) | Core ML — Neural Engine + CPU | Recommended. A Mac mini comfortably runs multi-camera detection on the ANE. |
| Linux | AMD GPU via ROCm (MIGraphX) | CPU fallback available on any x86-64/ARM64 host. |
| Windows | AMD NPU (VitisAI) → DirectML → CPU | NPU support is opt-in via EDGESIGHT_USE_NPU=1. |
Storage: any local volume. Recordings are written as standard MPEG-TS segments — plan roughly per-camera bitrate × retention window. PostgreSQL backs the configuration and recording index.
Client apps: iPhone and iPad (iOS 17+), Mac (macOS 14+), and Apple TV (tvOS 17+).
Installation
EdgeSite NVR currently installs from source on an Apple Silicon Mac. The install script handles the prerequisites and downloads, so setup is three commands. Packaged installers for macOS, Linux, and Windows are in the works.
Prerequisites
- A Mac with Apple Silicon (M1 or later) running macOS 14+.
- Homebrew — the install script uses it to install the rest: Rust, PostgreSQL 16, and ffmpeg.
Install and launch
# 1. Get the source git clone <repository URL> cd edgesight # 2. Run the installer — checks/installs prerequisites (Rust, PostgreSQL 16, # ffmpeg), builds the server, and downloads + verifies the detection models # and Core ML runtime from edgesitenvr.com/downloads ./backend/scripts/install.sh # 3. Launch the server (supervised; auto-restarts on failure) ./run_edgesight.sh
On first launch the server initializes its configuration database, generates its credential-encryption key (master.key), and serves a setup portal on your LAN. Open the portal in a browser to create the admin account, then pair your first device by scanning the QR code it shows.
master.key. Camera credentials are encrypted at rest with this key. Store a copy somewhere safe — without it, stored credentials cannot be recovered.Model weights and the Core ML ONNX runtime are published at edgesitenvr.com/downloads with SHA-256 checksums; the install script fetches and verifies them for you.
Useful environment variables
| Variable | Purpose |
|---|---|
EDGESIGHT_MODEL_PATH | Path to the YOLO ONNX detection model. |
EDGESIGHT_CPU_ONLY=1 | Force CPU inference (skip GPU/NPU/ANE). |
EDGESIGHT_USE_NPU=1 | Windows: enable AMD NPU execution. |
Adding cameras
Three onboarding paths, all from the app:
1. Discover (ONVIF)
EdgeSite scans your network for ONVIF cameras and lists their stream profiles. With one or two profiles, main and sub streams are assigned automatically; with more, you pick which profile serves each role.
2. Vendor templates
Pick your camera brand — Hikvision, Dahua, Reolink, Amcrest, UniFi Protect, and others — enter the IP, credentials, and channel, and EdgeSite renders the correct RTSP URLs. UniFi Protect cameras use their native per-quality rtsps:// stream URLs.
3. Custom URLs
Paste any RTSP or RTSPS URL directly, with an optional second URL for a low-bandwidth sub stream. EdgeSite probes the stream to detect codec and resolution — no manual codec configuration.
AI detection
Object detection runs entirely on the NVR using YOLO models over ONNX Runtime. Detected objects include people, vehicles (car, truck, bus, motorcycle, bicycle), and animals.
- Motion gating: frames are screened by a motion pipeline with weather-aware filtering, so rain and snow don't flood the detector — while subject-scale motion still triggers reliably.
- Object tracking: detections are chained into tracks across frames, so one visit produces one event, not a burst of duplicates.
- Zones and masks: draw per-camera zones to scope detection and filter events by zone in the app.
- Process isolation: inference runs in a supervised worker process that is recycled automatically, keeping the recording core immune to inference-runtime faults.
Storage & retention
Retention is two-tier and event-protected. Full-resolution recordings, sub-stream recordings, and event archives each have their own window:
| Setting | Default | What it controls |
|---|---|---|
hd_retention_days | 7 | Full-resolution (main stream) continuous recording. |
sub_retention_days | 30 | Low-bandwidth sub-stream recording for long-tail review. |
event_retention_days | 90 | Detection events, snapshots, and their protected footage. |
Segments that overlap a protected event are preserved even after the continuous window expires. A disk-pressure guard runs hourly: at 80% usage you get a storage warning push; at 90% cleanup accelerates to bring usage back under 85% — oldest, non-event footage first.
Remote access
Remote access needs no port forwarding, no VPN, and no cloud DVR. Your NVR holds a persistent outbound connection to a lightweight signaling relay; when you open the app away from home, the relay authenticates your device against your NVR and brokers a WebRTC session. Video then flows peer-to-peer, encrypted, directly between your phone and your NVR.
- The relay routes authentication and signaling only — media paths are refused at the relay by design.
- NAT traversal is STUN-first (direct peer-to-peer); an encrypted TURN fallback covers hostile networks like CGNAT.
- Device access is revocable: remove a paired device in the app and its remote access dies with it.
- On your home network the app talks straight to the NVR over the LAN — the relay is never in the path.
Notifications
Push notifications carry a snapshot thumbnail and deep-link to the event. Delivery is tunable per camera:
- Alert frequency: Fewer / Normal / More per camera, mapped to per-object-class cooldowns.
- Cross-camera dedup: one person walking past three cameras is one alert, not three.
- Quiet hours: scheduled windows with per-label exemptions (e.g. still alert on "person").
- Actions: mute a camera — or everything — for an hour straight from the notification, without opening the app.
MQTT & webhooks
Both are opt-in and hot-reloaded — no restart required.
MQTT
mqtt_enabled = true
mqtt_host = 192.168.1.10
mqtt_port = 1883
mqtt_topic_prefix = edgesight # set to "frigate" for Home Assistant Frigate blueprints
Events publish to {prefix}/events in a Frigate-compatible JSON schema, with a retained availability topic and offline last-will — so Home Assistant automations built for Frigate work unchanged.
Webhooks
Set webhook_urls to one or more HTTP(S) endpoints. Each event POSTs the same JSON payload with an X-EdgeSight-Event header, with automatic retries.
Security model
- Device pairing: clients enroll by QR code on the LAN and receive a per-device token with a role. Tokens are stored hashed on the NVR; pairing never works remotely.
- Credentials at rest: camera passwords are encrypted with a locally generated master key that never leaves your NVR.
- Relay hardening: constant-time secret verification, per-IP rate limits, size caps, media-path refusal, and no stored user accounts.
- Media encryption: all remote video is SRTP/DTLS end-to-end between your device and your NVR.
- Memory safety: the recording core is written in Rust — a class of memory-corruption vulnerabilities common in C/C++ video software doesn't apply.