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;
}
async function syncAndAutoplay() {
if (!audioEl) return;
syncAudioToCurrentTrack();
// If the source changed, playback may not start immediately on some browsers
// until we wait for the new media to be ready.
if (audioEl.readyState < 2) {
async function waitForEvent(el: HTMLMediaElement, eventName: string) {
await new Promise<void>((resolve) => {
const el = audioEl;
if (!el) {
resolve();
return;
}
const onCanPlay = () => {
el.removeEventListener("canplay", onCanPlay);
const onEvent = () => {
el.removeEventListener(eventName, onEvent);
resolve();
};
el.addEventListener("canplay", onCanPlay, { once: true });
el.addEventListener(eventName, onEvent, { once: true });
});
}
async function syncAndAutoplay() {
const el = audioEl;
if (!el) return;
// Capture current src BEFORE syncing so we can detect changes reliably.
const beforeSrc = el.currentSrc;
syncAudioToCurrentTrack();
// If the src changed, some browsers require a "load -> playing" sequence.
// Strategy:
// - if src changed: ensure load is kicked, then wait for loadedmetadata/canplay
// - call play()
// - if it's still paused, wait for 'playing' and retry play once
const afterSrc = el.currentSrc;
if (afterSrc !== beforeSrc) {
// Ensure metadata exists (duration available, etc.)
if (el.readyState < 1) {
await waitForEvent(el, "loadedmetadata");
}
// Ensure enough data to play.
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 {
await audioEl.play();
await el.play();
} 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
}
}
}