4.1 KiB
Private stream testing
Lumi Stream Testing previews the real OBS output without publishing it to the normal stream destination. Start it from the core Stream testing page in Lumi Companion, then watch it at Admin > Stream testing.
Architecture
- The existing paired-device WebSocket authenticates session creation, OBS metrics, caption cues, stop requests, and server-ended notifications.
- The existing same-user OBS bridge snapshots the complete current OBS service, temporarily installs an expiring custom service, reports real output facts, and restores the snapshot.
- Companion protects the minimum recovery record with Windows DPAPI and writes it atomically before OBS is redirected. A normal stop, server failure, expiry, Companion exit, WebSocket loss, or OBS restart all use the same restore path.
- Core supervises one FFmpeg receiver process and creates a short rolling HLS window. HLS.js provides authenticated Chromium playback; native HLS remains available where the browser supports it.
- Stable transcription captions are reused as a private WebVTT side channel. No second transcription pipeline and no local speech inference are added.
Temporary HLS fragments exist only to serve the active admin player. They are bounded, deleted as they roll out, and removed when the session ends. Lumi does not retain a raw stream recording.
Server setup
Install a current FFmpeg build and ensure the Lumi service account can execute it. Set:
LUMI_STREAM_TEST_INGEST_HOST=the-hostname-reachable-from-the-streaming-computer
Optional controls:
LUMI_FFMPEG_PATH=/absolute/path/to/ffmpeg
LUMI_STREAM_TEST_INGEST_PORT=19350
LUMI_STREAM_TEST_PUBLIC_PORT=443
LUMI_STREAM_TEST_ENCODER=h264_nvenc
LUMI_STREAM_TEST_MAX_MS=1800000
LUMI_STREAM_TEST_INACTIVITY_MS=45000
LUMI_STREAM_TEST_MAX_BYTES=1073741824
Allow the configured ingest port only from trusted streaming networks. The
default RTMP hop uses a 256-bit, session-scoped credential and never exposes the
normal stream key, but RTMP itself is not encrypted. Put RTMPS at the network
boundary, set LUMI_STREAM_TEST_RTMPS=true, and set
LUMI_STREAM_TEST_PUBLIC_PORT to the proxy's external port. FFmpeg continues
listening on the private LUMI_STREAM_TEST_INGEST_PORT.
The player, playlists, segments, status, and stop endpoints always require an
active Lumi administrator session.
Lumi automatically selects h264_nvenc when the installed FFmpeg advertises
it, otherwise it uses bounded libx264. NVIDIA acceleration has no artificial
model lock: an RTX 3060 12 GB is a supported production baseline, faster cards
such as a 3080 Ti work without configuration changes, and CPU fallback remains
available. The ladder contains the source plus 720p and 480p only when the
source is larger, so it never upscales.
Safety and recovery
Companion refuses to start while OBS is streaming or recording. During a test its navigation status reads PRIVATE TEST ACTIVE. The DPAPI recovery file is removed only after OBS confirms that the saved service type and complete settings JSON were restored and saved.
If OBS was closed or unavailable during cleanup, open OBS and leave Companion running. Automatic restoration resumes when the same-user bridge reconnects. The Repair restoration action retries the same operation and does not create a new session.
The receiver stops on maximum duration, inactivity, temporary-storage limit, process failure, server shutdown, Companion disconnect, or an administrator stop. One active session is allowed today; UUID session identities and scoped paths are already used throughout so the model can be expanded later.
Deterministic verification
Run test pattern on the Admin page creates a 1280×720 moving color/timing pattern with a stable 880 Hz audio tone. It exercises receiver startup, transcoding, adaptive HLS, audio, quality switching, player cleanup, and diagnostics without OBS. It uses the same limits and temporary-media cleanup as a Companion session.
The focused checks are:
npm run verify:stream-testing
dotnet run --project companion/tests/Lumi.Companion.Core.Tests/Lumi.Companion.Core.Tests.csproj