File size: 2,354 Bytes
59c3ada |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
import { useState, useRef, useCallback } from "react";
type AudioKeys = "pop" | "hover" | "music";
interface AudioPlayer {
initAudio: () => boolean;
playPopSound: () => void;
playHoverSound: () => void;
toggleMusic: () => void;
playMusic: () => void;
isMusicPlaying: boolean;
isAudioReady: boolean;
}
const useAudioPlayer = (): AudioPlayer => {
const audioRefs = useRef<Record<AudioKeys, HTMLAudioElement | null>>({
pop: null,
hover: null,
music: null,
});
const [isReady, setIsReady] = useState<boolean>(false);
const [isMusicPlaying, setIsMusicPlaying] = useState<boolean>(false);
const initAudio = useCallback(() => {
if (isReady) return true;
try {
audioRefs.current.pop = new Audio("/bubble.mp3");
audioRefs.current.hover = new Audio("/hover.mp3");
audioRefs.current.music = new Audio("/music.mp3");
audioRefs.current.music.loop = true;
audioRefs.current.music.volume = 0.1;
setIsReady(true);
return true;
} catch {
return false;
}
}, [isReady]);
const playMusic = useCallback(() => {
if (isReady && !isMusicPlaying) {
audioRefs.current.music?.play().catch(() => {});
setIsMusicPlaying(true);
}
}, [isReady, isMusicPlaying]);
const toggleMusic = useCallback(
(force?: boolean) => {
if (!isReady || !audioRefs.current.music) return;
const shouldBePlaying = force === undefined ? !isMusicPlaying : force;
if (shouldBePlaying === isMusicPlaying) return;
if (shouldBePlaying) {
audioRefs.current.music?.play().catch(() => {});
} else {
audioRefs.current.music?.pause();
}
setIsMusicPlaying(shouldBePlaying);
},
[isReady, isMusicPlaying],
);
const playPopSound = useCallback(() => {
if (!isReady || !audioRefs.current.pop) return;
audioRefs.current.pop.currentTime = 0;
audioRefs.current.pop.play().catch(() => {});
}, [isReady]);
const playHoverSound = useCallback(() => {
if (!isReady || !audioRefs.current.hover) return;
audioRefs.current.hover.currentTime = 0;
audioRefs.current.hover.play().catch(() => {});
}, [isReady]);
return {
initAudio,
playPopSound,
playHoverSound,
toggleMusic,
playMusic,
isMusicPlaying,
isAudioReady: isReady,
};
};
export default useAudioPlayer;
|