How to change the source in howler.js

As I’ve stated, I’ve been working on an app to organize my samples and loops. I plan to open-source the app at the end of the year, after a private beta to get the tires kicked. Just getting the audio player in it working right has been quite a challenge… well, it was working right and then I decided to swap out the HTML5 built-in HTML Audio player in the browser for a JavaScript library that plays more file formats.

Enter Howler.js

For example, when the app loads, it loads in a default sound… a 4.6-second ringtone I created in .m4a format. The HTML Audio player cannot play .m4a, but Howler can. But Howler came with its own plethora of issues. The easy part was just remapping the HTML Audio methods I used to the ones Howler uses (such as play and pause). “Rewinding” was different. Howler doesn’t fire an event while playing (the HTML Audio player does) so instead of listening for the progress event and updating the elapsed time then, I have to run a loop that queries the player for the current progress. I do this with a requestAnimationFrame loop, but the loop breaks (intentionally) whenever the playback stops or pauses and is re-started when play begins.

The hardest part was switching sounds in Howler.js

With the HTML Audio player, you just change its src property. Howler needs more, so much more I just couldn’t get it to run right. Either it wouldn’t play the sound or it would play it and the previously loaded sound simultaneously. I googled and googled and found an open issue where it was discussed a couple of years back: Add dynamically musics to src[sic]. Amazingly there was a solution for my issue. I had to do a little reprogramming of Howler by adding a function (see below).

How does this make Howler change the source sound?

There are a few tricks. The simple “unload()” wasn’t working for me in my code, but by triggering its internal unload method with the “true” attribute, it cleared out the old sound. Still, it left the duration data from the previous sound in a couple of places: 1) in the duration it presented when I accessed the object property from outside, and 2) in the internal value it used to know when to stop playing.

That’s where setting the duration to 0, reset it and made it get the duration of the new file. Great, but since the first file loaded was 4.6 seconds long, even a 22-second sound would play for 4.6 seconds and then stop. That was fixed by giving the _sprite property a value of an empty object literal. I didn’t so much figure these out myself. Different people shared different approaches. I took a little from here, a little from there… voila!

A code snippet to dynamically change the source sound in Howler.js

I need to do a smidge more testing to see if any formats need me to pass in a file type, but I don’t think so. The data URI I need to create to play sounds from the machine’s storage needs a mime type, so it seems Howler.js may be getting that data from the mime type. For example, an mp3 file’s mime type is audio/mpeg.

I still have a little debugging to do. When I load a directory of files and sort them into a list, it works the first time I open a folder, but the second folder in a session breaks it, so my function to populate the “filepicker” may be doing something to Howler it doesn’t like being done more than once. I’ll fix it.

Anyway, since this was useful for me, I’m sharing it. And when the app is ready for beta testers, I’ll open source and share the app. Hopefully in a week or so. I’ll also use this code category when I post about specifically about coding.

Thasnks for reading!

One Comment

Add a Comment

Your email address will not be published. Required fields are marked *