fix(playback): remove disposed sound instance from cache

Part-of: <https://dev.funkwhale.audio/funkwhale/funkwhale/-/merge_requests/2469>
This commit is contained in:
Kasper Seweryn 2023-06-12 15:55:57 +02:00 committed by Marge
parent 2aca2f18d5
commit 05f79c9489
3 changed files with 13 additions and 1 deletions

View File

@ -17,6 +17,7 @@ export interface Sound {
readonly audioNode: IAudioNode<IAudioContext> readonly audioNode: IAudioNode<IAudioContext>
readonly isErrored: Ref<boolean> readonly isErrored: Ref<boolean>
readonly isLoaded: Ref<boolean> readonly isLoaded: Ref<boolean>
readonly isDisposed: Ref<boolean>
readonly currentTime: number readonly currentTime: number
readonly playable: boolean readonly playable: boolean
readonly duration: number readonly duration: number
@ -51,6 +52,7 @@ export class HTMLSound implements Sound {
readonly isErrored = ref(false) readonly isErrored = ref(false)
readonly isLoaded = ref(false) readonly isLoaded = ref(false)
readonly isDisposed = ref(false)
audioNode = createAudioSource(this.#audio) audioNode = createAudioSource(this.#audio)
onSoundLoop: EventHookOn<HTMLSound> onSoundLoop: EventHookOn<HTMLSound>
@ -112,12 +114,15 @@ export class HTMLSound implements Sound {
} }
async preload () { async preload () {
this.isDisposed.value = false
this.isErrored.value = false this.isErrored.value = false
console.log('CALLING PRELOAD ON', this) console.log('CALLING PRELOAD ON', this)
this.#audio.load() this.#audio.load()
} }
async dispose () { async dispose () {
if (this.isDisposed.value) return
// Remove all event listeners // Remove all event listeners
this.#scope.stop() this.#scope.stop()
@ -128,6 +133,8 @@ export class HTMLSound implements Sound {
// Cancel any request downloading the source // Cancel any request downloading the source
this.#audio.src = '' this.#audio.src = ''
this.#audio.load() this.#audio.load()
this.isDisposed.value = true
} }
async play () { async play () {

View File

@ -324,7 +324,7 @@ export const useQueue = createGlobalState(() => {
const clear = async () => { const clear = async () => {
await currentSound.value?.pause() await currentSound.value?.pause()
await currentSound.value?.seekTo(0) await currentSound.value?.seekTo(0)
currentSound.value?.dispose() await currentSound.value?.dispose()
clearRadio.value = true clearRadio.value = true

View File

@ -101,6 +101,11 @@ export const useTracks = createGlobalState(() => {
setTimeout(() => playNext(), 0) setTimeout(() => playNext(), 0)
}) })
// NOTE: When the sound is disposed, we need to delete it from the cache (#2157)
whenever(sound.isDisposed, () => {
soundCache.delete(track.id)
})
// NOTE: Bump current track to ensure that it lives despite enqueueing 3 tracks as next track: // NOTE: Bump current track to ensure that it lives despite enqueueing 3 tracks as next track:
// //
// In every queue we have 3 tracks that are cached, in the order, they're being played: // In every queue we have 3 tracks that are cached, in the order, they're being played: