From 54a33cd14e4024580305f7f22758d5d71dadaab1 Mon Sep 17 00:00:00 2001 From: wvffle Date: Sun, 3 Jul 2022 21:36:27 +0000 Subject: [PATCH] Fix audio playback --- front/src/App.vue | 2 +- front/src/components/Queue.vue | 4 +- front/src/components/audio/Player.vue | 35 +++++--- front/src/components/audio/VolumeControl.vue | 87 ++++++++----------- .../src/composables/{ => audio}/usePlayer.ts | 9 +- front/src/composables/{ => audio}/useQueue.ts | 0 front/src/composables/audio/useSoundCache.ts | 6 +- .../src/composables/audio/useTrackSources.ts | 3 +- front/src/init/howler.ts | 12 +-- front/src/init/mediaSession.ts | 4 +- front/src/store/player.ts | 4 - 11 files changed, 82 insertions(+), 84 deletions(-) rename front/src/composables/{ => audio}/usePlayer.ts (89%) rename front/src/composables/{ => audio}/useQueue.ts (100%) diff --git a/front/src/App.vue b/front/src/App.vue index 056f69a1a..44c44ad8d 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -14,7 +14,7 @@ import { useIntervalFn, useToggle, useWindowSize } from '@vueuse/core' import { computed, nextTick, onMounted, ref, watchEffect } from 'vue' import { Track } from '~/types' import onKeyboardShortcut from '~/composables/onKeyboardShortcut' -import useQueue from '~/composables/useQueue' +import useQueue from '~/composables/audio/useQueue' import { useStore } from '~/store' const store = useStore() diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index 724487ddd..eb6d75608 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -9,8 +9,8 @@ import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue' import Draggable, { } from 'vuedraggable' import { whenever, useTimeoutFn, useWindowScroll, useWindowSize } from '@vueuse/core' import { useGettext } from "vue3-gettext" -import useQueue from '~/composables/useQueue' -import usePlayer from '~/composables/usePlayer' +import useQueue from '~/composables/audio/useQueue' +import usePlayer from '~/composables/audio/usePlayer' const queueModal = ref() diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue index 6b58d79ca..bde19b8bb 100644 --- a/front/src/components/audio/Player.vue +++ b/front/src/components/audio/Player.vue @@ -11,8 +11,8 @@ import onKeyboardShortcut from '~/composables/onKeyboardShortcut' import { ref, computed, watch, onMounted, onBeforeUnmount, watchEffect } from 'vue' import { useTimeoutFn, useIntervalFn } from '@vueuse/core' import { useGettext } from 'vue3-gettext' -import useQueue from '~/composables/useQueue' -import usePlayer from '~/composables/usePlayer' +import useQueue from '~/composables/audio/useQueue' +import usePlayer from '~/composables/audio/usePlayer' import useTrackSources, { TrackSource } from '~/composables/audio/useTrackSources' import useSoundCache from '~/composables/audio/useSoundCache' @@ -146,11 +146,7 @@ watch(currentTrack, (track, oldValue) => { }) const observeProgress = ref(false) -useIntervalFn(() => { - if (observeProgress.value) { - updateProgress() - } -}, 1000) +useIntervalFn(() => observeProgress.value && updateProgress(), 1000) watch(playing, async (isPlaying) => { if (currentSound.value) { @@ -207,6 +203,7 @@ onMounted(() => { // TODO (wvffle): Check if it is needed nextTrackPreloaded.value = false + // Cache sound if we have currentTrack available if (currentTrack.value) { getSound(currentTrack.value) } @@ -249,7 +246,7 @@ const getSound = (trackData: Track) => { }, onload () { - const node = (sound as any)._sounds[0].node as HTMLAudioElement + const node = (sound as any)._sounds[0]._node as HTMLAudioElement node.addEventListener('progress', () => { if (sound !== currentSound.value) { @@ -261,8 +258,8 @@ const getSound = (trackData: Track) => { }, onplay () { - if (sound !== currentSound.value) { - return sound.stop() + if (this !== currentSound.value) { + return (this as any).stop() } const time = currentSound.value.seek() @@ -277,11 +274,16 @@ const getSound = (trackData: Track) => { store.commit('player/duration', sound.duration()) }, + onplayerror (soundId, error) { + console.log('play error', soundId, error) + }, + onloaderror (soundId, error) { + console.log('load error', soundId, error) soundCache.delete(trackData.id) sound.unload() - if (sound !== currentSound.value) { + if (this !== currentSound.value) { return } @@ -298,6 +300,7 @@ const getSound = (trackData: Track) => { return sound } + const getTrack = async (trackData: Track) => { // use previously fetched trackData if (trackData.uploads.length) { @@ -372,7 +375,8 @@ const loadSound = async (trackData: Track, oldValue?: Track) => { handleError() } - currentSound.value = getSound(trackData as Track) + currentSound.value = getSound(trackData) + // TODO (wvffle): #1777 soundId.value = currentSound.value.play() store.commit('player/isLoadingAudio', true) @@ -576,8 +580,11 @@ const switchTab = () => { {{ currentTimeFormatted }} - | {{ durationFormatted }} + > + {{ currentTimeFormatted }} + + | + {{ durationFormatted }} diff --git a/front/src/components/audio/VolumeControl.vue b/front/src/components/audio/VolumeControl.vue index d8f45dccc..e1354a46d 100644 --- a/front/src/components/audio/VolumeControl.vue +++ b/front/src/components/audio/VolumeControl.vue @@ -1,3 +1,41 @@ + + - diff --git a/front/src/composables/usePlayer.ts b/front/src/composables/audio/usePlayer.ts similarity index 89% rename from front/src/composables/usePlayer.ts rename to front/src/composables/audio/usePlayer.ts index 1968f5ea5..f5bd7a55c 100644 --- a/front/src/composables/usePlayer.ts +++ b/front/src/composables/audio/usePlayer.ts @@ -1,6 +1,6 @@ import { computed, watchEffect } from "vue" import { Howler } from 'howler' -import useQueue from '~/composables/useQueue' +import useQueue from '~/composables/audio/useQueue' import toLinearVolumeScale from '~/composables/audio/toLinearVolumeScale' import store from "~/store" @@ -19,6 +19,10 @@ export default () => { watchEffect(() => Howler.volume(toLinearVolumeScale(volume.value))) + const mute = () => store.dispatch('player/mute') + const unmute = () => store.dispatch('player/unmute') + const toggleMute = () => store.dispatch('player/toggleMute') + // Time and duration const duration = computed(() => store.state.player.duration) const currentTime = computed(() => store.state.player.currentTime) @@ -65,6 +69,9 @@ export default () => { focused, volume, + mute, + unmute, + toggleMute, duration, currentTime, diff --git a/front/src/composables/useQueue.ts b/front/src/composables/audio/useQueue.ts similarity index 100% rename from front/src/composables/useQueue.ts rename to front/src/composables/audio/useQueue.ts diff --git a/front/src/composables/audio/useSoundCache.ts b/front/src/composables/audio/useSoundCache.ts index f414121ed..6134e24c0 100644 --- a/front/src/composables/audio/useSoundCache.ts +++ b/front/src/composables/audio/useSoundCache.ts @@ -19,11 +19,11 @@ export default (maxPreloaded: MaybeRef) => { if (toRemove > 0 && !cleaningCache.value) { cleaningCache.value = true - const excess = sortBy(soundCache.values(), [(cached: CachedSound) => cached.date]) - // TODO (wvffle): Check if works - .slice(0, toRemove) as unknown as CachedSound[] + const excess = sortBy([...soundCache.values()], [(cached: CachedSound) => cached.date]) + .slice(0, toRemove) for (const cached of excess) { + console.log('Removing cached element:', cached) soundCache.delete(cached.id) cached.sound.unload() } diff --git a/front/src/composables/audio/useTrackSources.ts b/front/src/composables/audio/useTrackSources.ts index f360bfbda..c6c1e2e2b 100644 --- a/front/src/composables/audio/useTrackSources.ts +++ b/front/src/composables/audio/useTrackSources.ts @@ -1,5 +1,5 @@ import { Track } from "~/types" -import { useStore } from '~/store' +import store from '~/store' import updateQueryString from '~/composables/updateQueryString' export interface TrackSource { @@ -8,7 +8,6 @@ export interface TrackSource { } export default (trackData: Track): TrackSource[] => { - const store = useStore() const audio = document.createElement('audio') const allowed = ['probably', 'maybe'] diff --git a/front/src/init/howler.ts b/front/src/init/howler.ts index 082e62ef0..d0994f064 100644 --- a/front/src/init/howler.ts +++ b/front/src/init/howler.ts @@ -7,11 +7,11 @@ export const install: InitModule = ({ app }) => { // this is needed to unlock audio playing under some browsers, // cf https://github.com/goldfire/howler.js#mobilechrome-playback // but we never actually load those audio files - const dummyAudio = new Howl({ - preload: false, - autoplay: false, - src: ['noop.webm', 'noop.mp3'] - }) + // const dummyAudio = new Howl({ + // preload: false, + // autoplay: false, + // src: ['noop.webm', 'noop.mp3'] + // }) - return dummyAudio + // return dummyAudio } diff --git a/front/src/init/mediaSession.ts b/front/src/init/mediaSession.ts index c2fc191b3..a3ea62148 100644 --- a/front/src/init/mediaSession.ts +++ b/front/src/init/mediaSession.ts @@ -1,7 +1,7 @@ import { InitModule } from '~/types' import { whenever } from '@vueuse/core' -import useQueue from '~/composables/useQueue' -import usePlayer from '~/composables/usePlayer' +import useQueue from '~/composables/audio/useQueue' +import usePlayer from '~/composables/audio/usePlayer' export const install: InitModule = ({ app }) => { const { currentTrack, next, previous } = useQueue() diff --git a/front/src/store/player.ts b/front/src/store/player.ts index 6fc34fa07..ea88ba018 100644 --- a/front/src/store/player.ts +++ b/front/src/store/player.ts @@ -95,10 +95,6 @@ const store: Module = { }, getters: { durationFormatted: state => { - if (state.duration % 1 !== 0) { - return time.parse(0) - } - return time.parse(Math.round(state.duration)) }, currentTimeFormatted: state => {