global player pt. 7 works kinda
This commit is contained in:
@@ -95,32 +95,64 @@
|
||||
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() {
|
||||
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();
|
||||
|
||||
// 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) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const el = audioEl;
|
||||
if (!el) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const onCanPlay = () => {
|
||||
el.removeEventListener("canplay", onCanPlay);
|
||||
resolve();
|
||||
};
|
||||
el.addEventListener("canplay", onCanPlay, { once: true });
|
||||
});
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user