How to Update Sound Position Dynamically in Howler.js

Controlling the playback position of an active audio file is crucial for creating interactive web applications, games, and custom media players. This article explains how to dynamically update the current playback position of a playing sound in howler.js using the library’s built-in seek() method, allowing you to instantly fast-forward, rewind, or skip to specific timestamps.

To dynamically update the position of a playing sound in howler.js, you use the seek() method on your Howl instance. The method accepts the new playback position in seconds as its first argument.

Here is a basic example of how to initialize a sound, play it, and then jump to a specific timestamp:

// Initialize the sound
const sound = new Howl({
  src: ['audio.mp3']
});

// Play the sound and store its unique play ID
const soundId = sound.play();

// Update the playback position dynamically to 30 seconds
sound.seek(30, soundId);

Passing the Sound ID

While you can call sound.seek(30) without a second argument, passing the soundId returned by the play() method is highly recommended. If you have multiple instances of the same sound playing simultaneously, specifying the ID ensures that only the target audio instance is updated.

Implementing a Dynamic Progress Slider

A common real-world use case is syncing a range slider (progress bar) to the audio playback, allowing users to scrub through the track.

You can capture the user’s input from an HTML range slider and update the audio position in real-time:

<input type="range" id="progressBar" min="0" max="100" value="0">
const progressBar = document.getElementById('progressBar');

// Update the maximum value of the slider once the audio loads
sound.once('load', () => {
  progressBar.max = sound.duration();
});

// Update the sound position when the user scrubs the slider
progressBar.addEventListener('input', () => {
  const targetTime = parseFloat(progressBar.value);
  sound.seek(targetTime, soundId);
});

Retrieving the Current Position

The seek() method is versatile; if you call it without a time parameter, it acts as a getter and returns the current playback position of the sound in seconds.

// Get the current playback position
const currentTime = sound.seek(soundId);
console.log(`Current position: ${currentTime} seconds`);

By combining the getter and setter capabilities of the seek() method, you can easily build robust playback controls, loop specific audio segments, or sync visual elements directly to your audio timeline.