Files
amqtrain/src/lib/components/player/PlayerRoot.svelte

112 lines
2.5 KiB
Svelte

<script lang="ts">
import { onMount, setContext } from "svelte";
import { player } from "$lib/player/store.svelte";
import { AudioContext, setAudioContext } from "./ctx.svelte";
import PlayerDesktop from "./PlayerDesktop.svelte";
import PlayerMobile from "./PlayerMobile.svelte";
// Initialize context
const audioCtx = new AudioContext();
setContext("amqtrain:player:audio-ctx", audioCtx);
let audioEl: HTMLAudioElement;
import { loadState, saveState } from "$lib/player/persist";
// ... existing imports ...
onMount(() => {
console.log("PlayerRoot mounted");
audioCtx.setElement(audioEl);
// Load state
const saved = loadState();
if (saved) {
player.init(saved);
}
// Setup MediaSession
// ...
});
// ... existing effect for persistence ...
// Update MediaSession metadata
// ...
// ... 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;
const currentSrc = audioEl.currentSrc;
// Create absolute URL for comparison if needed, or rely on currentSrc
// 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);
});
}
} else {
audioEl.removeAttribute("src");
}
// Update MediaSession playback state
if ("mediaSession" in navigator) {
navigator.mediaSession.playbackState = audioEl.paused
? "paused"
: "playing";
}
}
});
// ... existing callbacks ...
// Bindings and Event Listeners
function onEnded() {
player.next();
}
// Sync MediaSession playback state with bound paused state
$effect(() => {
if ("mediaSession" in navigator) {
navigator.mediaSession.playbackState = audioCtx.paused
? "paused"
: "playing";
}
});
</script>
<audio
bind:this={audioEl}
bind:currentTime={audioCtx.currentTime}
bind:duration={audioCtx.duration}
bind:paused={audioCtx.paused}
onended={onEnded}
class="hidden"
></audio>
<div class="contents">
<div class="lg:hidden">
<PlayerMobile />
</div>
<div class="hidden lg:block h-full">
<PlayerDesktop />
</div>
</div>