hls.js: put retry budget where 1.5.x actually reads it

maxNumRetry was set at the top of the load policy, which hls.js 1.5.x
ignores — it reads the budget from the errorRetry/timeoutRetry
sub-objects. Net effect before: a fragment-load *timeout* (a CDN that
starts sending then stalls) got only the default 1 retry before fatal
fragLoadTimeOut.

Now (verified resolved in-browser):
  maxTimeToFirstByteMs 15s   first byte
  maxLoadTimeMs        30s   total load (finite -> stalls time out)
  timeoutRetry.maxNumRetry 6  was 1
  errorRetry.maxNumRetry   8  our proxy's 502 path
This commit is contained in:
jozamudi committed 2026-08-31 01:22:22 +00:00
1 parent 83a2953a1c
commit d60524815f
1 file changed
+15 -1
+15 -1
View File
@@ -798,7 +798,21 @@ async function play(ep_id, ep_no) {
// before our proxy's 12s upstream attempt (+300ms retry) can answer with // before our proxy's 12s upstream attempt (+300ms retry) can answer with
// its 502 — keep TTFT past the proxy timeout so slow-but-alive segments // its 502 — keep TTFT past the proxy timeout so slow-but-alive segments
// finish, and the proxy's retry path gets a chance // finish, and the proxy's retry path gets a chance
hls = new Hls({ fragLoadPolicy: { default: { maxTimeToFirstByteMs: 15000, maxNumRetry: 8 } } }); // hls.js 1.5.x reads the retry budget from the errorRetry / timeoutRetry
// sub-objects (a top-level maxNumRetry is ignored — that was the old bug).
// maxTimeToFirstByteMs first byte within 15s
// maxLoadTimeMs total load within 30s — MUST be finite, else a CDN
// that starts sending then stalls hangs us forever
// timeoutRetry retries for a load *timeout* (was default 1!)
// errorRetry retries for HTTP errors like our proxy's 502
// Together: a slow/stalled CDN gets retried with backoff instead of one
// shot -> fatal fragLoadTimeOut.
hls = new Hls({ fragLoadPolicy: { default: {
maxTimeToFirstByteMs: 15000,
maxLoadTimeMs: 30000,
timeoutRetry: { maxNumRetry: 6, retryDelayMs: 1000, maxRetryDelayMs: 20000, backoff: "linear" },
errorRetry: { maxNumRetry: 8, retryDelayMs: 1000, maxRetryDelayMs: 20000, backoff: "linear" },
} } });
hls.on(Hls.Events.ERROR, (_, data) => { hls.on(Hls.Events.ERROR, (_, data) => {
if (data.fatal) { if (data.fatal) {
stopHls(); stopHls();