This document describes the architecture and internal design of the LightNVR system.
LightNVR is designed with a modular architecture that prioritizes memory efficiency and reliability. The system is composed of several key components that work together to provide a complete Network Video Recorder solution.
The architecture centers on go2rtc as the primary streaming backbone, with LightNVR providing configuration management, recording, detection, and a unified web interface.
┌─────────────┐ RTSP/ONVIF ┌─────────────────────────────────────────────────┐
│ Cameras │────────────────────▶│ go2rtc │
│ │ │ (Managed by LightNVR as child process) │
└─────────────┘ │ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ RTSP │ │ WebRTC │ │ HLS/frame.jpeg │ │
│ │ Server │ │ Server │ │ Endpoints │ │
│ │ :8554 │ │ │ │ :1984 │ │
│ └────┬────┘ └────┬────┘ └────────┬────────┘ │
└───────┼───────────┼─────────────────┼───────────┘
│ │ │
┌───────────────────────────────┼───────────┼─────────────────┼───────────┐
│ LightNVR │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Web Interface │ │
│ │ Live View (WebRTC/HLS) │ Recordings │ Settings │ Detection │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ ┌────────────────┴───────┐ ┌─────────┴─────────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────────┐ ┌────────────────┐ │
│ │ MP4 Recording │ │ HLS Streaming │ │ Detection │ │
│ │ (FFmpeg lib) │ │ (FFmpeg lib) │ │ (TFLite/ │ │
│ │ │ │ │ │ SOD/API) │ │
│ └────────┬────────┘ └──────────┬──────────┘ └───────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ SQLite Database │ │
│ │ streams │ recordings │ detections │ zones │ users │ settings │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Storage (/var/lib/lightnvr) │ │
│ │ recordings/mp4/ │ recordings/hls/ │ lightnvr.db │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
The core system is responsible for:
- Application lifecycle management
- Configuration loading and validation
- Signal handling and graceful shutdown
- Daemon mode operation
- PID file management
- Logging
- go2rtc process management (starting, monitoring, stopping)
Key files:
src/core/main.c: Main entry point and application lifecyclesrc/core/config.c: Configuration loading and managementsrc/core/daemon.c: Daemon mode functionalitysrc/core/logger.c: Logging system with syslog supportsrc/core/logger_json.c: JSON-formatted logging outputsrc/core/shutdown_coordinator.c: Coordinated shutdown of all componentssrc/core/mqtt_client.c: MQTT client for detection event publishingsrc/core/curl_init.c: Shared libcurl initialization
go2rtc is the heart of LightNVR's streaming architecture. It handles:
- Direct camera connections (RTSP, ONVIF, HTTP, etc.)
- WebRTC streaming for ultra-low-latency live viewing
- RTSP server for local re-streaming (used by MP4/HLS recorders)
- HLS segment generation
- Frame extraction via
frame.jpegendpoint (used for detection) - Two-way audio (backchannel) support
Key files:
src/video/go2rtc/go2rtc_process.c: Process lifecycle managementsrc/video/go2rtc/go2rtc_stream.c: Stream registration and API communicationsrc/video/go2rtc/go2rtc_integration.c: Integration layer with LightNVRsrc/video/go2rtc/go2rtc_consumer.c: Recording consumer managementsrc/video/go2rtc/go2rtc_api.c: HTTP API communication with go2rtcsrc/video/go2rtc/go2rtc_snapshot.c: Snapshot/frame extraction from go2rtcsrc/video/go2rtc/dns_cleanup.c: DNS resource cleanup for go2rtc
See GO2RTC_INTEGRATION.md for detailed documentation.
The video subsystem handles:
- Stream management (stream state, configuration)
- go2rtc coordination (registering streams, getting RTSP URLs)
- Recording to disk (MP4 and HLS formats)
- Detection-based recording triggers
Key files:
src/video/stream_manager.c: Manages stream state and configurationsrc/video/streams.c: Stream state implementationsrc/video/stream_state.c: Stream state machinesrc/video/stream_state_adapter.c: Stream state adapter layersrc/video/stream_protocol.c: Protocol-specific handling (TCP/UDP)src/video/stream_transcoding.c: Stream transcoding supportsrc/video/hls_writer.c: HLS (HTTP Live Streaming) recordingsrc/video/hls_streaming.c: HLS streaming managementsrc/video/hls/hls_unified_thread.c: Unified HLS writer threadsrc/video/hls/hls_context.c: HLS context managementsrc/video/hls/hls_directory.c: HLS directory/segment managementsrc/video/hls/hls_api.c: HLS API integrationsrc/video/mp4_writer.c: MP4 recording core writersrc/video/mp4_writer_core.c: MP4 writer core implementationsrc/video/mp4_writer_thread.c: MP4 writer thread managementsrc/video/mp4_writer_utils.c: MP4 writer utilitiessrc/video/mp4_recording_core.c: MP4 recording core logicsrc/video/mp4_recording_writer.c: MP4 recording writersrc/video/mp4_segment_recorder.c: Segmented MP4 recordingsrc/video/recording.c: Recording orchestration
The detection subsystem provides object detection and motion detection:
- Object Detection: TensorFlow Lite models, SOD (Simple Object Detection), or external API
- Motion Detection: ONVIF-based motion events from cameras
- Detection Zones: Polygon-based regions of interest per stream
- Detection-triggered recording: Start/stop recordings based on detection events
- Unified Detection Thread: Per-stream thread with pre/post detection buffering
LightNVR supports four recording modes based on the record and detection_based_recording flags:
record |
detection_based_recording |
Behavior |
|---|---|---|
false |
false |
No recording, no detection |
true |
false |
Continuous recording only (MP4 with trigger_type='scheduled') |
false |
true |
Detection-only recording (MP4 created only when detections occur) |
true |
true |
Annotation mode: Continuous recording + detection annotations linked via recording_id |
In annotation mode, the unified detection thread runs but does NOT create separate MP4 files. Instead, detections are stored in the database with a recording_id foreign key linking to the ongoing continuous recording.
Key files:
src/video/unified_detection_thread.c: Unified per-stream detection thread with buffering and annotation modesrc/video/detection.c: Core detection logicsrc/video/detection_config.c: Detection configuration managementsrc/video/detection_embedded.c: Embedded detection (SOD/TFLite)src/video/detection_integration.c: Model loading (TFLite/SOD/API)src/video/detection_model.c: Detection model managementsrc/video/detection_stream.c: Per-stream detection statesrc/video/api_detection.c: External API-based detectionsrc/video/sod_detection.c: SOD detection implementationsrc/video/sod_integration.c: SOD library integrationsrc/video/sod_realnet.c: SOD RealNet face detectionsrc/video/onvif_detection.c: ONVIF event-based detectionsrc/video/onvif_detection_integration.c: ONVIF detection integration layersrc/video/onvif_motion_recording.c: ONVIF motion-triggered recordingsrc/video/motion_detection.c: Motion detection processingsrc/video/motion_storage_manager.c: Motion recording storage managementsrc/video/pre_detection_buffer.c: Pre-detection circular buffer for capture before eventssrc/video/packet_buffer.c: Packet-level ring buffersrc/video/buffer_strategy_go2rtc.c: go2rtc-based buffer strategysrc/video/buffer_strategy_hls_segment.c: HLS segment buffer strategysrc/video/buffer_strategy_memory_packet.c: In-memory packet buffer strategysrc/video/buffer_strategy_mmap.c: Memory-mapped buffer strategysrc/database/db_detections.c: Detection storage with optional recording_id linkage
See SOD_INTEGRATION.md and ONVIF_MOTION_RECORDING.md for details.
The storage subsystem is responsible for:
- Managing recording storage with per-stream directories
- Implementing retention policies (standard vs detection recordings)
- Disk space management and automatic cleanup
- File organization by date
Key files:
src/storage/storage_manager.c: Storage management implementationsrc/storage/storage_manager_streams.c: Per-stream storage managementsrc/storage/storage_manager_streams_cache.c: Stream storage cachesrc/database/db_recordings.c: Recording metadata and retention queries
The database subsystem handles:
- Stream configurations (SQLite)
- Recording metadata with trigger types
- Detection results and zones
- User authentication and sessions
- ONVIF motion configuration
Key files:
src/database/db_core.c: Database initialization and connection managementsrc/database/db_schema.c: Schema version managementsrc/database/db_migrations.c: Migration execution enginesrc/database/db_streams.c: Stream configuration CRUDsrc/database/db_recordings.c: Recording metadata operationssrc/database/db_recordings_sync.c: Recording filesystem synchronizationsrc/database/db_detections.c: Detection result storagesrc/database/db_zones.c: Detection zone managementsrc/database/db_auth.c: User authentication and session managementsrc/database/db_events.c: Event loggingsrc/database/db_motion_config.c: Motion recording configurationsrc/database/db_maintenance.c: Database maintenance taskssrc/database/db_backup.c: Database backup supportsrc/database/db_query_builder.c: Dynamic query buildersrc/database/db_transaction.c: Transaction managementsrc/database/db_schema_cache.c: Schema caching for performance
The web interface provides:
- Live viewing via WebRTC (low latency) or HLS (compatibility)
- Recording playback with timeline scrubbing
- Stream configuration with detection zone editor
- ONVIF device discovery and auto-configuration
- PTZ (Pan-Tilt-Zoom) camera controls
- System settings, user management, and TOTP/MFA
- REST API for programmatic access
Key files:
src/web/libuv_server.c: Web server implementation using libuv + llhttpsrc/web/libuv_api_handlers.c: API route registrationsrc/web/libuv_connection.c: Connection managementsrc/web/libuv_file_serve.c: Static file serving with gzip supportsrc/web/libuv_response.c: HTTP response helperssrc/web/api_handlers_streams_get.c: Stream GET endpointssrc/web/api_handlers_streams_modify.c: Stream POST/PUT/DELETE endpointssrc/web/api_handlers_streams_test.c: Stream connection testingsrc/web/api_handlers_recordings_backend_agnostic.c: Recording CRUD endpointssrc/web/api_handlers_recordings_list.c: Recording list/filtersrc/web/api_handlers_recordings_playback.c: Recording playbacksrc/web/api_handlers_recordings_download.c: Recording file downloadsrc/web/api_handlers_recordings_files_backend_agnostic.c: Recording file operationssrc/web/api_handlers_recordings_sync.c: Recording filesystem syncsrc/web/api_handlers_detection.c: Detection API endpointssrc/web/api_handlers_detection_results.c: Detection result queriessrc/web/api_handlers_detection_models.c: Detection model listingsrc/web/api_handlers_motion.c: Motion detection APIsrc/web/api_handlers_retention.c: Retention policy APIsrc/web/api_handlers_timeline.c: Timeline segments and playbacksrc/web/api_handlers_auth_backend_agnostic.c: Login/logout/verifysrc/web/api_handlers_users_backend_agnostic.c: User CRUD, API keys, password managementsrc/web/api_handlers_totp.c: TOTP/MFA setup and verificationsrc/web/api_handlers_zones.c: Detection zone managementsrc/web/api_handlers_settings.c: System settingssrc/web/api_handlers_system.c: System info/restart/shutdownsrc/web/api_handlers_system_logs.c: Log viewing and managementsrc/web/api_handlers_onvif_backend_agnostic.c: ONVIF discovery and device managementsrc/web/api_handlers_ptz.c: PTZ camera controlsrc/web/api_handlers_go2rtc_proxy.c: go2rtc API proxysrc/web/api_handlers_ice_servers.c: WebRTC ICE server configurationsrc/web/api_handlers_streaming.c: HLS streaming endpointssrc/web/api_handlers_health.c: Health check endpointsweb/js/components/preact/: Preact components for the SPAweb/js/pages/: Page-level entry points
LightNVR is designed to be memory-efficient, with several strategies employed:
- go2rtc handles all camera connections and transcoding
- LightNVR only receives re-streamed video for recording
- Frame extraction for detection uses JPEG snapshots (not decoded video)
- Circular buffer of AVPackets for ONVIF motion detection
- Configurable duration (5-30 seconds)
- Memory-efficient packet cloning
- See MOTION_BUFFER.md
- Optional swap file for additional virtual memory
- Configurable swap size
- Used for non-critical operations to free physical memory for stream processing
LightNVR uses a multi-threaded architecture:
- Main Thread: Application lifecycle, signal handling, shutdown coordination
- go2rtc Process: Separate process managed by LightNVR (handles all camera I/O)
- HTTP Server Thread: HTTP/WebSocket event loop (libuv)
- Per-Request Threads: API requests handled in thread pool
- HLS Writer Threads: One per stream writing HLS segments
- MP4 Recording Threads: One per active MP4 recording
- Detection Threads: One per stream with detection enabled
- ONVIF Motion Threads: Event subscription threads per motion-enabled stream
- Health Monitor Thread: Monitors go2rtc and stream health
Thread synchronization uses mutexes and condition variables. The shutdown coordinator ensures ordered cleanup.
Camera (RTSP/ONVIF)
│
▼
go2rtc ──────────────────────────────┬─────────────────────┐
│ │ │
│ WebRTC │ HLS │ RTSP
▼ ▼ ▼
Browser LightNVR HLS LightNVR MP4
(Live View) Writer Thread Recording
│ │
▼ ▼
HLS Segments (.ts) MP4 Files
│ │
(Detection Thread Database
analyzes segments) Metadata
- Camera → go2rtc: go2rtc connects to cameras via RTSP/ONVIF/HTTP
- go2rtc → Browser: WebRTC for low-latency live viewing
- go2rtc → HLS Writer: Consumes go2rtc's RTSP output, writes .ts segments
- go2rtc → MP4 Recorder: Consumes go2rtc's RTSP output, writes MP4 files
- HLS Segments → Detection: Detection thread analyzes newest segments
- Detection → Recording Trigger: Detections can start/stop MP4 recordings
- User accesses web interface via browser
- Web server authenticates the user (session token or Basic Auth)
- Web server serves the SPA (Single Page Application)
- Client-side Preact app makes API requests
- Live viewing: Browser connects directly to go2rtc for WebRTC/HLS
- Recording playback: Browser requests MP4/HLS from LightNVR API
LightNVR uses SQLite for data storage. The schema is managed via numbered migration files in db/migrations/ (0001 through 0022). Below is the cumulative schema after all migrations.
Stores stream configuration:
CREATE TABLE streams (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
url TEXT NOT NULL,
enabled INTEGER DEFAULT 1,
streaming_enabled INTEGER DEFAULT 1,
width INTEGER DEFAULT 1280,
height INTEGER DEFAULT 720,
fps INTEGER DEFAULT 30,
codec TEXT DEFAULT 'h264',
priority INTEGER DEFAULT 5,
record INTEGER DEFAULT 1,
segment_duration INTEGER DEFAULT 900,
-- Detection (migration 0002)
detection_based_recording INTEGER DEFAULT 0,
detection_model TEXT DEFAULT '',
detection_threshold REAL DEFAULT 0.5,
detection_interval INTEGER DEFAULT 10,
pre_detection_buffer INTEGER DEFAULT 0,
post_detection_buffer INTEGER DEFAULT 3,
-- Protocol/ONVIF (migration 0003)
protocol INTEGER DEFAULT 0,
is_onvif INTEGER DEFAULT 0,
-- Audio (migration 0004)
record_audio INTEGER DEFAULT 1,
-- Detection API (migration 0011)
detection_api_url TEXT DEFAULT '',
-- Backchannel (migration 0012)
backchannel_enabled INTEGER DEFAULT 0,
-- Retention (migration 0013)
retention_days INTEGER DEFAULT 30,
detection_retention_days INTEGER DEFAULT 90,
max_storage_mb INTEGER DEFAULT 0,
-- PTZ (migration 0014)
ptz_enabled INTEGER DEFAULT 0,
ptz_max_x INTEGER DEFAULT 0,
ptz_max_y INTEGER DEFAULT 0,
ptz_max_z INTEGER DEFAULT 0,
ptz_has_home INTEGER DEFAULT 0,
-- Buffer strategy (migration 0015)
buffer_strategy TEXT DEFAULT 'auto',
-- ONVIF credentials (migration 0016)
onvif_username TEXT DEFAULT '',
onvif_password TEXT DEFAULT '',
onvif_profile TEXT DEFAULT ''
);Stores recording metadata:
CREATE TABLE recordings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
stream_name TEXT NOT NULL,
file_path TEXT NOT NULL,
start_time INTEGER NOT NULL,
end_time INTEGER,
size_bytes INTEGER DEFAULT 0,
width INTEGER,
height INTEGER,
codec TEXT,
created_at INTEGER DEFAULT (strftime('%s', 'now')),
-- Trigger type (migration 0010)
trigger_type TEXT DEFAULT 'scheduled', -- 'scheduled', 'detection', 'motion'
-- Protection and retention (migration 0013)
protected INTEGER DEFAULT 0,
retention_override_days INTEGER DEFAULT NULL
);Stores detection results:
CREATE TABLE detections (
id INTEGER PRIMARY KEY AUTOINCREMENT,
stream_name TEXT NOT NULL,
timestamp INTEGER NOT NULL,
label TEXT NOT NULL,
confidence REAL NOT NULL,
x REAL, y REAL, width REAL, height REAL,
recording_id INTEGER, -- Links to continuous recording in annotation mode
created_at INTEGER DEFAULT (strftime('%s', 'now')),
-- Tracking (migration 0009)
track_id INTEGER DEFAULT -1,
zone_id TEXT DEFAULT '',
FOREIGN KEY (recording_id) REFERENCES recordings(id)
);Stores polygon-based detection regions:
CREATE TABLE detection_zones (
id TEXT PRIMARY KEY,
stream_name TEXT NOT NULL,
name TEXT NOT NULL,
enabled INTEGER DEFAULT 1,
color TEXT DEFAULT '#3b82f6',
polygon TEXT NOT NULL, -- JSON array of {x, y} normalized points
filter_classes TEXT DEFAULT '',
min_confidence REAL DEFAULT 0.0,
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
FOREIGN KEY (stream_name) REFERENCES streams(name) ON DELETE CASCADE
);Stores user authentication information:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
salt TEXT NOT NULL,
role TEXT NOT NULL, -- 'admin', 'user', 'viewer'
email TEXT,
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
last_login INTEGER,
is_active INTEGER DEFAULT 1,
api_key TEXT,
-- Password lock (migration 0019)
password_change_locked INTEGER DEFAULT 0,
-- TOTP/MFA (migration 0021)
totp_secret TEXT,
totp_enabled INTEGER DEFAULT 0
);Stores active user sessions:
CREATE TABLE sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
token TEXT NOT NULL UNIQUE,
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
expires_at INTEGER NOT NULL,
-- Session tracking (migration 0018)
ip_address TEXT,
user_agent TEXT,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);Stores per-stream motion recording settings (migration 0020):
CREATE TABLE motion_recording_config (
id INTEGER PRIMARY KEY AUTOINCREMENT,
stream_name TEXT NOT NULL UNIQUE,
enabled INTEGER DEFAULT 1,
pre_buffer_seconds INTEGER DEFAULT 5,
post_buffer_seconds INTEGER DEFAULT 5,
max_file_duration INTEGER DEFAULT 300,
codec TEXT DEFAULT 'h264',
quality TEXT DEFAULT 'medium',
retention_days INTEGER DEFAULT 7,
max_storage_mb INTEGER DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY (stream_name) REFERENCES streams(name) ON DELETE CASCADE
);Stores motion-triggered recordings (migration 0020):
CREATE TABLE motion_recordings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
stream_name TEXT NOT NULL,
file_path TEXT NOT NULL UNIQUE,
start_time INTEGER NOT NULL,
end_time INTEGER,
size_bytes INTEGER DEFAULT 0,
width INTEGER,
height INTEGER,
fps INTEGER,
codec TEXT,
is_complete INTEGER DEFAULT 0,
created_at INTEGER NOT NULL,
FOREIGN KEY (stream_name) REFERENCES streams(name) ON DELETE CASCADE
);The LightNVR API follows RESTful principles:
- Resources are identified by URLs
- Standard HTTP methods (GET, POST, PUT, DELETE) for CRUD operations
- JSON for data exchange using cJSON library
- Authentication via session tokens or HTTP Basic Auth
- Proper status codes for success/error conditions
See API.md for detailed API documentation.
The frontend is a multi-page application with Preact components, built with Vite:
- Preact for component-based UI development
- Tailwind CSS for styling and responsive design with theme customization
- Vite for build tooling and bundling
- WebRTC for low-latency live viewing (via go2rtc)
- HLS.js for fallback streaming compatibility
- @tanstack/query for data fetching and caching
Key pages (web/js/pages/):
index-page.jsx: Live view entry pointrecordings-page.jsx: Recording browserstreams-page.jsx: Stream managementsettings-page.jsx: System settingssystem-page.jsx: System information and logsusers-page.jsx: User managementtimeline-page.jsx: Timeline playbackhls-page.jsx: Direct HLS viewerlogin-page.jsx: Authentication
Key components (web/js/components/preact/):
LiveView.jsx: Live camera grid with WebRTC/HLS/MSEWebRTCVideoCell.jsx,HLSVideoCell.jsx,MSEVideoCell.jsx: Video player cellsRecordingsView.jsx: Recording browser and playbackrecordings/: Modular recordings sub-components (filters, table, pagination)StreamConfigModal.jsx: Stream configuration with detection zonesStreamsView.jsx: Stream list and managementSettingsView.jsx: System settingsSystemView.jsx: System information dashboardsystem/: System sub-components (logs, memory, streams info, controls)timeline/: Timeline player components (segments, ruler, cursor, controls)UsersView.jsx: User managementusers/: User sub-components (add/edit/delete modals, TOTP setup, API keys)ZoneEditor.jsx: Detection zone polygon editorDetectionOverlay.jsx: Detection result overlay on videoPTZControls.jsx: Pan-Tilt-Zoom camera controlsThemeCustomizer.jsx: Theme selection and dark modeToast.jsx,ToastContainer.jsx: Notification systemSnapshotManager.jsx: Camera snapshot captureFullscreenManager.jsx: Fullscreen video managementUI.jsx: Shared UI primitives
Utilities (web/js/utils/):
auth-utils.js: Authentication helpersdom-utils.js: DOM manipulation utilitiessettings-utils.js: Settings managementtheme-init.js: Theme initializationurl-utils.js: URL parameter handling
Configuration uses INI format files (.ini) with the following sections:
[general]: PID file, log file, log level, syslog settings[storage]: Recording paths, retention, MP4 direct recording options[database]: SQLite database path[web]: Port, web root, authentication, session timeout, thread pool[streams]: Stream configuration[models]: Detection model storage path[api_detection]: External detection API URL, backend, confidence, class filter[memory]: Buffer size, swap settings[hardware]: Hardware acceleration[go2rtc]: WebRTC settings, STUN/TURN, ICE servers, proxy limits[mqtt]: MQTT broker connection, topic prefix, TLS, QoS[onvif]: ONVIF discovery settings and network
Stream configurations are stored in the SQLite database and managed via the API/web UI. System settings can be updated via the API or web UI and are persisted immediately. Some settings (like go2rtc port) require a restart.
See CONFIGURATION.md for detailed configuration documentation.
The Ingenic A1 SoC has only 256MB of RAM, requiring specific optimizations:
- go2rtc Efficiency: go2rtc handles camera connections, reducing LightNVR memory usage
- Staggered Initialization: Streams are initialized one at a time to prevent memory spikes
- JPEG-based Detection: Uses go2rtc's
frame.jpegendpoint instead of decoding video - Swap Support: Optional swap file for additional virtual memory
- Priority System: Ensures critical streams get resources when memory is constrained
LightNVR implements a robust shutdown coordination system to ensure clean and orderly shutdown of all components.
The shutdown coordination system follows a priority-based approach to ensure components shut down in the correct dependency order:
- Detection Threads (highest priority - 100): Shut down first since they depend on both MP4 writers and HLS streaming
- MP4 Writers (medium priority - 80): Shut down second since they depend on HLS streaming
- HLS Streaming Threads (lowest priority - 60): Shut down last as they are the foundation
- go2rtc Process (final): Terminated after all consumers are stopped
-
Shutdown Coordinator (
include/core/shutdown_coordinator.handsrc/core/shutdown_coordinator.c)- Centralized management of component registration and shutdown sequence
- Atomic operations for thread safety with minimal mutex usage
- Component state tracking during shutdown
- Priority-based shutdown sequencing
- Timeout mechanism to prevent hanging
-
Component Integration
- Components register with the coordinator during initialization
- Components check for shutdown signals in their main loops
- Components update their state when exiting
- Coordinator tracks component states during shutdown
- Main process initiates shutdown (via signal handler or user request)
- Coordinator sets shutdown flag and notifies components in priority order
- Components check shutdown flag in their main loops and begin cleanup
- Components release shared resources and update their state
- Coordinator waits for all components to stop (with timeout)
- go2rtc process is terminated
- Main process performs final cleanup when all components are stopped
This system prevents race conditions, deadlocks, and memory corruption during shutdown by ensuring components are stopped in the correct order and resources are properly released.
LightNVR is designed to be robust and self-healing:
- go2rtc Health Monitoring: Monitors go2rtc API and restarts on failure
- Stream Reconnection: go2rtc automatically reconnects to streams after network issues
- Graceful Degradation: Reduces functionality rather than crashing when resources are constrained
- Safe Shutdown: Ensures recordings are properly finalized during shutdown
- Crash Recovery: Recovers state from database after unexpected shutdowns
LightNVR implements several security measures:
- Session-based Authentication: Secure token-based sessions with configurable expiration
- TOTP/MFA: Two-factor authentication support via time-based one-time passwords
- Password Hashing: Passwords are stored as salted hashes (mbedTLS)
- Input Validation: All user input is validated to prevent injection attacks
- Role-based Access: Admin, user, and viewer roles with API key support
- Password Lock: Ability to lock user passwords against changes
- Minimal Dependencies: Reduces attack surface by minimizing external dependencies
Planned architectural improvements:
- go2rtc Native Recording: Use go2rtc's built-in recording capabilities
- Hardware Acceleration: Better support for hardware-accelerated video processing
- Webhooks: HTTP webhook notifications for detection events
- Multi-model Detection: Support for multiple detection models per stream
Note: Pre-detection buffer and MQTT event streaming have been implemented.