64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
export function useMediaSession() {
|
|
const store = usePlayerStore()
|
|
const { togglePlayPause, playNext, playPrev, seek } = useAudioPlayer()
|
|
|
|
function updateMediaSession() {
|
|
if (!('mediaSession' in navigator)) return
|
|
if (!store.currentSong) return
|
|
|
|
navigator.mediaSession.metadata = new MediaMetadata({
|
|
title: store.currentSong.title,
|
|
artist: store.currentSong.artist,
|
|
album: 'Une économie du don — enfin concevable',
|
|
artwork: store.currentSong.coverImage
|
|
? [{ src: store.currentSong.coverImage, sizes: '512x512', type: 'image/jpeg' }]
|
|
: [],
|
|
})
|
|
|
|
navigator.mediaSession.setActionHandler('play', () => togglePlayPause())
|
|
navigator.mediaSession.setActionHandler('pause', () => togglePlayPause())
|
|
navigator.mediaSession.setActionHandler('previoustrack', () => playPrev())
|
|
navigator.mediaSession.setActionHandler('nexttrack', () => playNext())
|
|
navigator.mediaSession.setActionHandler('seekto', (details) => {
|
|
if (details.seekTime != null) seek(details.seekTime)
|
|
})
|
|
}
|
|
|
|
function updatePositionState() {
|
|
if (!('mediaSession' in navigator)) return
|
|
if (!store.currentSong || store.duration === 0) return
|
|
|
|
try {
|
|
navigator.mediaSession.setPositionState({
|
|
duration: store.duration,
|
|
playbackRate: 1,
|
|
position: Math.min(store.currentTime, store.duration),
|
|
})
|
|
}
|
|
catch {
|
|
// Ignore errors from invalid position state
|
|
}
|
|
}
|
|
|
|
// Watch for song changes
|
|
watch(() => store.currentSong, () => {
|
|
updateMediaSession()
|
|
})
|
|
|
|
// Update position periodically
|
|
watch(() => store.currentTime, () => {
|
|
updatePositionState()
|
|
})
|
|
|
|
// Update playback state
|
|
watch(() => store.isPlaying, (playing) => {
|
|
if ('mediaSession' in navigator) {
|
|
navigator.mediaSession.playbackState = playing ? 'playing' : 'paused'
|
|
}
|
|
})
|
|
|
|
return {
|
|
updateMediaSession,
|
|
}
|
|
}
|