I am transitioning to use-sound as my audio player right now, but I have a problem when having multiple components on the same page. My sounds are a bit longer than simple beeps, so the problem is that sounds will be overlapping if the user clicks on multiple components that trigger useSound.
The interrupt flag that useSound provides is very useful when using sprites or having multiple sounds in one component, but I am using multiple components, so the instances won't affect each other.
Here is my basic component:
import useSound from 'use-sound';
const Button = ({soundPath}) => {
const [play] = useSound(soundPath, { interrupt: true });
return <button onClick={play}>Boop!</button>;
};
and I am using it like so:
<div>
<Button soundPath="https://...audio1.mp3" />
<Button soundPath="https://...audio2.mp3" />
<Button soundPath="https://...audio3.mp3" />
</div>
I had this problem before when using a different audio player, and I used to solve it by finding all html <audio> tags and pausing them, like so:
document.addEventListener(
"play",
function (e) {
var audios = document.getElementsByTagName("audio");
for (var i = 0, len = audios.length; i < len; i++) {
if (audios[i] != e.target) {
audios[i].pause();
audios[i].currentTime = 0;
}
}
},
true
);
Not the most elegant solution, but it worked. This doesn't seem to work with use-sound and I am not sure why? It seems like it does not inject <audio> tags into the DOM.
Any ideas on how I could solve this?
This is what I did:
idprop is used to differentiate one button from another.currentPlayButtonprop is used to keep track of which button is currently clicked.setCurrentPlayButtonprop is a function used to change the value ofcurrentPlayButton.useEffectinside the<Button/>component is used to ensure that only one button can be played at a time.