global player pt. 7 works kinda

This commit is contained in:
2026-02-06 02:04:21 -08:00
parent e91ea1761f
commit 5efe06e640

View File

@@ -95,32 +95,64 @@
audioEl.volume = snap.volume; audioEl.volume = snap.volume;
} }
async function waitForEvent(el: HTMLMediaElement, eventName: string) {
await new Promise<void>((resolve) => {
const onEvent = () => {
el.removeEventListener(eventName, onEvent);
resolve();
};
el.addEventListener(eventName, onEvent, { once: true });
});
}
async function syncAndAutoplay() { async function syncAndAutoplay() {
if (!audioEl) return; const el = audioEl;
if (!el) return;
// Capture current src BEFORE syncing so we can detect changes reliably.
const beforeSrc = el.currentSrc;
syncAudioToCurrentTrack(); syncAudioToCurrentTrack();
// If the source changed, playback may not start immediately on some browsers // If the src changed, some browsers require a "load -> playing" sequence.
// until we wait for the new media to be ready. // Strategy:
if (audioEl.readyState < 2) { // - if src changed: ensure load is kicked, then wait for loadedmetadata/canplay
await new Promise<void>((resolve) => { // - call play()
const el = audioEl; // - if it's still paused, wait for 'playing' and retry play once
if (!el) { const afterSrc = el.currentSrc;
resolve();
return; if (afterSrc !== beforeSrc) {
} // Ensure metadata exists (duration available, etc.)
const onCanPlay = () => { if (el.readyState < 1) {
el.removeEventListener("canplay", onCanPlay); await waitForEvent(el, "loadedmetadata");
resolve(); }
}; // Ensure enough data to play.
el.addEventListener("canplay", onCanPlay, { once: true }); if (el.readyState < 3) {
}); await waitForEvent(el, "canplay");
}
} else {
// Even if src didn't change, allow a minimal yield to let state settle.
await Promise.resolve();
} }
try { try {
await audioEl.play(); await el.play();
} catch { } catch {
// Autoplay may be blocked; user gesture will still allow manual play. // Autoplay may be blocked; bail out quietly.
return;
}
// If the browser didn't actually start playback, retry after 'canplay'/'playing'.
if (el.paused) {
if (el.readyState < 3) {
await waitForEvent(el, "canplay");
}
await Promise.race([waitForEvent(el, "playing"), Promise.resolve()]);
try {
await el.play();
} catch {
// ignore
}
} }
} }