Updated plugin to have writable computed for secondsPlayed and volume

This commit is contained in:
lucast committed 2026-02-19 15:26:45 +01:00
1 parent 3a9874b2fb
commit 4ca422e25a
1 file changed
+51 -11
+51 -11
View File
@@ -9,6 +9,30 @@ export default defineNuxtPlugin((nuxtApp) => {
const repeat = ref(false) const repeat = ref(false)
const isPlaying = ref(false) const isPlaying = ref(false)
const tick = ref(0)
const secondsPlayed = computed<number>({
get() {
tick.value
return (sound.value?.seek() as number) || 0
},
set(value: number) {
sound.value?.seek(value)
},
})
const volume = computed<number>({
get() {
tick.value
return sound.value?.volume() ?? 1
},
set(value) {
sound.value?.volume(value)
},
})
const duration = ref(0)
const aniFrame = ref<number | null>(null)
// Helpers // Helpers
const updateMediaSession = async () => { const updateMediaSession = async () => {
if (!import.meta.client) return if (!import.meta.client) return
@@ -32,11 +56,25 @@ export default defineNuxtPlugin((nuxtApp) => {
}) })
navigator.mediaSession.setPositionState({ navigator.mediaSession.setPositionState({
duration: await getDuration(), duration: duration.value,
position: getSecondsPlayed(), position: secondsPlayed.value,
}) })
} }
const startTracking = () => {
const update = () => {
tick.value++
aniFrame.value = requestAnimationFrame(update)
}
update()
}
const stopTracking = () => {
if (aniFrame.value) cancelAnimationFrame(aniFrame.value)
aniFrame.value = null
}
const createHowl = async (song: Track) => { const createHowl = async (song: Track) => {
if (!import.meta.client) return if (!import.meta.client) return
if (!song) throw new Error("Song not provided") if (!song) throw new Error("Song not provided")
@@ -46,21 +84,29 @@ export default defineNuxtPlugin((nuxtApp) => {
html5: false, html5: false,
autoplay: false, autoplay: false,
volume: 0.5, volume: 0.5,
onload: () => {
duration.value = sound.value?.duration() || 0
volume.value = sound.value?.volume() || 1
},
onend: () => { onend: () => {
next() next()
stopTracking()
}, },
onstop: () => { onstop: () => {
isPlaying.value = false isPlaying.value = false
stopTracking()
if (navigator.mediaSession) if (navigator.mediaSession)
navigator.mediaSession.playbackState = "none" navigator.mediaSession.playbackState = "none"
}, },
onplay: () => { onplay: () => {
isPlaying.value = true isPlaying.value = true
startTracking()
if (navigator.mediaSession) if (navigator.mediaSession)
navigator.mediaSession.playbackState = "playing" navigator.mediaSession.playbackState = "playing"
}, },
onpause: () => { onpause: () => {
isPlaying.value = false isPlaying.value = false
stopTracking()
if (navigator.mediaSession) if (navigator.mediaSession)
navigator.mediaSession.playbackState = "paused" navigator.mediaSession.playbackState = "paused"
}, },
@@ -161,11 +207,6 @@ export default defineNuxtPlugin((nuxtApp) => {
} }
}) })
const getSecondsPlayed = () => sound.value?.seek() || 0
const setSecondsPlayed = (s: number) => sound.value?.seek(s)
const setVolume = (v: number) => sound.value?.volume(v)
const getVolume = () => sound.value?.volume() || 0
return { return {
provide: { provide: {
player: { player: {
@@ -180,10 +221,9 @@ export default defineNuxtPlugin((nuxtApp) => {
clear, clear,
shuffle, shuffle,
getDuration, getDuration,
getSecondsPlayed, secondsPlayed,
setSecondsPlayed, duration,
setVolume, volume,
getVolume,
queue, queue,
}, },
}, },