Serve /stream.ts from one always-running encoder fanned out to every client
(TsBroadcaster) instead of spawning a fresh ffmpeg per connection: the process
count stays fixed at two (one HLS, one TS) no matter how many clients or
repeated on-demand pulls connect, and a joiner attaches to the live byte stream
with a keyframe-aligned prebuffer, so opening the channel is instant.
Emit TS keyframes every 0.4s so a consumer that joins mid-GOP (e.g. the panel's
LLOD probe with analyzeduration=0.5s) finds an IDR + SPS/PPS within its analysis
window — otherwise it reports "dimensions not set" and never starts.
Add run-background.sh (start/stop/status/restart, PID + log, auto-picks the
bundled XC_VM ffmpeg build that actually runs) and an M3u/ sample playlist;
refresh README to match.
Drop the sample.mp4 dependency: generate the source live with ffmpeg
`testsrc2` plus overlays — a big running stopwatch (elapsed), the real
wall-clock (handy to eyeball end-to-end latency), a frame counter and two
sweeping boxes; 1 kHz test tone for audio. Falls back to `testsrc` (v1,
built-in timestamp) when no TrueType font is found.
New flags: --size, --fps, --font (autodetected). Removed -i/--input and
--encode (the raw synthetic source is always encoded).
Long-run hardening so it can sit generating for days:
- --max-clients caps concurrent /stream.ts pulls (each is an ffmpeg);
extra connections get 503 instead of piling up processes/FDs.
- Per-client socket write timeout + TCP keepalive drops a stalled or
half-open peer instead of pinning its ffmpeg; hard-kill if terminate()
does not reap it.
- Per-request access logging is off by default (an HLS player polls every
few seconds and would flood the log over days); --verbose restores it.
The /stream.ts endpoint spawned a fresh per-client ffmpeg reading the file from the start, so the panel re-opening a channel always rewound to the beginning. Each client's ffmpeg now seeks to the current live position of the loop (offset = (now - start) %% duration); -ss lands on the nearest keyframe for a fast LLOD start, and clients connecting at the same wall-clock get the same offset (in sync).