Glide Vizion

Configuration reference

NVR is configured by a single config.yaml. Start it with nvrd -config config.yaml — or skip the file entirely on macOS, where the app manages it for you. You rarely need to edit it by hand: Settings → Configuration in the web app is a live editor that validates changes, snapshots history, and restarts the daemon for you.

This page is a tour of the knobs that matter. The shipped config.example.yaml documents every option inline; these are the ones worth knowing.

server#

KnobDefaultWhat it does
addr":8085"Listen address for the web UI and API.
debugfalseDaemon-wide structured debug logging. NVRD_DEBUG=1 works too.
log_filestdoutOptional bounded, rotating log file (log_max_mb, log_max_backups).
memory_modeautoDemand-aware Go memory sizing; grows with load, shrinks gradually.
trust_proxyfalseBelieve forwarded client-IP headers — only behind a known reverse proxy.
server:
  addr: ":8085"

storage & retention#

The heart of the config. Footage lands as ~20-second fMP4 segments plus a SQLite index.

KnobDefaultWhat it does
path./recordingsRecording root (single drive).
pathsMulti-drive list; each camera is pinned to one drive. Overrides path.
index_pathprimary rootWhere the SQLite index lives — point at the boot SSD on multi-HDD setups.
segment_seconds20Target segment length (keyframe-aligned). Keep near the default.
max_age_hours720Keep everything 30 days. The recommended primary policy. 0 = off.
total_gb10000Global size ceiling — a backstop, not the primary policy.
per_camera_gb0Per-camera size cap. 0 = unlimited.
min_free_gb0Evict a disk’s oldest if free space drops below this.
record_streams[main, sub]Which stream IDs are recordable.
record_by_defaulttrueWhether cameras without a record: field record.

Retention knobs are independent strategies — a pass only runs when its knob is non-zero, so combine them. Recommended: time-first (max_age_hours) with a size ceiling as a backstop. A single camera can override the window with retention_days.

cameras#

One block per camera. Minimum viable: an id, a name, and a main stream URL.

cameras:
  cam01:
    name: "Front Door"
    enabled: true
    record: true          # false = live-only, nothing written to disk
    retention_days: 90    # optional per-camera override of max_age_hours
    streams:
      - id: main
        url: "rtsp://admin:pass@192.168.10.201:554/Streaming/Channels/101"
        enabled: true
        audio: true
      - id: sub
        url: "rtsp://admin:pass@192.168.10.201:554/Streaming/Channels/102"
        enabled: true

See cameras & compatibility for URL formats per vendor and the devices shortcut for multi-channel DVRs.

thumbnails#

Scrub-preview sprites, decoded from the cheap sub stream. All optional — the defaults are sane.

KnobDefaultWhat it does
source_streamsubWhich stream to decode preview frames from.
cell_width / cell_height480x270Sprite cell size; match your sub stream’s native size for the crispest preview.
ms_per_cell1000One preview cell per second of footage.
cache_dirbeside recordingsDedicated sprite directory — put it on a fast internal SSD.
cache_max_gb0 (uncapped)Total sprite cache size; oldest evicted first.

playback#

KnobDefaultWhat it does
scrub_streamsubWhich recorded stream the timeline scrub preview seeks. Must be a recorded, low-res stream for instant scrubbing.

auth#

Off by default (LAN trust). Strongly recommended once the daemon is reachable from anywhere untrusted — including over the remote-access tunnel.

auth:
  enabled: true

On first run, a random admin password is written to <storage.path>/bootstrap_admin_password (mode 0600) — note it, sign in, then delete the file.

license#

Omit entirely for the built-in full-feature single-camera trial. Paid licenses are perpetual and unlock camera count and feature IDs; updates are never gated.

license:
  token_path: "/usr/local/etc/nvrd/license.token"

remote#

Managed remote access — see remote access for how it works before enabling.

remote:
  enabled: true
  device_name: "Office NVR"
  tunnel:
    enabled: true

Everything else#

Less-frequently touched sections, all documented inline in config.example.yaml:

  • mqtt — publish daemon/camera state to Home Assistant.
  • restream — re-serve streams as rtsp://<host>:8554/<camera>/<stream> without extra pulls to the camera.
  • time_sync — keep camera clocks correct (older Hikvisions revert to 1970 after brownouts and corrupt the timeline).
  • scrub_gop — shorten the scrub tier’s keyframe interval for lag-free scrubbing (control-plane writes, opt-in).
  • detection.local_motion — pixel-change motion evidence for analog/DVR channels that emit no native smart events.
  • updates — notify-only update checks against the signed release manifest.