This commit is contained in:
wvffle 2022-07-21 14:55:48 +00:00 committed by Georg Krause
parent debe024f88
commit 34610670c6
6 changed files with 47 additions and 41 deletions

View File

@ -220,13 +220,11 @@ const touchProgress = (event: MouseEvent) => {
>
<div
class="buffer bar"
:data-percent="bufferProgress"
:style="{ 'width': bufferProgress + '%' }"
:style="{ 'transform': `scaleX(${bufferProgress / 100})` }"
/>
<div
class="position bar"
:data-percent="progress"
:style="{ 'width': progress + '%' }"
:style="{ 'transform': `scaleX(${progress / 100})` }"
/>
</div>
</div>

View File

@ -117,13 +117,11 @@ const switchTab = () => {
>
<div
class="buffer bar"
:data-percent="bufferProgress"
:style="{ 'width': bufferProgress + '%' }"
:style="{ 'transform': `scaleX(${bufferProgress / 100})` }"
/>
<div
class="position bar"
:data-percent="progress"
:style="{ 'width': progress + '%' }"
:style="{ 'transform': `scaleX(${progress / 100})` }"
/>
</div>
<div class="controls-row">

View File

@ -2,7 +2,7 @@ import type { Track } from '~/types'
import { computed, watchEffect, ref, watch } from 'vue'
import { Howler } from 'howler'
import { useIntervalFn, useTimeoutFn } from '@vueuse/core'
import { useRafFn, useTimeoutFn } from '@vueuse/core'
import useQueue from '~/composables/audio/useQueue'
import useSound from '~/composables/audio/useSound'
import toLinearVolumeScale from '~/composables/audio/toLinearVolumeScale'
@ -119,36 +119,36 @@ const progress = computed({
get: () => store.getters['player/progress'],
set: (time) => {
if (currentSound.value?.state() === 'loaded') {
store.state.player.currentTime = time
const duration = currentSound.value.duration()
store.dispatch('player/updateProgress', time)
currentSound.value._triggerSoundProgress()
const toPreload = store.state.queue.tracks[currentIndex.value + 1]
if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) {
loadSound(toPreload)
nextTrackPreloaded.value = true
}
if (time > duration / 2) {
if (!isListeningSubmitted.value) {
store.dispatch('player/trackListened', currentTrack.value)
isListeningSubmitted.value = true
}
}
currentSound.value.triggerSoundProgress(time, duration)
}
}
})
const bufferProgress = computed(() => store.state.player.bufferProgress)
onSoundProgress((node: HTMLAudioElement) => {
onSoundProgress(({ node, time, duration }) => {
const toPreload = store.state.queue.tracks[currentIndex.value + 1]
if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) {
loadSound(toPreload)
nextTrackPreloaded.value = true
}
if (time > duration / 2) {
if (!isListeningSubmitted.value) {
store.dispatch('player/trackListened', currentTrack.value)
isListeningSubmitted.value = true
}
}
// from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
const { buffered, currentTime: time } = node
const { buffered, currentTime } = node
let range = 0
try {
while (buffered.start(range) >= time || time >= buffered.end(range)) {
while (buffered.start(range) >= currentTime || currentTime >= buffered.end(range)) {
range += 1
}
} catch (IndexSizeError) {
@ -181,11 +181,11 @@ onSoundProgress((node: HTMLAudioElement) => {
})
const observeProgress = ref(false)
useIntervalFn(() => {
useRafFn(() => {
if (observeProgress.value && currentSound.value?.state() === 'loaded') {
progress.value = currentSound.value.seek()
}
}, 1000)
})
watch(playing, async (isPlaying) => {
if (currentSound.value) {

View File

@ -6,7 +6,7 @@ import useTrackSources from '~/composables/audio/useTrackSources'
import useSoundCache from '~/composables/audio/useSoundCache'
import usePlayer from '~/composables/audio/usePlayer'
import store from '~/store'
import { createEventHook } from '@vueuse/core'
import { createEventHook, useThrottleFn } from '@vueuse/core'
interface Sound {
id?: number
@ -18,7 +18,7 @@ interface Sound {
seek: (time?: number) => number
duration: () => number
getSource: () => boolean
_triggerSoundProgress: () => void
triggerSoundProgress: (time: number, duration: number) => void
}
const soundCache = useSoundCache()
@ -28,7 +28,7 @@ const looping = computed(() => store.state.player.looping)
const currentSound = ref()
const soundId = ref()
const soundProgress = createEventHook<HTMLAudioElement>()
const soundProgress = createEventHook<{ node: HTMLAudioElement, time: number, duration: number }>()
const createSound = (howl: Howl): Sound => ({
howl,
@ -46,7 +46,7 @@ const createSound = (howl: Howl): Sound => ({
seek: (time?: number) => howl.seek(time),
duration: () => howl.duration(),
getSource: () => (howl as any)._sounds[0],
_triggerSoundProgress: () => soundProgress.trigger((howl as any)._sounds[0]._node)
triggerSoundProgress: useThrottleFn((time: number, duration: number) => soundProgress.trigger({ node: (howl as any)._sounds[0]._node, time, duration }), 1000)
})
const loadSound = (track: Track): Sound => {

View File

@ -37,7 +37,11 @@
}
.ui.progress .bar {
transition: none;
transition: transform .2s linear;
width: 100%;
transform: scaleX(0);
transform-origin: top left;
will-change: transform;
}
.ui.progress .buffer.bar {
@ -72,10 +76,9 @@
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.ui.progress:not([data-percent]):not(.indeterminate)
.ui.progress:not(.indeterminate)
.bar.position:not(.buffer) {
background: var(--vibrant-color);
min-width: 0;
}
.track-controls {

View File

@ -163,15 +163,25 @@
.progress-area {
overflow: hidden;
}
.progress-area .progress {
border-radius: 0.28571429rem;
}
.progress-wrapper, .warning.message {
max-width: 25em;
margin: 0 auto;
}
.ui.progress .bar {
transition: transform .2s linear;
width: 100%;
transform: scaleX(0);
transform-origin: top left;
will-change: transform;
}
.ui.progress .buffer.bar {
position: absolute;
background-color: rgba(255, 255, 255, 0.15);
}
.ui.progress:not([data-percent]):not(.indeterminate)
.ui.progress:not(.indeterminate)
.bar.position:not(.buffer) {
background: var(--vibrant-color);
}
@ -201,9 +211,6 @@
}
.progress {
cursor: pointer;
.bar {
min-width: 0 !important;
}
}
.player-controls {