fix(AudioController): Autoplay policy handling for WebView2

This commit is contained in:
neoapps-dev
2026-05-21 11:37:44 +03:00
parent 7107161dc1
commit 8bb20a072d
+23 -16
View File
@@ -191,25 +191,30 @@ export function useAudioController({
if (!audioContextRef.current) { if (!audioContextRef.current) {
audioContextRef.current = new AudioContext(); audioContextRef.current = new AudioContext();
} }
if (audioContextRef.current.state === "suspended") {
audioContextRef.current.resume();
}
return audioContextRef.current; return audioContextRef.current;
}, []); }, []);
const ensureAudioContextReady = useCallback(async () => {
const ctx = getAudioContext();
if (ctx.state === "suspended") {
await ctx.resume();
}
return ctx;
}, [getAudioContext]);
const loadAudioBuffer = useCallback( const loadAudioBuffer = useCallback(
async (url: string): Promise<AudioBuffer | undefined> => { async (url: string): Promise<AudioBuffer | undefined> => {
try { try {
const response = await fetch(url); const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer(); const arrayBuffer = await response.arrayBuffer();
const ctx = getAudioContext(); const ctx = await ensureAudioContextReady();
return await ctx.decodeAudioData(arrayBuffer); return await ctx.decodeAudioData(arrayBuffer);
} catch (error) { } catch (error) {
console.error("Failed to load audio:", url, error); console.error("Failed to load audio:", url, error);
return undefined; return undefined;
} }
}, },
[getAudioContext], [ensureAudioContextReady],
); );
const playSfx = useCallback( const playSfx = useCallback(
@@ -224,7 +229,7 @@ export function useAudioController({
} }
if (buffer) { if (buffer) {
const ctx = getAudioContext(); const ctx = await ensureAudioContextReady();
const source = ctx.createBufferSource(); const source = ctx.createBufferSource();
const gainNode = ctx.createGain(); const gainNode = ctx.createGain();
source.buffer = buffer; source.buffer = buffer;
@@ -234,7 +239,7 @@ export function useAudioController({
source.start(); source.start();
} }
}, },
[sfxVol, loadAudioBuffer, getAudioContext], [sfxVol, loadAudioBuffer, ensureAudioContextReady],
); );
const playPressSound = useCallback(() => playSfx("press.wav"), [playSfx]); const playPressSound = useCallback(() => playSfx("press.wav"), [playSfx]);
@@ -256,9 +261,10 @@ export function useAudioController({
}, []); }, []);
const playMusicBuffer = useCallback( const playMusicBuffer = useCallback(
(buffer: AudioBuffer, startTime: number = 0) => { async (buffer: AudioBuffer, startTime: number = 0) => {
const ctx = await ensureAudioContextReady();
stopMusic(); stopMusic();
const ctx = getAudioContext();
const source = ctx.createBufferSource(); const source = ctx.createBufferSource();
const gainNode = ctx.createGain(); const gainNode = ctx.createGain();
@@ -297,7 +303,7 @@ export function useAudioController({
} }
}; };
}, },
[stopMusic, getAudioContext], [stopMusic, ensureAudioContextReady],
); );
const fadeOutMusic = useCallback( const fadeOutMusic = useCallback(
@@ -336,9 +342,10 @@ export function useAudioController({
); );
const fadeInMusic = useCallback( const fadeInMusic = useCallback(
(buffer: AudioBuffer, targetVolume: number, duration: number = 500) => { async (buffer: AudioBuffer, targetVolume: number, duration: number = 500) => {
const ctx = await ensureAudioContextReady();
stopMusic(); stopMusic();
const ctx = getAudioContext();
const source = ctx.createBufferSource(); const source = ctx.createBufferSource();
const gainNode = ctx.createGain(); const gainNode = ctx.createGain();
@@ -377,7 +384,7 @@ export function useAudioController({
} }
}; };
}, },
[stopMusic, getAudioContext], [stopMusic, ensureAudioContextReady],
); );
const cycleSplash = useCallback(() => { const cycleSplash = useCallback(() => {
@@ -401,7 +408,7 @@ export function useAudioController({
} }
} }
if (buffer) { if (buffer) {
playMusicBuffer(buffer); await playMusicBuffer(buffer);
} }
}; };
@@ -424,7 +431,7 @@ export function useAudioController({
} }
} }
if (buffer) { if (buffer) {
fadeInMusic(buffer, musicVol / 100, 500); await fadeInMusic(buffer, musicVol / 100, 500);
} }
}; };
@@ -463,7 +470,7 @@ export function useAudioController({
} }
} }
if (buffer) { if (buffer) {
fadeInMusic(buffer, musicVol / 100, 500); await fadeInMusic(buffer, musicVol / 100, 500);
} }
}; };