117 lines
2.7 KiB
TypeScript
117 lines
2.7 KiB
TypeScript
import assets from 'url:../../../Assets/Audio/**/*.ogg'
|
|
console.log('audio assets:', assets)
|
|
|
|
type Entry = { [key: string]: string | Entry }
|
|
|
|
export const audio: Record<string, string> = {}
|
|
|
|
function traverse(path: string, entry: Entry|string) {
|
|
if (typeof entry === 'string') {
|
|
audio[path] = entry
|
|
} else if (typeof entry === 'object') {
|
|
for (let [key, value] of Object.entries(entry)) {
|
|
traverse((path?path+'/':'')+key, value)
|
|
}
|
|
}
|
|
}
|
|
|
|
traverse('', assets)
|
|
|
|
export let enabled = true
|
|
export function enableSound() {
|
|
enabled = true
|
|
if (playingSongAudio) {
|
|
playingSongAudio.play()
|
|
}
|
|
}
|
|
export function disableSound() {
|
|
enabled = false
|
|
if (playingSongAudio) {
|
|
playingSongAudio.pause()
|
|
}
|
|
}
|
|
|
|
// Preload 'em
|
|
for (let [key, value] of (Object.entries(audio))) {
|
|
let audio = new Audio()
|
|
audio.addEventListener('canplaythrough', () => {
|
|
console.log('preloaded audio', key)
|
|
})
|
|
audio.preload = ''
|
|
audio.src = value
|
|
}
|
|
|
|
let audioCache: HTMLAudioElement[] = []
|
|
|
|
let playingSongAudio: HTMLAudioElement
|
|
export function playSong(name: string) {
|
|
if (!enabled) return
|
|
// Replace old audio and start crossfading.
|
|
if (playingSongAudio && !playingSongAudio.paused) {
|
|
;((playingSongAudio: HTMLAudioElement) => {
|
|
let cl = setInterval(() => {
|
|
if (Number(playingSongAudio.volume.toFixed(1)) > 0) {
|
|
playingSongAudio.volume -= 0.1
|
|
} else {
|
|
clearInterval(cl)
|
|
}
|
|
}, 50)
|
|
})(playingSongAudio)
|
|
}
|
|
playingSongAudio = new Audio()
|
|
playingSongAudio.autoplay = true
|
|
playingSongAudio.preload = ''
|
|
playingSongAudio.loop = true
|
|
playingSongAudio.volume = 0
|
|
|
|
// Start fade in.
|
|
;((playingSongAudio: HTMLAudioElement) => {
|
|
let cl = setInterval(() => {
|
|
if (playingSongAudio.paused) {
|
|
clearInterval(cl)
|
|
return
|
|
}
|
|
if (Number(playingSongAudio.volume.toFixed(1)) < 1.0) {
|
|
playingSongAudio.volume += 0.1
|
|
} else {
|
|
clearInterval(cl)
|
|
}
|
|
}, 50)
|
|
})(playingSongAudio)
|
|
|
|
playingSongAudio.src = audio[name]
|
|
let promise = playingSongAudio.play()
|
|
if (promise !== undefined) {
|
|
promise.then(() => {
|
|
// ok
|
|
}).catch((error: any) => {
|
|
//console.error(error)
|
|
})
|
|
}
|
|
}
|
|
|
|
export function playSound(name: string, volume: number): HTMLAudioElement|undefined {
|
|
if (!enabled) return
|
|
let s = audioCache.pop()
|
|
if (!s) {
|
|
s = new Audio()
|
|
s.autoplay = true
|
|
s.preload = ''
|
|
s.addEventListener('ended', () => {
|
|
audioCache.push(s as HTMLAudioElement)
|
|
})
|
|
}
|
|
|
|
|
|
s.src = audio[name]
|
|
s.volume = volume
|
|
let promise = s.play()
|
|
if (promise !== undefined) {
|
|
promise.then(() => {
|
|
// ok
|
|
}).catch((error: any) => {
|
|
})
|
|
}
|
|
|
|
return s
|
|
} |