Both of your cameras call themselves "I91ET", so the slimmed dashboard
showed two identical names.
- A nickname kept in the registry now wins wherever a camera is named:
cards, camera page, live view and its window title, pop-outs and the
recordings list. It survives a rescan, and clearing it falls back to
the camera's own name, then its model.
- Rename on the camera page also writes the camera's own name and
location over ONVIF SetScopes, so everything else on the network sees
them. Since SetScopes replaces every configurable scope, the others are
read and sent back untouched; the result is re-read from the camera and
reported as applied or adjusted, and the change is audited.
- cameraName() lives in a client-safe module, because the registry is
server-only and the dashboard names cameras in the browser.
- NEXT_DIST_DIR lets a build run while dev servers hold .next.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- npm run video:install downloads the pinned MediaMTX v1.21.0 for this
platform, verifies its SHA-256 against checksums committed in
src/lib/mediamtx-install.ts, and installs it into gitignored bin/.
- On server start, instrumentation launches MediaMTX with a generated
owner-only config: API and WebRTC signaling on 127.0.0.1, only the ICE
port (UDP 8189) on the LAN, a hashed per-boot API password, no
anonymous users, unused protocols off. Restarts on crash with backoff,
stops with the server; VIDEO_BRIDGE=off skips it.
- Camera streams are added to MediaMTX at runtime, on demand, with the
stored login; nothing with a password is written to disk or echoed.
- rtspSourceWithLogin() reads a profile's RTSP URI over ONVIF.
- Export vrek log (live video goal, decisions, codec finding).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Read-only settings and stream URLs (vrek gol-2nxgqjn), shaped by a
read-only probe of the real cameras (findings fnd-*) and decisions
dec-s205dvs and dec-gtw493s.
- src/lib/camera-settings.ts: reads streams, image, time/NTP and
network over ONVIF behind a CameraSettingsSource interface, so an
ISAPI source can be added later. Sections are read independently
and fail on their own with fixed text. RTSP URLs have credentials
stripped and use the registry host. camera.ts exports its cached
connect() and the profile helpers it shares with it (iss-7eaywtf).
- /cameras/[id]: server-rendered page with an access check, 404 for
unknown ids or non-private hosts, and a streamed Suspense section.
Shows streams (with copyable RTSP URLs and an ONVIF-login note),
image, time/NTP with a drift warning, and network, plus Refresh
and back. Copy falls back to execCommand over plain LAN HTTP,
where the clipboard API is unavailable (iss-s935a4n).
- Dashboard card: the name links to the camera page; a main-stream
summary line ("Main 4096×1860 · H.264 · 20 fps"); a manufacturer
of "ONVIF" is hidden (iss-pv2bvzj).
522 tests, 99.9% line coverage. Checked by the user in a browser
against both cameras. Refreshes the vrek export (the icon principle
now covers the page's new icons).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cameraErrorResponse now returns fixed text for each error class and
logs the original server-side. Upstream ONVIF/SOAP responses, socket
errors and credential-file paths no longer reach the browser (vrek
iss-tz5s098). CameraAuthError gains a missingLogin flag so the UI can
still tell "no login saved" apart from "login rejected".
Tests throw errors carrying a fake password and file path, and check
neither appears in any response. Closes the dashboard migration (vrek
iss-qbh3541). Refreshes the vrek export.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Discovers ONVIF cameras (Hikvision/Annke) over WS-Discovery, keeps a
server-side registry and an encrypted credential store, and serves
info, snapshot and credentials routes for each camera.
The home page is now a Server Component that lists known cameras from
the registry on load, without a scan (vrek iss-a0hz0py). The snapshot
refresh rate lives in the URL (?refresh=), and a scan refreshes the
server-rendered list.
Route input is validated with zod (iss-rjqy3hy), and /api/discover no
longer returns raw error messages (iss-dbwgww8). Adds
@tanstack/react-query and zod as dependencies, with a QueryClient
provider in the root layout.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>