Follow-ups on the daemon HLS pipeline (0fc0e1c):
- engine/hls.go HLSSession.Register now closes every other active
session in the registry. Modeled as "one viewer == one transcode" so
repeated quality switches or page reloads don't leave orphan ffmpegs
saturating the CPU until the idle sweeper reaps them 30 min later.
- engine/hls.go restartFromSegment kills + respawns ffmpeg with
-ss / -output_ts_offset / -start_number when the browser asks for a
segment far ahead of the writer head. Segments already on disk stay
cached. Without this, a user dragging the scrubber to minute 30 of a
fresh stream blocks until the encoder reaches minute 30 in real time.
- engine/hls.go subtitle disambiguation: never set DEFAULT=YES on any
rendition (anime forced "signs only" tracks were autoselected and
rendered nothing during opening dialogue, looking broken). Names get
numeric suffixes when language is duplicated; FORCED tracks get a
"(forzados)" suffix.
- engine/hls.go ProbeInfo() exposes codec / audio / subtitle metadata
to the new GET /hls/<id>/probe.json endpoint for the player's info
badge + bandwidth logic.
- engine/hls.go scale chain fix: chains a trunc(iw/2)*2 scale after
the height cap so libx264 stops rejecting odd widths (853x480 etc.).
- engine/hls.go HW encoder tuning: NVENC -preset p4 -rc vbr -tune hq,
QSV -preset medium.
- engine/stream_server.go routes /hls/<id>/probe.json to the session.
- cmd/daemon.go runs an idle sweeper goroutine every 5 min, reaping
sessions whose last segment fetch was >30 min ago.
Introduces an HLS-over-HTTP path as Plan B for in-browser streaming. The
WebRTC + MSE pipeline keeps working untouched; the new path is selected
when the backend sets transport="hls" on a streaming session.
Daemon scope:
- engine/hls.go: HLSSession + HLSSessionRegistry. Spawns ffmpeg with
-f hls -hls_segment_type fmp4 + force_key_frames aligned with 4 s
segments. Pre-renders master + media playlists from the probe duration
so the browser knows the total timeline before any segment exists,
fixing seek/duration/pause/multi-track issues seen with the live fMP4
pipe.
- engine/probe.go: enumerate every audio + subtitle track instead of
collapsing to a single default audio track.
- engine/stream_server.go: route /hls/<id>/{master.m3u8,video/...,
subs/...} to the matching session. Emit a synthesised single-VTT
subtitle playlist per text track; bitmap subs (PGS/DVB) skip silently.
- cmd/daemon.go: branch on WebRTCSession.Transport == "hls" to register
an HLS session instead of running the legacy DataChannel pump.
- agent/types.go: WebRTCSession.Transport + AudioIndex fields.
Backend + web sides land in a follow-up commit.