From 1011b8885065b36e56efc6a833fe9114a69e88a3 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 4 Dec 2023 04:45:51 +0000 Subject: [PATCH] fix: sound effects stop music playback in iOS Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com> --- packages/client/src/scripts/sound.ts | 37 +++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/client/src/scripts/sound.ts b/packages/client/src/scripts/sound.ts index 84388b81c..289eb9e0b 100644 --- a/packages/client/src/scripts/sound.ts +++ b/packages/client/src/scripts/sound.ts @@ -1,16 +1,25 @@ import { ColdDeviceStorage } from "@/store"; +const ctx = new AudioContext(); const cache = new Map(); -export function getAudio(file: string, useCache = true): HTMLAudioElement { - let audio: HTMLAudioElement; +export async function getAudio( + file: string, + useCache = true, +): HTMLAudioElement { if (useCache && cache.has(file)) { - audio = cache.get(file); - } else { - audio = new Audio(`/static-assets/sounds/${file}.mp3`); - if (useCache) cache.set(file, audio); + return cache.get(file); } - return audio; + + const response = await fetch(`/static-assets/sounds/${file}.mp3`); + const arrayBuffer = await response.arrayBuffer(); + const audioBuffer = await ctx.decodeAudioData(arrayBuffer); + + if (useCache) { + cache.set(file, audioBuffer); + } + + return audioBuffer; } export function setVolume( @@ -28,11 +37,17 @@ export function play(type: string) { playFile(sound.type, sound.volume); } -export function playFile(file: string, volume: number) { +export async function playFile(file: string, volume: number) { const masterVolume = ColdDeviceStorage.get("sound_masterVolume"); - if (masterVolume === 0 || volume === 0 || file.toLowerCase().includes("none")) + if (masterVolume === 0 || volume === 0) { return; + } - const audio = setVolume(getAudio(file), volume); - audio.play(); + const gainNode = ctx.createGain(); + gainNode.gain.value = masterVolume * volume; + + const soundSource = ctx.createBufferSource(); + soundSource.buffer = await getAudio(file); + soundSource.connect(gainNode).connect(ctx.destination); + soundSource.start(); }