# 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: ```text LUMI_STREAM_TEST_INGEST_HOST=the-hostname-reachable-from-the-streaming-computer ``` Optional controls: ```text 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: ```text npm run verify:stream-testing dotnet run --project companion/tests/Lumi.Companion.Core.Tests/Lumi.Companion.Core.Tests.csproj ```