fix(stream): el modo copy ignora StartSec (offset EVENT rompe iOS nativo)

Un playlist EVENT cuyas entradas empiezan en 0 mientras los fragmentos
llevan tfdt desplazado (-ss + -output_ts_offset) es exactamente la forma
que el parser HLS nativo de iOS no traga: resume a 368s → error del player
y bucle de re-bootstrap de sesión en iPhone (observado 2026-06-10).

Copy produce siempre desde 0 con PTS absolutos reales: adelanta a la
reproducción a velocidad de I/O, así que el punto de resume aparece en la
timeline creciente en segundos y el seek de startPosition del player
aterriza con normalidad. Test de resume actualizado: el playlist debe
cubrir la timeline completa.
This commit is contained in:
Deivid Soto 2026-06-10 23:31:58 +02:00
parent 5a92df1e14
commit 9eb3e44153
2 changed files with 15 additions and 15 deletions

View file

@ -205,8 +205,9 @@ func TestHLSCopy_ResumeStartSec(t *testing.T) {
[]string{"-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p"},
[]string{"-c:a", "aac", "-b:a", "128k"}, 12)
_, pl := runCopySession(t, rt, src, 6)
// Resume covers roughly the back half (keyframe-snapped, so allow the
// full GOP of slack: 60 frames @30fps = 2s).
// StartSec must be IGNORED in copy mode: the playlist covers the FULL
// timeline from 0 (an offset EVENT playlist breaks iOS's native parser;
// the player seeks to the resume point itself). Sum ≈ full 12s.
var sum float64
for _, line := range strings.Split(pl, "\n") {
if strings.HasPrefix(line, "#EXTINF:") {
@ -215,8 +216,8 @@ func TestHLSCopy_ResumeStartSec(t *testing.T) {
sum += d
}
}
if sum < 4 || sum > 9 {
t.Errorf("resume EXTINF sum = %.2fs, want ≈6s (12s source, -ss 6, ±GOP)", sum)
if sum < 10.5 || sum > 13.5 {
t.Errorf("copy EXTINF sum = %.2fs, want ≈12s (StartSec ignored, full timeline)", sum)
}
}