Calling Play on an Already Playing Howler.js Instance
This article explains the behavior of the Howler.js library when you
call the play() method on a sound instance that is already
active. You will learn how Howler.js handles overlapping audio, how
unique sound IDs are managed, and how to modify this behavior to either
restart the audio or prevent multiple instances from playing
simultaneously.
Default Behavior: Multi-Playback (Overlapping Audio)
By default, Howler.js is designed to support multi-playback. If you
call .play() on a Howl instance that is
already playing, the library will not stop, pause, or
restart the currently playing audio.
Instead, Howler.js will start a brand new, independent playback of the same sound file. This results in the audio layering over itself, playing multiple instances of the sound at the same time. This behavior is ideal for sound effects in games, such as gunshots or UI clicks, where rapid consecutive triggers need to overlap.
Each time you call .play(), Howler.js generates and
returns a unique sound ID (integer) for that specific
playback instance. You can use this ID to control that specific sound
layer individually (e.g., pausing, stopping, or changing the volume of
just one of the overlapping sounds).
const sound = new Howl({
src: ['sound.mp3']
});
// Starts the first playback instance
const id1 = sound.play();
// Starts a second, overlapping instance of the same sound
const id2 = sound.play(); Behavior When Specifying a Sound ID
If you pass a specific, currently active sound ID back into the
.play() method (i.e., sound.play(id)), the
behavior changes.
In this scenario, Howler.js will not layer a new sound. Instead, it will restart that specific audio instance from the beginning.
How to Prevent Overlapping Sounds
If your application requires a sound to only play one at a time (like background music or a voiceover track), you can prevent the default overlapping behavior using one of the following methods:
1. Stop and Play (To Restart the Sound)
To stop the current playback and start it fresh from the beginning,
call .stop() immediately before calling
.play().
// Stops any currently playing instances of this sound and starts a new one
sound.stop().play();2. Check If Playing (To Ignore Subsequent Play Calls)
If you want the sound to continue playing uninterrupted and ignore
any additional play commands, check the .playing() status
first.
// Only play the sound if it is not currently active
if (!sound.playing()) {
sound.play();
}