From 085e131b3d5cb92794b8bc38b67599e7c515c399 Mon Sep 17 00:00:00 2001 From: kts of kettek Date: Sat, 29 Jan 2022 19:41:18 -0800 Subject: [PATCH] Add audio playback --- Engine/src/custom.d.ts | 5 +++ Engine/src/shared/audio.ts | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 Engine/src/shared/audio.ts diff --git a/Engine/src/custom.d.ts b/Engine/src/custom.d.ts index d40114f..765a21f 100644 --- a/Engine/src/custom.d.ts +++ b/Engine/src/custom.d.ts @@ -1,3 +1,8 @@ +declare module '*.ogg' { + const content: [string, string][] + export default content +} + declare module '*.yaml' { const content: any export default content diff --git a/Engine/src/shared/audio.ts b/Engine/src/shared/audio.ts new file mode 100644 index 0000000..7995dc5 --- /dev/null +++ b/Engine/src/shared/audio.ts @@ -0,0 +1,72 @@ +import assets from 'url:../../../Assets/Audio/**/*.ogg' + +export const audio: Record = assets + +// Preload 'em +for (let [key, value] of (Object.entries(assets) as [string,string][])) { + let audio = new Audio() + audio.addEventListener('canplaythrough', () => { + console.log('preloaded audio', key) + }) + audio.preload = '' + audio.src = value +} + +let playingSongAudio: HTMLAudioElement +export function playSong(name: string) { + // 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) + } + }, 100) + })(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) + } + }, 100) + })(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): HTMLAudioElement { + let s = new Audio() + + s.src = audio[name] + s.autoplay = true + s.preload = '' + ;(async () => { + await s.play() + })() + + return s +} \ No newline at end of file