Evidence clip export: concatenates the segments overlapping a time range and trims to
the requested window with -c copy (no re-encode). Keyframe-aligned (Stage 0 precision).
Network discovery: scan an IPv4 range / CIDR for cameras (open RTSP), then identify each by
probing a list of vendor RTSP paths with one or more credential sets (via ffprobe). Vendor-
agnostic: HikVision, Dahua, Axis, and generic/ONVIF paths are all tried. Optionally auto-
registers verified devices (recording disabled by default).
Health monitor: downgrades cameras that claim to be recording but have stopped producing
segments (a stalled-but-connected stream), emitting an event on the transition.
Timeline indexer: periodically scans each camera’s recordings directory, turning closed
segment files into rows in the segments table (the timeline index) and detecting gaps.
Live-view gateway integration: registers a camera’s stream as a MediaMTX path (server-side,
credentials never exposed to the browser) and returns HLS / WebRTC / RTSP playback URLs.
Dual / mirror recording: a SECOND, supervised ffmpeg pipeline per mirror_enabled camera that
writes byte-identical segments to HELDAR_MIRROR_RECORDINGS_DIR/{camera_id}/ (a redundant DVR
copy on a separate volume). It reuses the recorder’s [build_record_command] with the output dir
swapped, so the mirror files are indistinguishable from the primaries (same names, same codecs).
Segment-spanning HLS playback sessions: interactive review of recorded footage over a time range,
with native seek. A session concatenates the segments overlapping the requested window, trims to
the exact offsets, and remuxes (-c copy, no re-encode) into a self-contained HLS VOD playlist
under playback_dir/{session_id}/. HLS players seek freely within a VOD playlist.
Recorder supervisor: one FFmpeg process per camera, recording the configured stream
into time-segmented fragmented-MP4 files with -c copy (no decode). Supervises the
process, reconnects with backoff on stream loss, and maintains live camera status.
Plugin registry service (Phase C): fetch + verify + cache remote catalogs, and merge the bundled +
remote catalogs with live module state into the store view.
Retention sweeper: deletes recordings past each camera’s age policy, and enforces a global
size cap by pruning the oldest deletable segments. Segments under a durable evidence hold
(evidence_locked = 1) are never deleted, and a segment with a transient export read-lock
(locked = 1) is skipped while the export is in flight. Both are excluded from every prune.
AI frame sampler (Stage 2): for each (camera, stream_profile) that has an enabled AI task, decode
that stream at a budgeted frame rate and write the latest frame to frames/<cam>/latest_<profile>.jpg
(atomic rename, so readers never see a torn JPEG). AI workers pull frames on their own cadence.
A global FPS budget is shared across samplers, and the number of concurrent decoders is capped, so
adding AI cameras degrades gracefully instead of overloading the host (backpressure). AI workers
never touch RTSP directly — they consume sampled frames + post detections back.
Recording-schedule watcher. On each tick it asks the recorder to reconcile the time-based
cameras (scheduled / scheduled_event) whose recording state must change because a window just
opened or closed — so a recorder starts when the window opens and stops when it closes, without
waiting for an external API call. Continuous cameras are untouched (their reconcile is event-driven
on config change), and a camera already in the correct state is never restarted mid-window.
Scheduled interval snapshots. On each tick the scheduler fires any due snapshot_schedule
(enabled, and either never fired or its interval has elapsed since last_fired_at): it grabs a
live JPEG via the snapshot service, writes it to snapshots_dir/{camera_id}/{taken_at}.jpg,
records a snapshots row, and advances last_fired_at. Captured frames are pruned by the
retention sweeper past HELDAR_SNAPSHOT_RETENTION_HOURS. Spawned from main (supervised) only
when HELDAR_SNAPSHOT_SCHEDULER_ENABLED.
Storage / disk observability: free space on the recordings filesystem (via statvfs), the
recordings footprint, and a projected retention horizon from the recent write rate.
Webhook delivery engine — the SINGLE deliverer of generic events to external systems, superseding
the old single-URL alert notifier (whose stored app_state settings are folded into a “Default
alerts” subscription by the one-time legacy migration below).
Zone engine (Stage 3): evaluates tracked detections against per-camera polygon zones and raises
enter / exit / dwell events (with an evidence frame). State is keyed per (camera, zone, track),
held in memory, and driven by SERVER time (never the worker-supplied timestamp), so a skewed
worker clock cannot corrupt or evict state. A small confirm-frame debounce suppresses boundary
jitter, and a track still inside when its state expires gets a synthesized exit. Fed
synchronously from detection ingest.