fix(stream): clamp out-of-range audio-track index to 0🅰️0

The web persists the chosen audioIndex globally, so a value from a
multi-track file can arrive for a file with fewer tracks. buildHLSFFmpegArgsAt
mapped `-map 0🅰️N?` verbatim; the optional `?` then matched nothing and the
HLS output had NO audio stream (video-only — 2026-06-03, Wistoria S02E08 had
one audio track but the session carried audioIndex=2). Clamp an out-of-range
index to the first track so audio is never silently dropped.

Regression test: TestBuildHLSFFmpegArgsAudioClamp.
This commit is contained in:
Deivid Soto 2026-06-03 18:55:42 +02:00
parent 2148b0e2cc
commit 1814d59e09
2 changed files with 51 additions and 0 deletions

View file

@ -1217,6 +1217,17 @@ func buildHLSFFmpegArgsAt(cfg HLSSessionConfig, probe *StreamProbe, tmpDir strin
}
}
}
// Clamp to an audio track that actually exists. The web persists the chosen
// audioIndex globally, so a value from a multi-track file can arrive for a
// file with fewer tracks; `-map 0:a:N?` would then match nothing and the
// optional `?` silently yields a VIDEO-ONLY stream (no sound — 2026-06-03,
// Wistoria S02E08 had one audio track but the session carried audioIndex=2).
// Fall back to the first track so audio is never silently dropped.
if n := len(probe.AudioTracks); n > 0 && audioIdx >= n {
log.Printf("[hls %s] audioIndex %d out of range (%d audio track(s)) — using 0:a:0",
shortHLSID(cfg.SessionID), audioIdx, n)
audioIdx = 0
}
args = append(args, "-map", fmt.Sprintf("0:a:%d?", audioIdx))
// Video encode. Codec + preset come from the EncoderProfile resolved at