Encountering errors with sound libraries in NextJS led me to create my own Audio Player component that can be controlled externally. This player utilizes the "audio" tag accessed through react refs.
Let's delve into the code snippets for a better understanding.
The parent component manages a "play" state to determine if the audio should play or not. Within the AudioPlayer component, this state is monitored using useEffect, triggering the sound only when the "play" state is true after a user interaction like a button click. Once the sound finishes playing, the "play" property is reset to false, enabling it to play again when triggered.
Benefits of this approach include lesser code due to a separate component and the ability to control the AudioPlayer's state externally.
However, limitations include the need for user initiation to activate the sound and being unable to play the sound unless it has ended previously.
import React, { useRef, useEffect } from "react";
export default function AudioPlayer(props) {
const audioRef = useRef(null);
useEffect(() => {
if (props.play) {
playAudio();
}
}, [props.play]);
const playAudio = () => {
if (audioRef.current) {
audioRef.current.play();
}
};
const handleAudioEnded = () => {
// Call the callback function when the audio ends
if (props.onFinish) {
props.onFinish();
}
};
return (
<div>
<audio ref={audioRef} controls className="hidden" onEnded={handleAudioEnded}>
<source src={props.src} type="audio/mp3" />
Your browser does not support the audio element.
</audio>
</div>
);
}
To incorporate this within the parent component:
// State to toggle sound playback
const [playSubmitSound, setPlaySubmitSound] = useState(false);
return (
<AudioPlayer
src="/sounds/submit.mp3"
play={playSubmitSound}
onFinish={() => setPlaySubmitSound(false)}
/>
<button onClick={() => setPlaySubmitSound(true)}>sound</button>);
Note: TailwindCSS is used to hide the Audio tag, but CSS can achieve the same by setting the display: none;
property on the wrapping div of the audio tag.