With fanout switched off (FanoutMode::legacyDelivery(), which is also true
when the licence denies fanout), live delivery goes back to the paths that
ADR 0003 Phase E removed. Each is restored from git history:
- HLS (E3): live.php serves HLSGenerator::generateHLS() over the on-disk
playlist. segment.php serves on-disk LIVE segments again through
X-Accel /xc_hls/, AES-128-encrypting on first read, and burns a pending
send-message signal with SignalSender. generateHLS now mints tokens with
Encryption::mintToken (so secure_stream_tokens applies), rewrites one
segment line at a time (a str_replace of 1_1.ts also hit 11_1.ts), and
tokenizes an fMP4 init map.
- TS (E2): live.php chase-reads the on-disk segments again (SegmentReader
and its test restored). $rSegmentSettings, which the old loop read but
never defined, is now set there. A signalled segment is no longer sent
twice.
- Proxy streams (E1): StreamProcess::startProxy() starts ProxyCommand
(XC_VMProxy[<id>]), and live.php relays its datagrams from the viewer's
unix socket. Fixed while restoring:
- the read loop ended after its first read (a stray break);
- it spun on an idle source;
- it never exited when the last viewer left;
- it passed the proxy argument's whole row to ffmpeg;
- it ran ffmpeg with no input when no source opened.
Runtime state goes through StreamStateWriter.
With fanout on, nothing changes: a daemon that is merely down still gives
not-on-air until the keepalive restarts it, and segment.php still 404s
non-daemon live segments.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Es8UhyPS8MNjuYTagqfGWi