diff --git a/src/lib/components/player/PlayerRoot.svelte b/src/lib/components/player/PlayerRoot.svelte index 6d644c0..ab8c08b 100644 --- a/src/lib/components/player/PlayerRoot.svelte +++ b/src/lib/components/player/PlayerRoot.svelte @@ -16,6 +16,7 @@ // ... existing imports ... onMount(() => { + console.log("PlayerRoot mounted"); audioCtx.setElement(audioEl); // Load state @@ -25,56 +26,21 @@ } // Setup MediaSession - if ("mediaSession" in navigator) { - navigator.mediaSession.setActionHandler("play", () => { - audioCtx.paused = false; - }); - navigator.mediaSession.setActionHandler("pause", () => { - audioCtx.paused = true; - }); - navigator.mediaSession.setActionHandler("previoustrack", () => - player.prev(), - ); - navigator.mediaSession.setActionHandler("nexttrack", () => player.next()); - navigator.mediaSession.setActionHandler("stop", () => { - audioCtx.paused = true; - audioCtx.currentTime = 0; - }); - } + // ... }); - // Persist state changes - $effect(() => { - // Create a dependency on all persisted fields - const state = { - queue: player.queue, - currentId: player.currentId, - volume: player.volume, - isMuted: player.isMuted, - minimized: !player.uiOpen, - }; - saveState(state); - }); + // ... existing effect for persistence ... // Update MediaSession metadata - $effect(() => { - const track = player.currentTrack; - if (track && "mediaSession" in navigator) { - navigator.mediaSession.metadata = new MediaMetadata({ - title: track.title, - artist: track.artist, - album: track.album || track.animeName, - artwork: [ - // We could add artwork here if available in track - // { src: track.artworkUrl, sizes: '512x512', type: 'image/png' } - ], - }); - } - }); + // ... // ... existing effect for playback ... $effect(() => { const track = player.currentTrack; + console.log("Playback effect triggered", { + trackId: track?.id, + src: track?.src, + }); if (audioEl) { if (track) { const newSrc = track.src; @@ -83,7 +49,14 @@ // audioEl.src sets the attribute, currentSrc is the resolved URL const newSrcAbsolute = new URL(newSrc, document.baseURI).href; + console.log("Src check", { + currentSrc, + newSrcAbsolute, + match: currentSrc === newSrcAbsolute, + }); + if (currentSrc !== newSrcAbsolute) { + console.log("Setting new src", newSrc); audioEl.src = newSrc; audioEl.play().catch((e) => { console.warn("Autoplay blocked or failed", e); @@ -105,37 +78,25 @@ // ... existing callbacks ... // Bindings and Event Listeners - function onTimeUpdate() { - audioCtx.currentTime = audioEl.currentTime; - } - - function onDurationChange() { - audioCtx.duration = audioEl.duration; - } - - function onPlay() { - audioCtx.paused = false; - if ("mediaSession" in navigator) - navigator.mediaSession.playbackState = "playing"; - } - - function onPause() { - audioCtx.paused = true; - if ("mediaSession" in navigator) - navigator.mediaSession.playbackState = "paused"; - } - function onEnded() { player.next(); } + + // Sync MediaSession playback state with bound paused state + $effect(() => { + if ("mediaSession" in navigator) { + navigator.mediaSession.playbackState = audioCtx.paused + ? "paused" + : "playing"; + } + }); diff --git a/src/lib/components/player/ctx.svelte.ts b/src/lib/components/player/ctx.svelte.ts index 4a61833..c06de42 100644 --- a/src/lib/components/player/ctx.svelte.ts +++ b/src/lib/components/player/ctx.svelte.ts @@ -13,23 +13,25 @@ export class AudioContext { this.audioEl = el; } + // Bindings will handle state updates, but we need methods to control play/pause + // from other components. + // Since we bind to `this.paused`, toggling it here will trigger the audio element. + play() { - this.audioEl?.play(); + this.paused = false; } pause() { - this.audioEl?.pause(); + this.paused = true; } toggle() { - if (this.paused) this.play(); - else this.pause(); + this.paused = !this.paused; } seek(time: number) { - if (this.audioEl) { - this.audioEl.currentTime = Math.max(0, Math.min(time, this.duration)); - } + // Seeking is done by updating currentTime, which is bound to the audio element. + this.currentTime = Math.max(0, Math.min(time, this.duration)); } }