import type { Song } from '~/types/song' let audio: HTMLAudioElement | null = null let animationFrameId: number | null = null export function useAudioPlayer() { const store = usePlayerStore() function getAudio(): HTMLAudioElement { if (!audio) { audio = new Audio() audio.preload = 'metadata' audio.volume = store.volume audio.addEventListener('loadedmetadata', () => { store.setDuration(audio!.duration) }) audio.addEventListener('ended', () => { const next = store.nextSong() if (next) { loadAndPlay(next) } }) audio.addEventListener('error', (e) => { console.error('Audio error:', e) store.pause() }) } return audio } function startTimeUpdate() { if (animationFrameId) return const update = () => { if (audio && !audio.paused) { store.setCurrentTime(audio.currentTime) } animationFrameId = requestAnimationFrame(update) } animationFrameId = requestAnimationFrame(update) } function stopTimeUpdate() { if (animationFrameId) { cancelAnimationFrame(animationFrameId) animationFrameId = null } } async function loadAndPlay(song: Song) { const el = getAudio() store.setSong(song) // Try OGG first, fall back to MP3 const oggPath = song.file.replace(/\.mp3$/, '.ogg') const canOgg = el.canPlayType('audio/ogg; codecs=vorbis') el.src = canOgg ? oggPath : song.file el.volume = store.volume try { await el.play() store.play() startTimeUpdate() } catch { // If OGG failed, try MP3 if (el.src !== song.file) { el.src = song.file try { await el.play() store.play() startTimeUpdate() } catch (err) { console.error('Playback failed:', err) } } } } function pause() { getAudio().pause() store.pause() stopTimeUpdate() } function resume() { const el = getAudio() if (el.src) { el.play() store.play() startTimeUpdate() } } function togglePlayPause() { if (store.isPlaying) { pause() } else { resume() } } function seek(time: number) { const el = getAudio() el.currentTime = time store.setCurrentTime(time) } function setVolume(vol: number) { store.setVolume(vol) getAudio().volume = store.volume } function playNext() { const song = store.nextSong() if (song) loadAndPlay(song) } function playPrev() { const song = store.prevSong() if (song) { if (song === store.currentSong && store.currentTime <= 3) { // prevSong already reset time seek(0) } else { loadAndPlay(song) } } } // Watch volume changes from store watch(() => store.volume, (vol) => { if (audio) audio.volume = vol }) return { loadAndPlay, pause, resume, togglePlayPause, seek, setVolume, playNext, playPrev, getAudio, } }