Track Audio Load Progress in Howler.js
Tracking the loading progress of audio files in Howler.js is essential for creating accurate preloaders and progress bars in web applications. Because Howler.js does not provide a built-in progress event, you must calculate the loading percentage by fetching the audio file manually using native browser APIs before passing it to Howler. This article explains how to use XMLHttpRequest to track download progress and load the cached file into a Howler instance.
The Challenge with Howler.js
By default, Howler.js only provides an onload event,
which fires once the entire audio file has finished loading. It does not
expose real-time buffer progress. To get around this limitation, you can
download the audio file as a binary Blob using an
XMLHttpRequest (XHR) and monitor its progress, then feed
that Blob directly to Howler.js.
Step-by-Step Implementation
Here is the most reliable method to calculate and display the load percentage of a sound file in Howler.js.
1. Fetch the Audio and Track Progress
Create an XMLHttpRequest pointing to your audio file.
Set the responseType to 'blob' so the browser
handles the download as a binary object. Inside the
onprogress event, calculate the percentage by dividing the
bytes loaded by the total bytes.
const audioUrl = 'https://example.com/audio.mp3';
const xhr = new XMLHttpRequest();
xhr.open('GET', audioUrl, true);
xhr.responseType = 'blob';
// Calculate and track progress
xhr.onprogress = function(event) {
if (event.lengthComputable) {
const percentLoaded = (event.loaded / event.total) * 100;
console.log(`Loading: ${percentLoaded.toFixed(2)}%`);
// Update your UI progress bar here
}
};2. Pass the Loaded Blob to Howler.js
Once the download is complete, use URL.createObjectURL()
to convert the downloaded Blob into a temporary local URL. You can then
pass this local URL to the src array of your Howl
instance.
Because blob URLs do not have file extensions, you must explicitly
define the format property in your Howler configuration so
the library knows how to decode the audio.
xhr.onload = function() {
if (xhr.status === 200) {
// Create a local URL representing the downloaded audio blob
const blobUrl = URL.createObjectURL(xhr.response);
// Initialize Howl with the blob URL
const sound = new Howl({
src: [blobUrl],
format: ['mp3'], // Explicitly declare the file format
onload: function() {
console.log('Audio is fully loaded and ready to play!');
sound.play();
}
});
} else {
console.error('Failed to download the audio file.');
}
};
// Start the request
xhr.send();Important Considerations
- CORS Headers: Since you are fetching the audio file
via XMLHttpRequest, the server hosting the audio file must have
Cross-Origin Resource Sharing (CORS) headers enabled. If the audio is
hosted on a different domain, ensure the server sends
Access-Control-Allow-Origin: *. - Memory Management: When using
URL.createObjectURL(), the browser keeps the resource in memory until the document is unloaded. If you are loading many large files, release the memory by callingURL.revokeObjectURL(blobUrl)after the Howlonloadevent fires and the audio is fully decoded.