howler.js
howler.js copied to clipboard
Suggestions for more examples/docs?
I noticed we had some dings on Openbase (https://openbase.com/js/howler) for having poor documentation. One of the initial goals for the project was obviously to make audio on the web extremely easy, so I've been thinking about ways to improve that in the docs. This is something I've struggled with being so close to the project, so any suggestions or PRs for additional examples or areas to cover in the docs would be greatly appreciated!
Hey @goldfire first all, thank you very much for all the efforts. This library is gold. I would suggest more examples or more details on dynamic update the playlist of music. Maybe an example on random playlist. So far, everything is awesome.
I would love more extensive documentation on how to use Howler for sound effects in web games. I understand that one can just do it as is shown in the basic example, but I am personally puzzling over issues like what is the best pool number and should I handle unload of individual sounds, etc.
I would also love a Troubleshooting section, something like "Common problems and how to fix them".
Agreed, great library 😄
Two things for me:
-
I got caught out by orientation of the axes with the spatialisation audio, with my directional audio sounding from the wrong direction. I'm using howler not only so I don't have to find the edge cases, but also so I don't have to look at the finer details of web audio APIs. To fix, I had to swap my x/z axes so the web axes system lined up with babylonjs' system. A call out for this, such as an inclusion of the axes pic from https://webaudio.github.io/web-audio-api/#Spatialization might be good
-
A specific call out for features that don't work on certain platforms like iOS, all in its own section. This would be great to just have a look at and check I'm not relying on any features that are unsupported on some platforms. For me, something I'm worried about is how https://github.com/tonistiigi/audiosprite mentions iOS doesn't support playing multiple html5 audio sounds at the same time and I don't know if this will be the same when using web APIs instead.
I ran into a series of problems/discoveries when I tried to use Howler for a game:
How do I precache sounds?
I have a bunch of sounds to play when space ships are shooting each other. So I'll make a dictionary of URLs and instantiate Howl
on-demand, with the correct volume. I'll set the pos
and pannerAttr
and such. then call play()
.
But the first sound doesn't play
Oh right, because when I try to play it, it has to download the file first, given I'm instantiating the Howl
and calling play()
immediately.
Let's just make a dictionary of Howl
instances
Right! Because the instance will preload the sound file then cache it.
Nope, won't work because then I cannot play a dozen overlapping instances of laserSound
. I get some sort of error in the spatial engine. But I bet I also get the undesired behaviour of only being able to play one instance of the sound at a time.
Solution
Let's instantiate every sound once and let the instances be garbage collected. It's okay because Howl internally caches the files we download. We can make this async and then call it in our preload
game engine method:
const soundUrls = {
laserSound: "https://example.com/url/to/asset/or/output/of/bundler.mp3",
// ...
};
public static async precacheSounds() {
await Promise.all(
Object.values(soundUrls).map((url) => {
return new Promise<void>((res, err) => {
new Howl({
src: [url],
onload: () => res(),
onloaderror: () => err("custom error msg or construct it from callback"),
});
});
})
);
}
I would be happy to make a PR for this if you have any advice on where to place it and how much of this I should include. Personally, I found the important lessons to be:
- That the first use of a sound might not work in time if you try to play it immediately.
- That you cannot call the same Howl many times for overlapping sounds (am I wrong about this?)
- An example solution to precache
I am looking for more detailed documentation on how to efficiently load sound data from a locally stored blob with howler (that is with the least memory consumption overhead). I have a specific scenario, see below.
Missing documentation
There is very little documentation available at https://github.com/goldfire/howler.js#src-arraystring--required
However, I would like to have some more topics covered like
- object URL's (they work, but officially?)
- how to optimize local (offline) sound storage (with indexed db or local storage)
- how to handle very large and long sound files (multiple tens of MB's) efficiently
- how to optimize for very few and very many sound files (especially when they are also large and long)
My scenario
I am developing a karaoke-type application, for audio playback specifically in rehearsals. See https://web-test.replayer.app, if you want to try it. It's a PWA, for offline use, including the sound files. The files may be quite long (up to 15 mins) and I want to store them for offline use, too. The user downloads a package (.zip) of sound files, and the application stores them into the local indexed db storage.
I currently retrieve them (all at once) from the indexed db, and load them into individual howls for consecutive playback. I do this by creating objectURL's. A minor drawback is, that howler can not detect the media type from object URL's.
hey @suterma , I use howler in conjunction with localforage https://github.com/localForage/localForage to store mp3 Files. The library makes very easy to work with offline storage for large files.
@dheimoz Thanks for mentioning this library. I already use https://github.com/jakearchibald/idb-keyval with success. The issue at hand is more on how to efficiently hand over the data to howler for playback. I fear that some memory is actually allocated by howler, when I hand over the objectUrl. I would have some more comfort, when the howler docs would have an example or explanation about this. I have edited my other comment to better reflect this aspect.