Fix #1381
This commit is contained in:
parent
debe024f88
commit
34610670c6
|
@ -220,13 +220,11 @@ const touchProgress = (event: MouseEvent) => {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="buffer bar"
|
class="buffer bar"
|
||||||
:data-percent="bufferProgress"
|
:style="{ 'transform': `scaleX(${bufferProgress / 100})` }"
|
||||||
:style="{ 'width': bufferProgress + '%' }"
|
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="position bar"
|
class="position bar"
|
||||||
:data-percent="progress"
|
:style="{ 'transform': `scaleX(${progress / 100})` }"
|
||||||
:style="{ 'width': progress + '%' }"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -117,13 +117,11 @@ const switchTab = () => {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="buffer bar"
|
class="buffer bar"
|
||||||
:data-percent="bufferProgress"
|
:style="{ 'transform': `scaleX(${bufferProgress / 100})` }"
|
||||||
:style="{ 'width': bufferProgress + '%' }"
|
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="position bar"
|
class="position bar"
|
||||||
:data-percent="progress"
|
:style="{ 'transform': `scaleX(${progress / 100})` }"
|
||||||
:style="{ 'width': progress + '%' }"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls-row">
|
<div class="controls-row">
|
||||||
|
|
|
@ -2,7 +2,7 @@ import type { Track } from '~/types'
|
||||||
|
|
||||||
import { computed, watchEffect, ref, watch } from 'vue'
|
import { computed, watchEffect, ref, watch } from 'vue'
|
||||||
import { Howler } from 'howler'
|
import { Howler } from 'howler'
|
||||||
import { useIntervalFn, useTimeoutFn } from '@vueuse/core'
|
import { useRafFn, useTimeoutFn } from '@vueuse/core'
|
||||||
import useQueue from '~/composables/audio/useQueue'
|
import useQueue from '~/composables/audio/useQueue'
|
||||||
import useSound from '~/composables/audio/useSound'
|
import useSound from '~/composables/audio/useSound'
|
||||||
import toLinearVolumeScale from '~/composables/audio/toLinearVolumeScale'
|
import toLinearVolumeScale from '~/composables/audio/toLinearVolumeScale'
|
||||||
|
@ -119,11 +119,16 @@ const progress = computed({
|
||||||
get: () => store.getters['player/progress'],
|
get: () => store.getters['player/progress'],
|
||||||
set: (time) => {
|
set: (time) => {
|
||||||
if (currentSound.value?.state() === 'loaded') {
|
if (currentSound.value?.state() === 'loaded') {
|
||||||
|
store.state.player.currentTime = time
|
||||||
|
|
||||||
const duration = currentSound.value.duration()
|
const duration = currentSound.value.duration()
|
||||||
|
currentSound.value.triggerSoundProgress(time, duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
store.dispatch('player/updateProgress', time)
|
const bufferProgress = computed(() => store.state.player.bufferProgress)
|
||||||
currentSound.value._triggerSoundProgress()
|
onSoundProgress(({ node, time, duration }) => {
|
||||||
|
|
||||||
const toPreload = store.state.queue.tracks[currentIndex.value + 1]
|
const toPreload = store.state.queue.tracks[currentIndex.value + 1]
|
||||||
if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) {
|
if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) {
|
||||||
loadSound(toPreload)
|
loadSound(toPreload)
|
||||||
|
@ -136,19 +141,14 @@ const progress = computed({
|
||||||
isListeningSubmitted.value = true
|
isListeningSubmitted.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const bufferProgress = computed(() => store.state.player.bufferProgress)
|
|
||||||
onSoundProgress((node: HTMLAudioElement) => {
|
|
||||||
// from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
|
// from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
|
||||||
|
|
||||||
const { buffered, currentTime: time } = node
|
const { buffered, currentTime } = node
|
||||||
|
|
||||||
let range = 0
|
let range = 0
|
||||||
try {
|
try {
|
||||||
while (buffered.start(range) >= time || time >= buffered.end(range)) {
|
while (buffered.start(range) >= currentTime || currentTime >= buffered.end(range)) {
|
||||||
range += 1
|
range += 1
|
||||||
}
|
}
|
||||||
} catch (IndexSizeError) {
|
} catch (IndexSizeError) {
|
||||||
|
@ -181,11 +181,11 @@ onSoundProgress((node: HTMLAudioElement) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const observeProgress = ref(false)
|
const observeProgress = ref(false)
|
||||||
useIntervalFn(() => {
|
useRafFn(() => {
|
||||||
if (observeProgress.value && currentSound.value?.state() === 'loaded') {
|
if (observeProgress.value && currentSound.value?.state() === 'loaded') {
|
||||||
progress.value = currentSound.value.seek()
|
progress.value = currentSound.value.seek()
|
||||||
}
|
}
|
||||||
}, 1000)
|
})
|
||||||
|
|
||||||
watch(playing, async (isPlaying) => {
|
watch(playing, async (isPlaying) => {
|
||||||
if (currentSound.value) {
|
if (currentSound.value) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import useTrackSources from '~/composables/audio/useTrackSources'
|
||||||
import useSoundCache from '~/composables/audio/useSoundCache'
|
import useSoundCache from '~/composables/audio/useSoundCache'
|
||||||
import usePlayer from '~/composables/audio/usePlayer'
|
import usePlayer from '~/composables/audio/usePlayer'
|
||||||
import store from '~/store'
|
import store from '~/store'
|
||||||
import { createEventHook } from '@vueuse/core'
|
import { createEventHook, useThrottleFn } from '@vueuse/core'
|
||||||
|
|
||||||
interface Sound {
|
interface Sound {
|
||||||
id?: number
|
id?: number
|
||||||
|
@ -18,7 +18,7 @@ interface Sound {
|
||||||
seek: (time?: number) => number
|
seek: (time?: number) => number
|
||||||
duration: () => number
|
duration: () => number
|
||||||
getSource: () => boolean
|
getSource: () => boolean
|
||||||
_triggerSoundProgress: () => void
|
triggerSoundProgress: (time: number, duration: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const soundCache = useSoundCache()
|
const soundCache = useSoundCache()
|
||||||
|
@ -28,7 +28,7 @@ const looping = computed(() => store.state.player.looping)
|
||||||
const currentSound = ref()
|
const currentSound = ref()
|
||||||
const soundId = ref()
|
const soundId = ref()
|
||||||
|
|
||||||
const soundProgress = createEventHook<HTMLAudioElement>()
|
const soundProgress = createEventHook<{ node: HTMLAudioElement, time: number, duration: number }>()
|
||||||
|
|
||||||
const createSound = (howl: Howl): Sound => ({
|
const createSound = (howl: Howl): Sound => ({
|
||||||
howl,
|
howl,
|
||||||
|
@ -46,7 +46,7 @@ const createSound = (howl: Howl): Sound => ({
|
||||||
seek: (time?: number) => howl.seek(time),
|
seek: (time?: number) => howl.seek(time),
|
||||||
duration: () => howl.duration(),
|
duration: () => howl.duration(),
|
||||||
getSource: () => (howl as any)._sounds[0],
|
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 => {
|
const loadSound = (track: Track): Sound => {
|
||||||
|
|
|
@ -37,7 +37,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.progress .bar {
|
.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 {
|
.ui.progress .buffer.bar {
|
||||||
|
@ -72,10 +76,9 @@
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
.ui.progress:not([data-percent]):not(.indeterminate)
|
.ui.progress:not(.indeterminate)
|
||||||
.bar.position:not(.buffer) {
|
.bar.position:not(.buffer) {
|
||||||
background: var(--vibrant-color);
|
background: var(--vibrant-color);
|
||||||
min-width: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-controls {
|
.track-controls {
|
||||||
|
|
|
@ -163,15 +163,25 @@
|
||||||
.progress-area {
|
.progress-area {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.progress-area .progress {
|
||||||
|
border-radius: 0.28571429rem;
|
||||||
|
}
|
||||||
.progress-wrapper, .warning.message {
|
.progress-wrapper, .warning.message {
|
||||||
max-width: 25em;
|
max-width: 25em;
|
||||||
margin: 0 auto;
|
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 {
|
.ui.progress .buffer.bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: rgba(255, 255, 255, 0.15);
|
background-color: rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
.ui.progress:not([data-percent]):not(.indeterminate)
|
.ui.progress:not(.indeterminate)
|
||||||
.bar.position:not(.buffer) {
|
.bar.position:not(.buffer) {
|
||||||
background: var(--vibrant-color);
|
background: var(--vibrant-color);
|
||||||
}
|
}
|
||||||
|
@ -201,9 +211,6 @@
|
||||||
}
|
}
|
||||||
.progress {
|
.progress {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
.bar {
|
|
||||||
min-width: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-controls {
|
.player-controls {
|
||||||
|
|
Loading…
Reference in New Issue