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();
}