初始化
This commit is contained in:
95
vite-tailwindcss/src/composables/useAudio.js
Normal file
95
vite-tailwindcss/src/composables/useAudio.js
Normal file
@@ -0,0 +1,95 @@
|
||||
import { ref, onUnmounted } from 'vue'
|
||||
|
||||
/**
|
||||
* 背景音乐控制 composable
|
||||
* 处理浏览器自动播放限制:首次用户交互后再尝试播放
|
||||
*/
|
||||
export function useAudio(initialUrl = '') {
|
||||
const isPlaying = ref(false)
|
||||
const isReady = ref(false)
|
||||
let audio = null
|
||||
let currentUrl = initialUrl
|
||||
let unlockHandler = null
|
||||
|
||||
const setUrl = (url) => {
|
||||
currentUrl = url
|
||||
if (audio) {
|
||||
const wasPlaying = isPlaying.value
|
||||
audio.pause()
|
||||
audio.src = url
|
||||
isPlaying.value = false
|
||||
if (wasPlaying && url) play()
|
||||
}
|
||||
}
|
||||
|
||||
const ensureAudio = () => {
|
||||
if (audio) return audio
|
||||
audio = new Audio(currentUrl)
|
||||
audio.loop = true
|
||||
audio.volume = 0.5
|
||||
audio.preload = 'auto'
|
||||
audio.addEventListener('canplay', () => (isReady.value = true))
|
||||
audio.addEventListener('play', () => (isPlaying.value = true))
|
||||
audio.addEventListener('pause', () => (isPlaying.value = false))
|
||||
return audio
|
||||
}
|
||||
|
||||
const tryPlay = async () => {
|
||||
const a = ensureAudio()
|
||||
try {
|
||||
await a.play()
|
||||
} catch (e) {
|
||||
// 被浏览器拦截,等待用户手势
|
||||
isPlaying.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const play = async () => {
|
||||
const a = ensureAudio()
|
||||
try {
|
||||
await a.play()
|
||||
isPlaying.value = true
|
||||
} catch (e) {
|
||||
isPlaying.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const pause = () => {
|
||||
if (audio) audio.pause()
|
||||
isPlaying.value = false
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
if (isPlaying.value) pause()
|
||||
else play()
|
||||
}
|
||||
|
||||
// 首次交互解锁自动播放
|
||||
const armAutoplay = () => {
|
||||
const handler = () => {
|
||||
play()
|
||||
removeUnlock()
|
||||
}
|
||||
unlockHandler = handler
|
||||
window.addEventListener('pointerdown', handler, { once: true })
|
||||
window.addEventListener('keydown', handler, { once: true })
|
||||
}
|
||||
|
||||
const removeUnlock = () => {
|
||||
if (!unlockHandler) return
|
||||
window.removeEventListener('pointerdown', unlockHandler)
|
||||
window.removeEventListener('keydown', unlockHandler)
|
||||
unlockHandler = null
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
pause()
|
||||
removeUnlock()
|
||||
if (audio) {
|
||||
audio.src = ''
|
||||
audio = null
|
||||
}
|
||||
})
|
||||
|
||||
return { isPlaying, isReady, play, pause, toggle, tryPlay, armAutoplay, setUrl }
|
||||
}
|
||||
Reference in New Issue
Block a user