diff --git a/static/app.js b/static/app.js index 4edcaca..a40b443 100644 --- a/static/app.js +++ b/static/app.js @@ -798,7 +798,21 @@ async function play(ep_id, ep_no) { // 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 // 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) => { if (data.fatal) { stopHls();