I'm using HTML5 to program games; the obstacle I've run into now is how to play sound effects.
The specific requirements are few in number:
- Play and mix multiple sounds,
- Play the same sample multiple times, possibly overlapping playbacks,
- Interrupt playback of a sample at any point,
- Preferably play WAV files containing (low quality) raw PCM, but I can convert these, of course.
My first approach was to use the HTML5 <audio>
element and define all sound effects in my page. Firefox plays the WAV files just peachy, but calling #play
multiple times doesn't really play the sample multiple times. From my understanding of the HTML5 spec, the <audio>
element also tracks playback state, so that explains why.
My immediate thought was to clone the audio elements, so I created the following tiny JavaScript library to do that for me (depends on jQuery):
var Snd = {
init: function() {
$("audio").each(function() {
var src = this.getAttribute('src');
if (src.substring(0, 4) !== "snd/") { return; }
// Cut out the basename (strip directory and extension)
var name = src.substring(4, src.length - 4);
// Create the helper function, which clones the audio object and plays it
var Constructor = function() {};
Constructor.prototype = this;
Snd[name] = function() {
var clone = new Constructor();
clone.play();
// Return the cloned element, so the caller can interrupt the sound effect
return clone;
};
});
}
};
So now I can do Snd.boom();
from the Firebug console and play snd/boom.wav
, but I still can't play the same sample multiple times. It seems that the <audio>
element is really more of a streaming feature rather than something to play sound effects with.
Is there a clever way to make this happen that I'm missing, preferably using only HTML5 and JavaScript?
I should also mention that, my test environment is Firefox 3.5 on Ubuntu 9.10. The other browsers I've tried - Opera, Midori, Chromium, Epiphany - produced varying results. Some don't play anything, and some throw exceptions.
I ran into this while programming a musicbox card generator. Started with different libraries but everytime there was a glitch somehow. The lag on normal audio implementation was bad, no multiple plays... eventually ended up using lowlag library + soundmanager:
http://lowlag.alienbill.com/ and http://www.schillmania.com/projects/soundmanager2/
You can check out the implementation here: http://musicbox.grit.it/
I generated wav + ogg files for multi browser plays. This musicbox player works responsive on ipad, iphone, Nexus, mac, pc,... works for me.
HTML5
Audio
objectsYou don't need to bother with
<audio>
elements. HTML 5 lets you accessAudio
objects directly:There's no support for mixing in current version of the spec.
To play same sound multiple times, create multiple instances of the
Audio
object. You could also setsnd.currentTime=0
on the object after it finishes playing.Since the JS constructor doesn't support fallback
<source>
elements, you should useto test whether the browser supports Ogg Vorbis.
If you're writing a game or a music app (more than just a player), you'll want to use more advanced Web Audio API, which is now supported by most browsers.
howler.js
For game authoring, one of the best solutions is to use a library which solves the many problems we face when writing code for the web, such as howler.js. howler.js abstracts the great (but low-level) Web Audio API into an easy to use framework. It will attempt to fall back to HTML5 Audio Element if Web Audio API is unavailable.
wad.js
Another great library is wad.js, which is especially useful for producing synth audio, such as music and effects. For example:
Sound for Games
Another library similar to Wad.js is "Sound for Games", it has more focus on effects production, while providing a similar set of functionality through a relatively distinct (and perhaps more concise feeling) API:
Summary
Each of these libraries are worth a look, whether you need to play back a single sound file, or perhaps create your own html-based music editor, effects generator, or video game.
You may also want to use this to detect HTML 5 audio in some cases:
http://diveintohtml5.ep.io/everything.html
HTML 5 JS Detect function
I know this is a total hack but thought I should add this sample open source audio library I put on github awhile ago...
https://github.com/run-time/jThump
After clicking the link below, type on the home row keys to play a blues riff (also type multiple keys at the same time etc.)
Sample using jThump library >> http://davealger.com/apps/jthump/
It basically works by making invisible
<iframe>
elements that load a page that plays a sound onReady().This is certainly not ideal but you could +1 this solution based on creativity alone (and the fact that it is open source and works in any browser that I've tried it on) I hope this gives someone else searching some ideas at least.
:)
Have a look at the
jai(->mirror) (javascript audio interface) site. From looking at their source, they appear to be callingplay()
repeatedly, and they mention that their library might be appropriate for use in HTML5-based games.