SoundJS: Preloading Audio
Synopsis: Preload audio.
Topics: preload, registerSound, registerManifest, PreloadJS, manifest
Target: PreloadJS v0.4.1+
This tutorial is part of the SoundJS GitHub repository.
Check out the repository for more tutorials and a handful of helpful samples.
SoundJS Basics
Without CreateJS, most modern browsers do a great job of loading enough audio data to play back a sound
continuously until the end using HTML tags. The canplaythrough
event will fire when the buffer is
full, and the sound will start. This is sufficient for a click-to-play sound, or for a background sound that
can start whenever its ready - but in order to play on-demand audio for games, applications, and web sites,
sounds must be preloaded first.
There are a few different approaches to preloading, and this article provides some of the recommended patterns that can be used with SoundJS:
- Internal preloading capabilities in SoundJS
- Preloading audio using PreloadJS
SoundJS Internal Preloading
SoundJS includes the ability to internally preload audio. This requires each sound to be "registered" with SoundJS, and it will immediately be preloaded for use.
SoundJS will only preload audio that is supported, so if multiple formats are provided, only the one that the browser can play will be preloaded.
When each audio file is complete, the Sound class will fire off a fileload
event. A
fileload
event is dispatched once for each audio file that has been registered.
Multiple requests for the same audio source will fire the first time it is loaded, but for each instance that
uses that source. The event contains the sound's src
and id
property, as well as a
generic data
property containing any associated data that was passed into the registerSound
call.
Once you have registered sounds and they have finished loading, they can be played on-demand using the play
call that passes in either the src
or the id
.
A manifest of files can also be registered, but note that a fileload
event will be fired for each
sound - there is no "complete" event for internal preloading a manifest in SoundJS.
This approach is great for quick demos, or applications that just need a little bit of audio. For larger projects, it is recommended to use PreloadJS to load audio.
Preloading using PreloadJS
PreloadJS is a CreateJS library that helps preload all sorts of content. Specific architecture has gone into how audio is preloaded, since it can not be simply downloaded and then retrieved from the browser cache like many html objects (such as images, scripts, svg, etc). For larger projects with many file types (or just a lot of files), PreloadJS is a better choice for loading audio.
The LoadQueue
class is the main interface for preloading content. Simply construct a LoadQueue, and
then add a file, or manifest of files. The queue will dispatch events as the progress changes, files are loaded,
or errors occur (plus a
few
other
events).
Here is a quick sample that loads some images:
Sounds require some special considerations though:
- PreloadJS doesn't know how to fallback to alternate file types if the original type is not supported
- PreloadJS has no way to determine how to load audio (xhr, tag, flash, etc)
- SoundJS requires some additional calls to register sounds properly
To solve these (and other) problems, PreloadJS has a fairly simple plugin model, which provides the ability to pre-process files before they are loaded, or completely override how loading is done.
SoundJS has already been built as a PreloadJS plugin, so it can just be installed, and audio loads will automatically be handled by SoundJS.
That's it! Now all preload requests that are of type:"sound"
or have a
supported file extension will be properly handled by SoundJS. All other aspects of preloading remain unchanged -
the same events are dispatched, and initialized audio tags (for html audio) or data buffers (for web audio)
will be available from PreloadJS. Sounds are also automatically registered with SoundJS.
Sounds can now be played on-demand using the same code from the beginning of this tutorial:
Using Flash as a Fallback
The FlashAudioPlugin is completely compatible with both internal and PreloadJS preloading. Follow the steps in the FlashAudioPlugin documentation to set up the FlashAudioPlugin as a fallback (or primary playback plugin), and it will preload the same way the samples above describe.
Tag loading vs XHR loading
It is important to know how SoundJS loads audio, so it can be configured to work properly depending on the playback requirement (HTML tags vs WebAudio), or location of sound files (local, relative, or remote).
SoundJS plays audio using a specific plugin depending on the capabilities. The available plugins are Web Audio, HTML Audio, and Flash. By default, SoundJS will attempt to use Web Audio playback (via the WebAudioPlugin), and then fall back to HTML audio when Web Audio is not supported. These playback modes will work in 90% of the current versions of modern browsers. (the big exception being Mobile Safari on iOS 5 and older).
- Web Audio requires a fully loaded data buffer, which can only be loaded using XHR (XMLHttpRequest).
- HTML Audio requires a sound tag, which has been loaded enough to play back, and can only be loaded using HTML audio tags. This is why loading using tags often appears to be faster, especially with large files
- Local and cross-domain loading can not use Web Audio due to cross-origin issues (CORS can be used to get around remote loading, but requires some server setup)
The purpose of SoundJS is to provide a consistent playback engine, no matter what browser the end user has - so it will try and make the best determination it can on which plugin to use by testing browser capabilities. If there is no Web Audio support, or the user is loading local files, HTML audio will be used instead. Check out the section on Using Flash as a Fallback for an additional fallback for older browsers.
Related Links
- Download CreateJS from the Adobe CDN
- Get the SoundJS source code, including minified versions of SoundJS and FlashAudioPlugin from GitHub.
- Read more about SoundJS in the online docs (also available in GitHub)
- Read more about PreloadJS in the online docs (also available in GitHub)