feat(streaming): seek-restart, single-session, idle sweeper, probe.json
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.
This commit is contained in:
parent
0fc0e1c21a
commit
eb2548f9a6
3 changed files with 295 additions and 25 deletions
|
|
@ -513,6 +513,25 @@ func runDaemonStart() error {
|
|||
}
|
||||
}()
|
||||
|
||||
// Periodic HLS session sweeper (every 5 min). Closes sessions whose last
|
||||
// segment fetch was over 30 min ago — kills the orphan ffmpeg + removes
|
||||
// the per-session tmpdir, so a tab that died mid-stream doesn't leak
|
||||
// disk space until daemon shutdown.
|
||||
go func() {
|
||||
ticker := time.NewTicker(5 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if n := streamSrv.HLS().SweepIdle(); n > 0 {
|
||||
log.Printf("[hls] swept %d idle session(s)", n)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start auto-scan goroutine
|
||||
scanPaths := daemonCfg.ScanPaths
|
||||
if len(scanPaths) > 0 && cfg.Library.AutoScan {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue