add working player
All checks were successful
Deploy App / build (push) Successful in 1m20s
Deploy App / deploy (push) Successful in 16s

This commit is contained in:
valere
2025-10-04 00:49:12 +02:00
parent fef1a8c234
commit 96ffb4b10a
9 changed files with 242 additions and 153 deletions

View File

@@ -1,62 +1,113 @@
// ~/store/player.ts
import { defineStore } from 'pinia'
import type { Track } from '~/types/types'
import type { Track } from '~/../types/types'
import { useDataStore } from '~/store/data'
export const usePlayerStore = defineStore('player', {
state: () => ({
currentTrack: null as Track | null,
isPlaying: false,
position: 0,
audio: null as HTMLAudioElement | null,
}),
actions: {
setTrack(track: Track) {
async playTrack(track: Track) {
this.currentTrack = track
if (!this.audio) this.audio = new Audio(this.getCompilationUrlFromTrack(track))
else this.audio.src = this.getCompilationUrlFromTrack(track)
// Commencer à start secondes
this.audio.currentTime = track.start || 0
},
// toggle si on reclique sur la même
if (this.isPlayingTrack(track)) {
this.togglePlay()
return
}
if (!this.audio) {
this.audio = new Audio()
}
playTrack(track?: Track) {
// load compile if not allready loaded
// play if track is not already played
// else pause
// définir la source (fichier de la compilation entière)
this.audio.src = this.getCompilationUrlFromTrack(track)
this.audio.load()
// attendre que le player soit prêt avant de lire
await new Promise<void>((resolve, reject) => {
const onCanPlay = () => {
this.audio!.removeEventListener("canplay", onCanPlay)
resolve()
}
const onError = (e: Event) => {
this.audio!.removeEventListener("error", onError)
reject(e)
}
this.audio!.addEventListener("canplay", onCanPlay, { once: true })
this.audio!.addEventListener("error", onError, { once: true })
})
if (track) this.setTrack(track)
if (!this.currentTrack || !this.audio) return
// positionner le début
this.audio.currentTime = track.start ?? 0
this.audio.play()
this.isPlaying = true
},
pauseTrack() {
if (this.audio) this.audio.pause()
this.isPlaying = false
},
togglePlay(track?: Track) {
if (track && (!this.currentTrack || track.id !== this.currentTrack.id)) {
this.playTrack(track)
} else {
this.isPlaying ? this.pauseTrack() : this.playTrack()
// lancer la lecture
try {
await this.audio.play()
} catch (err) {
console.error("Impossible de lire la piste :", err)
}
},
setPosition(time: number) {
if (this.audio) this.audio.currentTime = time
this.position = time
togglePlay() {
if (!this.audio) return
if (this.audio.paused) {
this.audio.play().catch(err => console.error(err))
} else {
this.audio.pause()
}
},
},
getters: {
isCurrentCompilation: (state) => {
return (compilationId: string) =>
compilationId === state.currentTrack?.compilationId
},
isPlayingTrack: (state) => {
return (track: Track) => {
if (!state.audio || !state.currentTrack) return false
const currentTime = state.audio.currentTime
if (!currentTime || isNaN(currentTime)) return false
const from = track.start ?? 0
const to = state.getTrackStop(track)
if (!to || isNaN(to)) return false
return currentTime >= from && currentTime < to
}
},
getCurrentTrack: (state) => state.currentTrack,
getPlaying: (state) => state.isPlaying,
getCompilationUrlFromTrack: (state) => {
return (track: Track) => `https://files.erudi.fr/evilspins/${track.compilationId}.mp3`
getCompilationUrlFromTrack: () => {
return (track: Track) =>
`https://files.erudi.fr/evilspins/${track.compilationId}.mp3`
},
getCurrentCompilation: (state) => {
return state.currentTrack
? state.getCompilationUrlFromTrack(state.currentTrack)
: null
},
getTrackStop: (state) => {
return (track: Track) => {
if (!state.audio) return 0
if (track.order === 0) {
return Math.round(state.audio.duration)
} else {
const dataStore = useDataStore()
const nextTrack = dataStore.getNextTrack(track)
return nextTrack ? nextTrack.start : Math.round(state.audio.duration)
}
}
}
},
})