Skip to content

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

364 Commits

Folders and files

Repository files navigation

ONVIFscanner NVR

ONVIFscanner NVR

Local-first Web-App zum Finden und Identifizieren von ONVIF-, RTSP- und HTTP/IP-Kameras im eigenen Netzwerk.

Hinweis zur Lizenz: Dieses Projekt ist source-available zur freien Nutzung für nicht-kommerzielle Zwecke (siehe LICENSE). Es ist damit nicht “Open Source” im OSI-Sinne, auch wenn der Quellcode öffentlich ist.

Features

  • Kiosk- & Wand-Tablet-Modus: Spezieller Vollbild-Modus für Flur- und Wand-Tablets mit automatischer Display-Wachhaltung (Screen Wake-Lock API), Auto-Pop-up der aktiven Kamera bei erkannter Bewegung mit konfigurierbarem Countdown und intelligentem Bildschirmschoner (Display-Dimmer mit Digitaluhr).
  • Kennzeichen- & Fahrzeugspeicher (LPR): Zentrale Verwaltung bekannter Fahrzeuge und Personen. Erkennt bei Kameras mit aktivierter OCR automatisch bekannte Kennzeichen („Michaels Auto“) vs. unbekannte Fahrzeuge, sendet personalisierte Push-Benachrichtigungen und ermöglicht 1-Klick-Übernahme direkt aus dem Protokoll.
  • Web-Push Benachrichtigungen: Direkte Browser- und Smartphone-Push-Nachrichten (PWA) bei Alarmen ohne externe Dienste wie Telegram oder ntfy; automatische VAPID-Schlüsselverwaltung und Bereinigung inaktiver Abonnements.
  • Konfigurations-Backup & Wiederherstellung: Kameras, Zugangsdaten, Speicherziele und Einstellungen mit 1-Klick als portables JSON exportieren und wieder einspielen (Merge- und Replace-Modus).
  • Versionsverwaltung & Rollback: Schnelles Zurücksetzen auf vorherige Release-Versionen per 1-Klick im Web-Interface oder über die CLI (npm run rollback), inklusive automatischem SQLite-Datenbank-Backup.
  • Telegram- & ntfy-Alarmierung: Push-Benachrichtigungen inklusive Live-Vorschaubild bei Bewegungen oder Statuswechseln direkt aufs Smartphone (Bot-Token/Chat-ID für Telegram oder Topic für ntfy).
  • Zweisprachige Oberfläche: Vollständige Unterstützung für Deutsch und Englisch mit 1-Klick-Umschaltung im Header und in den Einstellungen.
  • Cybersecurity & Zugriffsschutz: Integriertes AuthGate für Passwort- oder PIN-Schutz der Web-App mit Brute-Force-Sperre, sicherem Session-Cookie und AES-256-GCM-Verschlüsselung gespeicherter Kamera-Passwörter (Zero-Plaintext on Disk).
  • Notfall-Reset via CLI: Passwort oder PIN jederzeit direkt über die Konsole zurücksetzen oder deaktivieren (npm run reset-password).
  • Speichermanagement & NAS-Anbindung: Lokale Speicheranzeige, 1-Klick-Rechte-Reparatur, Mounten von SMB/CIFS- und NFS-Netzwerkfreigaben direkt in der UI sowie automatische Bereinigung mit Mindest-Pufferschutz und konfigurierbarer Vorhaltezeit (Retention).
  • Interaktive Vorfall-Zeitleiste: Zoomstufen von 15 Minuten bis 24 Stunden, Mini-Map, Farbmarkierungen für Personen/Fahrzeuge und flüssiges Scrubben durch alle Aufnahmen.
  • Ein-Klick Auto-Scan: Kombiniert WS-Discovery, IP/CIDR-Portscan und Hersteller-Profile automatisch.
  • Kamera-Identifikation: Ermittelt Hersteller, Modell und Hostname per ONVIF, Vendor-API und Reverse-DNS soweit verfügbar.
  • Stream- & Snapshot-URLs: Sammelt bestätigte RTSP-, HTTP-Stream- und Snapshot-URLs und bietet Kopieren per Klick.
  • Hersteller-Profile: Unterstützt u. a. Hikvision/HiLook/Annke, Reolink, Dahua/Amcrest/Imou, Axis, Uniview, Geutebrück, Foscam/Instar und TP-Link Tapo/VIGI.
  • False-Positive-Filter: Reine HTTP-Geräte werden im Auto-Scan nicht automatisch als Kamera angezeigt.
  • Responsive UI: Desktop-Tabelle und Smartphone-Kartenlayout für bessere Bedienung unterwegs.
  • Auto-Korrektur von Kamera-IPs: Behebt das Problem falscher lokaler IPs, die von Kameras in RTSP-Links gemeldet werden.
  • Vorschaubilder: Lädt Snapshot-Bilder über einen Thumbnail-Proxy mit Basic/Digest-Unterstützung und begrenzter Parallelität.
  • Kamera-Wall: Speichert Scan-Ergebnisse lokal auf dem ONVIFscanner-Server und zeigt die Kameras in einem konfigurierbaren Raster mit Vollbildmodus und automatischer Aktualisierung.
  • Mobile Fokusansicht: Nutzt auf Smartphones die gesamte verfügbare Fläche, blendet Bedienelemente standardmäßig aus und zeigt Kameranamen als dezentes Overlay.
  • Kontextbezogene Kamerasteuerung: Zeigt Live- und Aktionsschaltflächen nur beim Antippen beziehungsweise per Desktop-Hover; seltene Aktionen liegen platzsparend im Drei-Punkte-Menü.
  • Live-Ansicht: Wandelt gespeicherte RTSP-Streams über MediaMTX in browserfähiges WebRTC um; ohne Live-Modus bleibt die robuste Snapshot-Aktualisierung aktiv.
  • Legacy-RTSP-Kompatibilität: Ältere Kameras mit /user=…_password=…_channel=…_stream=….sdp oder der entsprechenden &-Variante werden automatisch über FFmpeg an MediaMTX angebunden, ohne Video oder Audio neu zu kodieren.
  • Bewegungsaufnahme mit Ringpuffer: Speichert auf Wunsch nur relevante Bewegungsclips inklusive konfigurierbarem Vor- und Nachlauf; eine klassische Daueraufnahme bleibt weiterhin auswählbar.
  • Bewegungsmasken pro Kamera: Beliebig geformte rote Ignorierbereiche lassen sich mit einem Pinsel direkt auf das Kamerabild malen, damit etwa Bäume, Straßen oder Zeitstempel keine Aufnahme auslösen.
  • Lokale Objekterkennung: Optional bestätigt ein lokales COCO-SSD-Modell Bewegungen als Person, Fahrzeug oder Tier, ohne Kamerabilder an einen KI-Dienst zu senden.
  • Flexible Aufnahme-Strategien: Dauer- und Bewegungsaufnahme lassen sich pro Kamera rund um die Uhr, nur in einem Zeitfenster oder als automatische Kombination konfigurieren.
  • Tageszusammenfassung: Die Wiedergabe fasst Ereignisse und erkannte Objekte pro Tag und Kamera zusammen.
  • Kamera-Protokoll: Zeigt mit Zeitstempel, welche Kamera eine Bewegung gemeldet hat oder offline beziehungsweise wieder online gegangen ist.
  • Optionale Status-Pushs: Meldet Kamera-Wechsel zwischen online und offline auf Wunsch per Telegram und/oder ntfy.
  • Zentraler Aufnahme-Kalender: Monatsansicht mit markierten Aufnahmetagen, Clip-Anzahl und direkter Auswahl der an diesem Tag aktiven Kameras.
  • Gestengesteuerte Wiedergabe: Doppeltippen links oder rechts springt zehn Sekunden, längeres Halten spult schnell; weitere Player-Funktionen bleiben in einem kompakten Optionsbereich verborgen.
  • Filterbares Aufnahme-Archiv: Sortiert Aufnahmen direkt über die Tabellenspalten und filtert nach Kamera, Datum, Uhrzeit, Bewegung, Speicherort, Dateigröße oder Freitext.
  • Verständliche Logs: Pro Kamera gibt es einen Kurzstatus plus optionales technisches Log zur URL-/Auth-Erkennung.
  • Heimnetz-Gating: Standardmäßig nur private IP-Ranges (RFC1918) scanbar.

Wie funktioniert der Auto-Scan?

Der normale Workflow ist bewusst einfach:

  1. Suchbereich eintragen, z. B. 192.168.1.0/24.
  2. Optional Benutzername/Passwort für die Kameras eintragen.
  3. Scan Starten klicken.

Die App kombiniert danach automatisch:

  • WS-Discovery für ONVIF-Geräte.
  • CIDR/Portscan für typische Kamera-Ports wie 80, 443, 554, 8554, 8000, 8080, 8899.
  • ONVIF Media-Abfragen für echte RTSP-/Snapshot-URLs.
  • Hersteller-Profile für Kameras, die proprietäre Pfade nutzen.
  • Reverse-DNS / ONVIF Hostname / Vendor-Hostname zur besseren Identifikation.

Die erweiterten Scan-Einstellungen sind eingeklappt, weil sie im Normalfall nicht geändert werden müssen.

Kamera-Wall

Nach einem Scan können einzelne Kameras oder alle Ergebnisse über + Wall bzw. Alle zur Wall gespeichert werden. Unter /wall stehen anschließend zur Verfügung:

  • Raster mit 1 bis 6 Spalten (auf Smartphones automatisch einspaltig)
  • Überwachungsmodus im echten Browser-Vollbild ohne App-Header, Footer oder dauerhaft sichtbare Bedienelemente
  • automatische Snapshot-Aktualisierung oder manuelles Neuladen
  • Bearbeiten von Anzeigename, Snapshot-/Stream-URLs und lokal gespeicherten Zugangsdaten
  • Sortieren und Entfernen gespeicherter Kameras

Die Wall-Konfiguration wird lokal auf dem ONVIFscanner-Server in einer SQLite-Datenbank gespeichert. Falls ein Snapshot oder Stream eine Anmeldung benötigt, werden die Zugangsdaten ebenfalls dort gespeichert und nicht an externe Dienste übertragen. RTSP kann ein Browser nicht direkt darstellen; die normale Wall-Ansicht nutzt daher HTTP-Snapshots.

Der Schalter Live bereitet den ersten gespeicherten RTSP-Stream serverseitig über MediaMTX auf. Das Installationsskript richtet MediaMTX und ffmpeg automatisch ein. Vor dem Start prüft ONVIFscanner den Codec; nicht WebRTC-kompatible Streams wie H.265/HEVC bleiben automatisch in der Snapshot-Ansicht. Auf Smartphones werden zum Schutz vor Decoder- und Verbindungsabbrüchen höchstens vier Live-Streams parallel geöffnet. Für WebRTC muss der Client den LXC zusätzlich über UDP-Port 8189 erreichen können. Die Signalisierung läuft über dieselbe ONVIFscanner-Adresse und funktioniert dadurch auch hinter einem HTTP-Reverse-Proxy.

Aufnahme-Strategien

Für jede gespeicherte Kamera wird unter Aufnahmen oder direkt beim Bearbeiten genau eine verständliche Strategie gewählt. Ein separater, missverständlicher Zeitprofil-Schalter ist nicht mehr nötig:

  • Aus: Es werden keine Videodateien geschrieben.
  • Nur Bewegung – immer: Rund um die Uhr werden nur erkannte Bewegungen gespeichert.
  • Daueraufnahme – immer: Der RTSP-Stream wird rund um die Uhr in konfigurierbaren Segmenten archiviert.
  • Nur Bewegung – im Zeitfenster: Innerhalb des Zeitfensters werden Bewegungen gespeichert, außerhalb wird nicht aufgenommen.
  • Daueraufnahme – im Zeitfenster: Innerhalb des Zeitfensters wird dauerhaft aufgenommen, außerhalb nicht.
  • Im Zeitfenster Bewegung, sonst dauerhaft: Im Zeitfenster werden nur Bewegungen gespeichert, außerhalb läuft die Daueraufnahme.
  • Im Zeitfenster dauerhaft, sonst Bewegung: Im Zeitfenster läuft die Daueraufnahme, außerhalb werden nur Bewegungen gespeichert.

Bei allen zeitgesteuerten Strategien werden Start, Ende und Wochentage direkt darunter eingestellt. Zeitfenster über Mitternacht werden unterstützt. Der Monitor setzt einen Strategiewechsel spätestens innerhalb einer Minute um.

Bei einer Bewegungsstrategie schreibt MediaMTX kurze Segmente in einen temporären Ringpuffer. Bei einem ONVIF-, Webhook- oder optionalen Bildanalyse-Ereignis werden nur die Segmente vom Vorlauf bis zum Ende des Nachlaufs in das Aufnahme-Archiv übernommen. Nicht benötigte Pufferdaten werden automatisch gelöscht.

Standardmäßig nutzt die Bewegungsaufnahme 10 Sekunden Vorlauf und 30 Sekunden Nachlauf. Wiederholte Ereignisse verlängern das persistente Aufnahmefenster automatisch. Nach dem Nachlauf verbindet ffmpeg alle zugehörigen Ringpuffer-Segmente verlustfrei zu einem Bewegungsclip. Der temporäre Puffer liegt unter data/motion-buffer, Arbeitsdateien unter data/motion-staging; nur der fertige Clip wird in das gewählte Speicherziel übernommen. Aufnahmefenster und Ereignis-Zuordnung liegen in SQLite und überstehen dadurch einen Neustart der Anwendung.

Für Bewegungsaufnahmen schreibt der MediaMTX-Abschlusshook die tatsächliche Dauer eines geschlossenen Segments in eine .complete-Datei. Offene Segmente werden weder in einen Clip verschoben noch durch die Pufferbereinigung entfernt. Bei älteren Segmenten ohne Marker gilt ein stabiles Segment mit vorhandenem Nachfolger als abgeschlossen. Überlappende Vor- und Nachläufe werden zusammengeführt. Vor der Freigabe eines fertigen Clips werden Videospur und Dauer mit ffprobe geprüft; Zeitstempel und Ereignispositionen beziehen sich auf den tatsächlichen Beginn der übernommenen Segmente. Scheitert die Verarbeitung, bleiben die gestaffelten Eingangssegmente zur Fehleranalyse erhalten.

Im Kamera-Editor können außerdem rote Ignorierbereiche mit einem Pinsel direkt auf das Vorschaubild gemalt und mit dem Radierer wieder entfernt werden. Ein Raster ermöglicht mehrere kleine oder unregelmäßige Masken statt nur eines großen Rechtecks. Die Koordinaten werden proportional gespeichert und funktionieren daher unabhängig von der Analyseauflösung. Sobald eine Kamera eine Maske besitzt, wird ihre Bewegung ausschließlich durch die serverseitige Bildanalyse bewertet, da ONVIF- und Webhook-Ereignisse keine räumlichen Koordinaten für die Maske liefern.

Optional kann pro Kamera die lokale KI-Objekterkennung für Personen, Fahrzeuge und Tiere aktiviert werden. Sie läuft erst nach einer erkannten Bildbewegung in einem eigenen, niedriger priorisierten Prozess. Damit bleibt die rechenintensive Analyse vom Webserver isoliert, benötigt aber weiterhin CPU und RAM des Servers. Es läuft höchstens eine Analyse gleichzeitig, ein weiteres Bild darf warten. Modellstart und Bildanalyse haben getrennte Zeitlimits; nach einem Fehler wird der Analyseprozess vollständig beendet und vor einem erneuten Start pausiert. Ein Linux-RAM-Watchdog prüft den Prozess jede Sekunde (standardmäßig 512 MiB); zusätzlich ist dessen JavaScript-Heap auf 256 MiB begrenzt. Das ist kein hartes Gesamt-RAM-Limit der Anwendung und ersetzt keinen ausreichenden RAM für Aufnahmen, Webserver und Betriebssystem. Das Modell wird beim ersten Einsatz geladen; die Auswertung selbst findet vollständig auf dem ONVIFscanner-Server statt. Der Objektfilter arbeitet bewusst fehlersicher: Ist die lokale KI nicht verfügbar oder liefert sie kein ausgewähltes Objekt, entsteht kein ungefilterter Bewegungsalarm oder Bewegungsclip. Bereits laufende Daueraufnahmen hängen nicht von der KI-Freigabe ab. Zeitprofile erlauben zusätzlich Wochentage, auch über Mitternacht laufende Zeitfenster und eine eigene Empfindlichkeit. Masken, Objektfilter, Zeitprofil und Cooldown gelten einheitlich für Serveranalyse, ONVIF- und Webhook-Ereignisse. In der Wiedergabe zeigt die Tageszusammenfassung die Ereignis- und Objektzahlen je Tag.

Die Wiedergabe lädt Aufnahmen als HLS-Stream in kurzen H.264/AAC-Segmenten. Bei vorhandenen H.264-Aufnahmen werden die Videodaten ohne erneute Kodierung übernommen; die Segmentgrenzen folgen den echten Schlüsselbildern, ungefähr alle sechs Sekunden. Nur inkompatible Videoformate werden umgerechnet. Die Wiedergabegeschwindigkeit ist auf maximal 2× begrenzt. Der HLS-Player puffert ungefähr 30 Sekunden tatsächliche Abspielzeit voraus: 30 Videosekunden bei 1× und 60 bei 2×. Bei aktivem Auto-Play wird erst kurz vor dem Clipende der nächste Clip derselben Kamera vorbereitet. Scheitert HLS, versucht der aktive Player die Originaldatei direkt zu öffnen. Browser ohne MediaSource-Unterstützung verwenden, soweit verfügbar, den nativen HLS-Player; dessen Puffergröße bestimmt der Browser. Echte Aufnahmelücken und ein zu langsames Speicherziel können weiterhin Unterbrechungen verursachen.

Tageszeitleiste und Clip-Fortschrittsbalken lassen sich mit Maus oder Finger ziehen: Der Player zeigt beim Ziehen die zugehörigen Videobilder und springt beim Loslassen exakt zur gewählten Position, auch über Clipgrenzen hinweg. Innerhalb desselben Clips bleibt der vorhandene Player erhalten; grau hinterlegte Bereiche im Clip-Balken sind bereits gepuffert. Pause und Geschwindigkeit bleiben beim Scrubben erhalten. Positionswechsel während des Ziehens sind auf etwa einen pro 150 ms begrenzt; die letzte Position wird beim Loslassen sofort übernommen. Der HLS.js-Player reduziert dabei das Vorausladen auf etwa sechs Videosekunden und hält bis zu 30 Sekunden Rückwärtspuffer vor. Bereits gepufferte Stellen erscheinen ohne erneute Vorbereitung; noch nicht geladene oder umzuwandelnde Stellen benötigen weiterhin Ladezeit. Aufnahmelücken werden nicht durch einen Sprung zu einem anderen Zeitpunkt überspielt. Beide Leisten sind per Tastatur bedienbar (Pfeile: 1 Sekunde, Umschalt+Pfeil: 10 Sekunden, Pos1/Ende: Anfang/Ende).

Browser-Decoderfehler führen nicht mehr sofort zum Abbruchdialog. HLS.js baut zuerst einmal den Medienpuffer an derselben Position neu auf. Bei erneuten Decoderproblemen wechselt der Player einmalig auf kompatible, bedarfsgerecht erzeugte H.264/AAC-Segmente (compatibility=1); dabei wird auch normalerweise kopierbares H.264 neu kodiert. Diese Segmente haben einen getrennten Cache und teilen sich dieselbe Begrenzung auf einen FFmpeg-Auftrag mit einem Thread. Es wird kein kompletter Clip vorsorglich konvertiert. Der Wechsel erhält Abspielposition, Pause und Geschwindigkeit. Netzwerkfehler können wie bisher auf die Originaldatei zurückfallen; kann der Browser deren Format nicht dekodieren, bleibt der segmentierte Kompatibilitätspfad verfügbar. Jede Wiederherstellungsstufe hat ein Zeitlimit von 20 Sekunden, und die Stufen werden pro Clip nicht endlos wiederholt. Nach dem ersten Videobild bleibt während der Wiederherstellung nur eine dezente Ladeanzeige statt des blockierenden Dialogs. Erst wenn die Wiederherstellung scheitert, erscheint eine Fehlermeldung; eine kurze Clipdauer allein wird nicht mehr als Beschädigung oder Stream-Abbruch interpretiert. Die Browserkonsole enthält Fehlerart, Wiedergabepfad (normal/kompatibel/original) und Position zur Diagnose; echte Defekte oder dauerhaft unerreichbare Speicher können weiterhin die Wiedergabe verhindern.

Bei älteren RTSP-Kameras kann MediaMTX einen Stream trotz funktionierendem FFmpeg-Abruf mit Content-Type header is missing ablehnen. Für das oben genannte Legacy-URL-Format aktiviert die App deshalb automatisch ein Stream-Copy-Relay. Bei aktiver Aufnahme läuft es dauerhaft, bei ausgeschalteter Aufnahme nur auf Anforderung eines Lesers; MediaMTX beendet und startet den Prozess bei Bedarf beziehungsweise Verbindungsverlust neu. Die Kamera-URL bleibt gespeichert und wird nicht durch einen lokalen Link ersetzt. Der interne RTSP-Empfänger bindet ausschließlich an 127.0.0.1 mit einem dynamisch gewählten TCP-Port; es wird kein zusätzlicher RTSP-Port im LAN freigegeben. Der kurzlebige Node-Helfer liest die gespeicherte Konfiguration, danach läuft nur FFmpeg. Hook-Befehle enthalten lediglich Kamera-Kennung und Konfigurations-Fingerprint, keine Kamera-Passwörter. FFmpeg-Ausgaben mit möglicherweise eingebetteten Zugangsdaten werden nicht ins Journal geschrieben; dort erscheinen Relay-Start, Prozess-ID und MediaMTX-Status. H.265/G.711 bleiben bei der Weiterleitung unverändert: Das behebt die Aufnahme-Anbindung, nicht die H.265-Beschränkung der direkten WebRTC-Liveansicht. Das Relay selbst kodiert nicht neu; die bestehende H.264-Konvertierung beim Fertigstellen von H.265-Bewegungsclips und gegebenenfalls bei der browserkompatiblen HLS-Wiedergabe bleibt unverändert und benötigt weiterhin CPU.

Videosegmente liegen unter data/playback-cache/segments und werden wiederverwendet. Es wird höchstens ein Segment gleichzeitig vorbereitet; eine erforderliche Videokonvertierung verwendet einen FFmpeg-Thread und ist auf maximal 1280×720 Pixel sowie 4 Mbit/s mit begrenztem Bitratenpuffer ausgelegt. Der H.264-Kopierpfad behält die Originalqualität. Die Ermittlung der Metadaten wartet nicht hinter der Videokonvertierung. Bei neuen Segmenten werden alte Cachedateien nach 24 Stunden bereinigt; über etwa 2 GiB werden zusätzlich die ältesten, mindestens fünf Minuten alten Segmente entfernt. Die Originalaufnahmen und Downloads bleiben unverändert. npm run test:playback prüft Zeitzuordnung, Segmentgrenzen, Bildgleichheit beim H.264-Kopierpfad und FFmpeg-Ausgabe und benötigt ffmpeg und ffprobe.

Abgebrochene Wiedergabeanforderungen beenden nicht mehr benötigte Segmentarbeiten. Verwenden mehrere Betrachter denselben Auftrag, bleibt dieser für die übrigen Betrachter erhalten. Metadatenprüfungen sind auf zwei gleichzeitige Prozesse begrenzt. Scheitert das Vorladen des Folgeclips, kann der Player beim Wechsel auf dessen Originaldatei zurückfallen.

Im Videobild zeigt eine dezente Einblendung die tatsächliche Aufnahme-Uhrzeit mit Sekunden und Datum in der lokalen Zeitzone des Browsers. Sie folgt der aktuellen Abspielposition, auch bei Zeitsprüngen, 2× und über Mitternacht; die Clipdauer bleibt zusätzlich am Fortschrittsbalken sichtbar. Die Zeit im Player-Kopf ist ausdrücklich als Clip-Start gekennzeichnet.

Automatische Aufnahme- und Wiedergabetests

Voraussetzungen sind die Entwicklungsabhängigkeiten, ffmpeg und ffprobe. Für die Browserprüfung wird Chromium einmalig mit npx playwright install chromium installiert.

npm test
npm run test:recording
npm run test:recording:api
npm run test:playback
npm run test:playback:browser
npm run test:recording:rtsp
npm run test:legacy-rtsp:integration
npm run build

Der Aufnahmetest prüft offene Segmente, Vor-/Nachlauf, vollständige Bildanzahl und den Erhalt fehlerhafter Eingangsdateien. Die API-Prüfung deckt fertige Metadaten, ausgeblendete Teildateien sowie fehlende und nicht freigegebene Aufnahmepfade ab. Der Wiedergabetest prüft Zeitstempel einschließlich Sekundenbruchteilen, Mitternacht und Zeitumstellung, MP4/fMP4-Segmentierung sowie Abbruch und gemeinsame Nutzung von Aufträgen. Die Browserprüfung verwendet den echten Player mit simulierten API-Antworten in Desktop- und mobiler Chromium-Ansicht; sie prüft exakte Videobilder beim Ziehen mit Maus und Touch, Clipwechsel und Aufnahmelücken, unveränderte Scrollposition, abgebrochene Gesten und Segmentanfragen, Pause, Tastatur, maximal 2×, Folgeclip, erhaltene Aufnahmeliste und absichtliche HTTP-500-Fehler. Der RTSP-Test benötigt ein zum Betriebssystem passendes MediaMTX-Binary unter ./mediamtx oder in MEDIAMTX_BIN; er veröffentlicht lokal einen Teststream, unterbricht ihn und prüft die Bild-/Tonsegmente nach Wiederanlauf. Diese Prüfungen laufen auch in GitHub Actions. Sie ersetzen keinen Dauertest mit den eigenen Kameras, Netz- und Speicherzielen; natives iPhone-Safari wird durch die mobile Chromium-Ansicht nicht abgedeckt.

Der zusätzliche Legacy-RTSP-Test simuliert gezielt eine Kamera ohne SDP-Content-Type-Header. Er prüft die Ablehnung der Direktquelle, das echte FFmpeg-Relay mit H.265/G.711, abspielbare Aufnahmen, Start/Stopp auf Anforderung, automatische Wiederverbindung und das vollständige Beenden der Relay-Prozesse. Datenbank und Medien liegen ausschließlich in temporären Testverzeichnissen.

Unter Aufnahmen zeigt jede Kamera außerdem den Zustand ihrer Bewegungsquelle an: aktive ONVIF-PullPoint-Verbindung, Webhook, Snapshot-Fallback, laufende Prüfung oder einen konkreten Fehler. In der Wiedergabe ist jedes Bewegungsereignis direkt mit dem daraus erzeugten Clip verknüpft; die bisherige zeitbasierte Zuordnung bleibt als Fallback für ältere Aufnahmen erhalten.

Der systemd-Dienst startet die Anwendung im Produktionsmodus und startet sie nach einem unerwarteten Ende automatisch neu. Der Endpunkt /api/health steht für externe Zustandsprüfungen bereit. Der Kamera-Statusmonitor läuft standardmäßig alle 60 Sekunden. ONVIF-Bewegungsereignisse und Kamera-Webhooks werden unabhängig davon verarbeitet. Für Kameras ohne zuverlässige ONVIF-Ereignisse ist zusätzlich die ressourcenschonende serverseitige Bildanalyse standardmäßig aktiv. Die automatische Netzwerksuche bleibt standardmäßig deaktiviert.

Sicherheit & Zugriffsschutz (Cybersecurity)

ONVIFscanner legt großen Wert auf Datensparsamkeit und robuste Absicherung im LAN:

  • AuthGate (App-Passwort & PIN):
    • In den Einstellungen (/settings) kann ein Master-Passwort oder eine PIN aktiviert werden.
    • Sobald aktiv, schützt ein Anmeldedialog den Zugriff auf Kameras, Streams, Wall, Einstellungen und Aufnahmen.
    • Sichere Session-Cookies (HttpOnly, SameSite=Lax, mit 30 Tagen Gültigkeit).
    • Progressive Sperre (Brute-Force-Schutz): Nach mehreren Fehlversuchen wird der Login temporär gesperrt.
  • Passwort-Verschlüsselung auf der Festplatte (Zero Plaintext):
    • Alle für Kameras hinterlegten Passwörter werden vor dem Speichern in der SQLite-Datenbank mit AES-256-GCM verschlüsselt.
    • Der Verschlüsselungsschlüssel wird automatisch generiert und geschützt unter data/security.json verwaltet.
  • CSRF- & SSRF-Schutz:
    • Strenges Origin-Gating für alle mutierenden API-Endpunkte (POST/PUT/DELETE).
    • Validierung lokaler IP-Bereiche verhindert unberechtigte Zugriffe auf externe Netze.
  • Path-Traversal-Schutz:
    • Alle Dateizugriffe (Clips, Snapshots, Puffer) werden strikt auf erlaubte Zielverzeichnisse begrenzt.
  • HTTP Security Header:
    • Automatische Header wie X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN und restriktive Berechtigungsrichtlinien.

Notfall-Reset des App-Passworts

Solltest du das App-Passwort oder die PIN einmal vergessen haben oder ausgesperrt sein, kannst du den Schutz direkt über die Shell auf dem Server (z. B. im Proxmox Debian LXC) zurücksetzen:

# Interaktives Tool aufrufen (im Projektverzeichnis):
npm run reset-password

# Oder direkt via Node:
node scripts/reset-password.js

Das Skript erlaubt es dir, das Passwort direkt im Terminal neu zu vergeben, den Schutz vollständig zu deaktivieren oder die Dateiberechtigungen der Konfiguration zu reparieren. Alternativ kann die Datei data/security.json gelöscht werden, um den Auth-Schutz manuell zu entfernen.

Speichermanagement, NAS & Notfall-Schutz

Unter /nvr/storage (bzw. über das Menü "Speicher") bietet ONVIFscanner vollständige Kontrolle über lokale und entfernte Speichermedien:

  • Echtzeit-Speicheranzeige:
    • Zeigt den aktuellen Speicherplatz, belegten und freien Platz in Gigabyte sowie Prozent an.
  • NAS & Netzlaufwerke (SMB/CIFS & NFS):
    • Freigaben von Synology, QNAP, TrueNAS oder Linux-Servern können direkt über die Weboberfläche eingebunden werden – ganz ohne manuelles Hantieren im Terminal.
    • Automatische Integration in /etc/fstab für persistente Mounts auch nach einem Server-Neustart.
  • 1-Klick-Rechte-Reparatur:
    • Repariert Dateiberechtigungen (0775) und Eigentümer (onvifscanner:onvifscanner), falls ein Netzlaufwerk oder USB-Datenträger Schreibprobleme verursacht.
  • Automatischer Notfall-Pufferschutz & Retention:
    • Mindest-Freispeicher (Buffer): Garantiert, dass z. B. immer mindestens 5 GB freier Speicherplatz auf der Partition verbleiben. Fällt der freie Speicher darunter, löscht das System automatisch die ältesten Videosegmente.
    • Vorhaltezeit (Tage): Begrenzt die Lebensdauer von Aufnahmen (z. B. maximal 14 oder 30 Tage gemäß DSGVO).
    • Ordner-Hygiene: Automatische Bereinigung verwaister temporärer Ringpuffer- und Staging-Dateien.

Interaktive Zeitleiste & Vorfall-Prüfung

Unter /timeline steht eine intuitive Zeitleiste für die Überprüfung aller Überwachungsaufnahmen bereit:

  • Flexible Zoomstufen: Umschalten zwischen 15 Minuten, 30 Minuten, 1 Stunde, 3 Stunden, 6 Stunden, 12 Stunden und 24 Stunden.
  • Visuelle Mini-Map: Zeigt den gesamten Tagesverlauf auf einen Blick mit direkter Sprungfunktion zu auffälligen Ereignissen.
  • Farbcodierung: Aufnahmen mit erkannten Personen, Fahrzeugen oder reinen Bewegungsereignissen sind farblich hervorgehoben.
  • Flüssiges Scrubben: Direktes Spulen und präzise Zeitpunktauswahl synchronisiert mit der Videowiedergabe.
  • Kamera-Filter: Einzelne Kameras gezielt isolieren oder die Gesamtsituation im Überblick betrachten.

Zweisprachige Oberfläche (Deutsch & Englisch)

ONVIFscanner unterstützt Deutsch und Englisch vollständig:

  • Schnellumschaltung direkt über das Sprach-Symbol (DE/EN) im Header oder in den Einstellungen.
  • Alle Navigationselemente, Einstellungen, Kalender, Tageszusammenfassungen, Speicherstatistiken und Dialoge passen sich sofort an.
  • Datums- und Zeitformate sowie Monatsnamen im Archiv und in der Zeitleiste werden automatisch in der gewählten Sprache formatiert.

Woher kommen die Streaming-URLs?

Zuverlässige RTSP-Streaming-URLs kommen nicht aus dem ONVIF Device-Service-Endpunkt (/onvif/device_service), sondern aus dem ONVIF Media bzw. Media2 Service:

  • GetProfiles → liefert Profile (oft Main/Sub)
  • GetStreamUri → liefert die RTSP-URL pro Profil
  • GetSnapshotUri → liefert Snapshot-URL pro Profil

Zusätzlich prüft ONVIFscanner bekannte Herstellerpfade, z. B. Hikvision:

  • Snapshot Main: /ISAPI/Streaming/channels/101/picture
  • Snapshot Sub: /ISAPI/Streaming/channels/102/picture
  • RTSP Main: /Streaming/Channels/101
  • RTSP Sub: /Streaming/Channels/102

Wenn eine Kamera Authentifizierung verlangt, können die Zugangsdaten im UI eingetragen werden. Beim Kopieren können Credentials optional direkt an die URL angehängt werden.

Quickstart

Voraussetzungen: Node.js 20+

npm install
npm run dev

Dann im Browser: http://localhost:3000

Deployment (Debian LXC)

Schritt-für-Schritt inkl. Requirements (Node 20+, Build-Tools, libvips für sharp), systemd Service, Reverse Proxy und Updates:

Siehe: docs/DEPLOY_DEBIAN_LXC.md

Schnellinstallation/Update:

curl -fsSL https://raw.githubusercontent.com/Schello805/onvifscanner/main/scripts/debian-lxc/auto.sh | bash

Das Update verwendet einen Schnellpfad: Bereits installierte Systempakete, unveränderte npm-Abhängigkeiten und ein unverändertes Prisma-Schema werden übersprungen. Ist Git bereits aktuell, entfallen Build und Service-Neustart vollständig. Für eine erzwungene Neuprüfung und einen sauberen Rebuild:

Ab Version 0.13.2 installiert das LXC-Skript außerdem einen eng begrenzten systemd-Helper für den 1-Klick-Update-Button im Footer. Bei einer älteren Installation muss das Update auf 0.13.2 einmalig mit dem obigen Terminal-Befehl erfolgen; danach können weitere Updates direkt in der Oberfläche gestartet werden.

FORCE_SYSTEM_PACKAGES=true FORCE_REBUILD=true curl -fsSL https://raw.githubusercontent.com/Schello805/onvifscanner/main/scripts/debian-lxc/auto.sh | bash

Updates & Versions-Rollback

npm run build verweigert den Build, solange der systemd-Dienst dieselbe Projektinstallation verwendet. So wird .next nicht unter einem laufenden Aufnahme-/Webserver gelöscht. Der letzte vollständige Build wird während des Neubaus gesichert und bei einem Fehler wiederhergestellt; nach einem hart unterbrochenen Build wird die Sicherung beim nächsten Build berücksichtigt. Ein fehlgeschlagenes Update startet den Dienst nicht automatisch mit möglicherweise unpassendem Code oder Abhängigkeiten neu. Die Update-Skripte stoppen systemd/PM2 vor Paketinstallation und Build. Manuell immer zuerst systemctl stop onvifscanner ausführen, danach bauen und nur bei Erfolg systemctl reset-failed onvifscanner && systemctl start onvifscanner. Während des Stopps werden keine Aufnahmen erstellt.

Absturzdiagnose

journalctl -u onvifscanner -n 200 --no-pager
journalctl -u onvifscanner -f
free -h

oom-kill bedeutet, dass der Kernel einen Prozess wegen Speichermangel beendet hat; die gemeldete Speicher-Spitze betrifft den gesamten Dienst einschließlich Kindprozessen. Could not find a production build bedeutet dagegen, dass .next/BUILD_ID fehlt: Dienst stoppen, einen vollständigen Build erstellen und erst danach neu starten. Objekterkennung Timeout oder RAM-Limit verwirft bei aktivem Objektfilter das betroffene Ereignis; es ist kein bestätigter Objektalarm. Auf schwacher Hardware kann OBJECT_DETECTION_MODEL_BASE=lite_mobilenet_v2 in der Environment-Datei die KI entlasten (mit geringerer Erkennungsqualität); Änderungen benötigen einen Dienstneustart. RTSP-Protokollfehler einzelner Kameras und Paketverluste müssen zusätzlich an Quelle, Stream-URL und Netzwerk geprüft werden.

ONVIFscanner nutzt offizielle Git-Tags und GitHub-Releases (v0.16.0, v0.15.14, etc.). Sollte ein Update unerwartet Probleme bereiten, kann jederzeit auf eine vorherige Version zurückgesetzt werden.

1-Klick Update & Rollback (Web-Oberfläche)

Im Footer zeigt die Versionsanzeige (z. B. Rev. v0.16.0) den aktuellen Versionsstatus an:

  • 1-Klick Update: Aktualisiert auf die neueste Version von GitHub.
  • Rollback / Version wechseln: Aus einem Dropdown kann direkt eine beliebige vorherige Release-Version (oder main) ausgewählt und per Klick aktiviert werden.
  • Automatisches Datenbank-Backup: Vor jedem Update oder Rollback wird die SQLite-Datenbank automatisch gesichert (data/onvifscanner.db.backup-*).

Rollback über das Terminal (CLI)

Sollte die Web-App nach einem fehlerhaften Stand nicht mehr erreichbar sein, steht ein interaktives CLI-Tool bereit:

# Interaktives Rollback-Menü (zeigt die letzten Tags zur Auswahl):
npm run rollback

# Oder direkt mit Zielversion aufrufen:
npm run rollback v0.15.14

Konfiguration (Environment)

  • NEXT_PUBLIC_REPO_URL (optional): URL, die im Header/Footer als “Repo/GitHub” verlinkt wird.
  • ALLOW_PUBLIC_SCAN (default false): Wenn true, sind auch öffentliche IP-Ranges im CIDR-Scan erlaubt.
  • SCAN_MAX_HOSTS (default 4096): Oberes Limit der Hosts pro Scan-Request.
  • SCAN_CONCURRENCY (default 128): Standard-Concurrency beim IP/Port-Scan.
  • SCAN_TIMEOUT_MS (default 1200): Default-Timeout pro Socket/FETCH.
  • WS_DISCOVERY_TIMEOUT_MS (default 1800): Wartezeit auf WS-Discovery Antworten.
  • SCAN_VENDOR_MAX_DEVICES (optional): Begrenzung der Vendor-/URL-Prüfung pro Scan.
  • VENDOR_PROBE_CAMERA_BUDGET_MS (default 2500): Zeitbudget pro Kamera für Hersteller-/URL-Prüfung.
  • THUMBNAIL_MAX_CONCURRENCY (default 2): Max. parallele Thumbnail-Requests.
  • THUMBNAIL_SHARP_CONCURRENCY (default 2): sharp/libvips Parallelität.
  • THUMBNAIL_CACHE_TTL_MS (default 10000): Kurzzeit-Cache für generierte Vorschaubilder.
  • MOTION_BUFFER_SEGMENT_SECONDS (default 5): Länge der temporären Ringpuffer-Segmente für Bewegungsaufnahmen.
  • MOTION_BUFFER_DIR (default data/motion-buffer): Lokales Verzeichnis für den temporären Ringpuffer.
  • MOTION_STAGING_DIR (default data/motion-staging): Arbeitsverzeichnis zum Zusammenführen eines Bewegungsclips.
  • ENABLE_MOTION_DETECTION (default true): Aktiviert die serverseitige Bildanalyse für Kameras ohne gesunde ONVIF-Ereignisquelle.
  • MOTION_DETECTION_INTERVAL_MS (default 3000): Zielintervall der serverseitigen Bildanalyse; laufende Zyklen überlappen sich nicht.
  • MOTION_DETECTION_CONCURRENCY (default 2): Maximal parallel analysierte Kamerabilder; kleinere Werte begrenzen CPU-Spitzen.
  • MOTION_CONFIRMATION_FRAMES (default 2): Anzahl aufeinanderfolgender Bilder, in denen eine Änderung bestehen muss; reduziert kurze Bildfehler und Fehlalarme.
  • MOTION_ANALYSIS_WIDTH (default 192): Breite der CPU-schonenden Graustufen-Bewegungsanalyse.
  • MOTION_SOURCE_WIDTH (default 768): Breite des nur bei erkannter Bewegung nachgeladenen Detailbildes für Objekterkennung und Benachrichtigung.
  • MOTION_PIXEL_THRESHOLD, MOTION_AREA_THRESHOLD, MOTION_MEAN_THRESHOLD: Optionale Feineinstellung für Pixel-, Flächen- und mittlere Differenzschwelle.
  • ENABLE_OBJECT_DETECTION (default true): Erlaubt die pro Kamera aktivierbare lokale Person-/Fahrzeug-/Tiererkennung.
  • OBJECT_DETECTION_MODEL_BASE (default mobilenet_v2): Qualitätsstufe der lokalen COCO-SSD-Erkennung. lite_mobilenet_v2 reduziert CPU-Last, erkennt kleine Objekte aber ungenauer.
  • Lokale Kennzeichenerkennung: Im Kamera-Dialog optional pro Kamera aktivierbar. Nach bestätigter Bewegung wird nur bei einem erkannten Fahrzeug die lokale Tesseract-OCR gestartet. Die Bewegungsmaske gilt auch für OCR, erkannte Kennzeichen erscheinen strukturiert im Protokoll und Bilder werden nicht an einen Cloud-Dienst übertragen.
  • OBJECT_DETECTION_MODEL_URL (optional): Eigene lokale oder erreichbare URL für das COCO-SSD-Modell. Ohne Angabe wird beim ersten Einsatz das Standardmodell geladen; Kamerabilder verlassen den Server nicht.
  • OBJECT_DETECTION_TIMEOUT_MS (default 25000): Maximale Laufzeit einer einzelnen KI-Analyse nach dem Modellstart; länger wartende Bilder werden nicht mehr analysiert.
  • OBJECT_DETECTION_INIT_TIMEOUT_MS (default 90000): Separates Zeitlimit für Laden und Aufwärmen des KI-Modells.
  • OBJECT_DETECTION_MAX_RSS_MB (default 512): RAM-Watchdog des isolierten KI-Prozesses in MiB. Linux prüft zusätzlich während der Analyse; auf anderen Systemen wird nach Modellstart/Analyse geprüft. Ein höheres Limit benötigt entsprechend freien Arbeitsspeicher.
  • OBJECT_DETECTION_RETRY_MS (default 30000): Pause nach Timeout, Prozessfehler oder überschrittenem RAM-Limit; verhindert Neustart-Schleifen.
  • NTFY_IMAGE_WIDTH (default 960) und NTFY_IMAGE_QUALITY (default 82): Qualität des separat geladenen Alarmbildes für Ntfy.

Hinweis: Thumbnails werden separat nach dem Scan geladen. Wenn kein Bild abrufbar ist, bleibt die Kamera trotzdem in der Ergebnisliste und der Grund steht im Kamera-Log.

Lizenz

Siehe LICENSE und NOTICE.

Nutzung im Heimnetz

Dieses Tool ist für das eigene Heimnetz/LAN gedacht. Standardmäßig akzeptiert der CIDR-Scan nur private IP-Bereiche (RFC1918).

Thumbnails: Wenn aktiviert, werden pro gefundenem ONVIF-Gerät zusätzlich Snapshot-URLs aufgerufen (Image-Download), um eine Vorschau zu zeigen.

Development Notes

Architektur: docs/ARCHITECTURE.md Troubleshooting: docs/TROUBLESHOOTING.md

Contributing

Siehe CONTRIBUTING.md.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages