import assets from 'url:../../../Assets/Audio/**/*.ogg' console.log('audio assets:', assets) type Entry = { [key: string]: string | Entry } export const audio: Record = {} 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 }