let hoverAudio = null
|
let clickAudio = null
|
let unlocked = false
|
let unlockListenerAdded = false
|
|
function getHoverAudio() {
|
if (!hoverAudio) {
|
hoverAudio = uni.createInnerAudioContext()
|
hoverAudio.src = '/static/sounds/hover.mp3'
|
}
|
return hoverAudio
|
}
|
|
function getClickAudio() {
|
if (!clickAudio) {
|
clickAudio = uni.createInnerAudioContext()
|
clickAudio.src = '/static/sounds/click.mp3'
|
}
|
return clickAudio
|
}
|
|
/** 安全播放,吞掉 autoplay 策略导致的 Promise rejection */
|
function safePlay(audio) {
|
try {
|
audio.stop()
|
const ret = audio.play()
|
if (ret && typeof ret.then === 'function') {
|
ret.catch(() => {})
|
}
|
} catch (e) {}
|
}
|
|
/** 首次用户点击/触摸后解锁音频(hover 不算用户手势) */
|
function primeAudio() {
|
;[getHoverAudio(), getClickAudio()].forEach(audio => {
|
try {
|
audio.volume = 0
|
const ret = audio.play()
|
const finish = () => {
|
audio.stop()
|
audio.volume = 1
|
}
|
if (ret && typeof ret.then === 'function') {
|
ret.then(finish).catch(() => { audio.volume = 1 })
|
} else {
|
setTimeout(finish, 30)
|
}
|
} catch (e) {
|
audio.volume = 1
|
}
|
})
|
}
|
|
export function setupSoundUnlock() {
|
if (unlockListenerAdded || typeof document === 'undefined') return
|
unlockListenerAdded = true
|
const onUnlock = () => {
|
if (unlocked) return
|
unlocked = true
|
primeAudio()
|
document.removeEventListener('click', onUnlock, true)
|
document.removeEventListener('touchstart', onUnlock, true)
|
document.removeEventListener('keydown', onUnlock, true)
|
}
|
document.addEventListener('click', onUnlock, true)
|
document.addEventListener('touchstart', onUnlock, true)
|
document.addEventListener('keydown', onUnlock, true)
|
}
|
|
function ensureUnlocked() {
|
if (!unlocked) {
|
unlocked = true
|
primeAudio()
|
}
|
}
|
|
export function playHoverSound() {
|
if (!unlocked) return
|
safePlay(getHoverAudio())
|
}
|
|
export function playClickSound() {
|
ensureUnlocked()
|
safePlay(getClickAudio())
|
}
|
|
setupSoundUnlock()
|