From 1b300d2e1e55177b9558905c6450194aaa4519fe Mon Sep 17 00:00:00 2001 From: "every.channel" Date: Tue, 24 Feb 2026 22:09:24 -0800 Subject: [PATCH] web: force hls.js archive playback on chromium --- apps/web/app.js | 13 +++++++++++- .../ECP-0074-archive-hls-engine-selection.md | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 evolution/proposals/ECP-0074-archive-hls-engine-selection.md diff --git a/apps/web/app.js b/apps/web/app.js index 6eec15b..19f35d9 100644 --- a/apps/web/app.js +++ b/apps/web/app.js @@ -219,6 +219,17 @@ async function ensureHlsPlayerCtor() { return hlsModulePromise; } +function shouldUseNativeHls(video) { + const ua = navigator.userAgent || ""; + const vendor = navigator.vendor || ""; + const isIos = /iPhone|iPad|iPod/i.test(ua); + const isSafari = + /Safari/i.test(ua) && + /Apple/i.test(vendor) && + !/CriOS|FxiOS|EdgiOS|OPiOS|Chrome|Chromium/i.test(ua); + return (isIos || isSafari) && Boolean(video.canPlayType("application/vnd.apple.mpegurl")); +} + async function mountArchivePlayer(name) { clearPlayerSignals(); destroyArchivePlayer(); @@ -241,7 +252,7 @@ async function mountArchivePlayer(name) { mount.appendChild(video); const archiveUrl = `/api/archive/${encodeURIComponent(name)}/master.m3u8`; - if (video.canPlayType("application/vnd.apple.mpegurl")) { + if (shouldUseNativeHls(video)) { video.src = archiveUrl; void video.play().catch(() => {}); return; diff --git a/evolution/proposals/ECP-0074-archive-hls-engine-selection.md b/evolution/proposals/ECP-0074-archive-hls-engine-selection.md new file mode 100644 index 0000000..0e334b7 --- /dev/null +++ b/evolution/proposals/ECP-0074-archive-hls-engine-selection.md @@ -0,0 +1,21 @@ +# ECP-0074: Archive HLS Engine Selection For Chromium + +## Context + +Archive mode currently chooses native HLS whenever `video.canPlayType("application/vnd.apple.mpegurl")` is non-empty. + +Chromium may report support but still fail to actually play event-style fMP4 HLS in this path, leaving the player stuck at `readyState = 0`. + +## Decision + +Use native HLS only on Safari/iOS user agents. For all other browsers (including Chromium), force `hls.js` playback. + +## Why + +- Restores archive playback on Chrome/Chromium. +- Keeps Safari native path where it is reliable. +- Preserves a single URL and UI flow (`/api/archive/.../master.m3u8`). + +## Reversibility + +Revert the UA gate and return to the previous `canPlayType`-only check.