优化讲解详情播放器体验
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-25 00:02:33 +08:00
parent 9037f4d3e5
commit cb6da6590d
3 changed files with 248 additions and 73 deletions

View File

@@ -41,6 +41,10 @@ const pendingLanguage = ref<AudioLanguage | ''>('')
const activeHostId = ref('')
const lastClosedSource = ref<GlobalAudioSource | null>(null)
const closeVersion = ref(0)
const playbackRate = ref(1)
const muted = ref(false)
const PLAYBACK_RATES = [1, 1.25, 1.5, 2] as const
let audioElement: HTMLAudioElement | null = null
let retryOnError: GlobalAudioRetryHandler | null = null
@@ -74,11 +78,17 @@ const syncAudioDuration = () => {
: currentAudio.value?.duration || 0
}
const applyAudioPreferences = (audio: HTMLAudioElement) => {
audio.playbackRate = playbackRate.value
audio.muted = muted.value
}
const ensureAudioElement = () => {
if (audioElement || typeof window === 'undefined' || !window.Audio) return audioElement
const audio = new window.Audio()
audio.preload = 'metadata'
applyAudioPreferences(audio)
audio.addEventListener('loadedmetadata', syncAudioDuration)
audio.addEventListener('play', () => {
playing.value = true
@@ -124,6 +134,11 @@ const resetState = () => {
duration.value = 0
displayMode.value = 'mini'
pendingLanguage.value = ''
playbackRate.value = 1
muted.value = false
if (audioElement) {
applyAudioPreferences(audioElement)
}
retryOnError = null
retrying = false
retryUsed = false
@@ -227,6 +242,7 @@ const play = async (audio: AudioItem, options: GlobalAudioPlayOptions = {}) => {
element.src = audio.audioUrl
element.load()
}
applyAudioPreferences(element)
try {
await element.play()
@@ -448,6 +464,22 @@ const seekToPercent = (percent: number) => {
currentTime.value = targetTime
}
const cyclePlaybackRate = () => {
const currentIndex = PLAYBACK_RATES.indexOf(playbackRate.value as typeof PLAYBACK_RATES[number])
const nextIndex = currentIndex >= 0 ? (currentIndex + 1) % PLAYBACK_RATES.length : 0
playbackRate.value = PLAYBACK_RATES[nextIndex]
if (audioElement) {
audioElement.playbackRate = playbackRate.value
}
}
const toggleMuted = () => {
muted.value = !muted.value
if (audioElement) {
audioElement.muted = muted.value
}
}
const registerHost = () => {
hostSequence += 1
const hostId = `global-audio-host-${hostSequence}`
@@ -490,6 +522,8 @@ export const useGlobalAudioPlayer = () => ({
activeHostId,
lastClosedSource,
closeVersion,
playbackRate,
muted,
hasAudio: computed(() => Boolean(currentAudio.value)),
play,
pause,
@@ -502,6 +536,8 @@ export const useGlobalAudioPlayer = () => ({
handleEnded,
handleError,
seekToPercent,
cyclePlaybackRate,
toggleMuted,
registerHost,
activateHost,
unregisterHost,