mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-09-23 08:32:51 +00:00
fix(AudioController): Autoplay policy handling for WebView2
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user