SoundManager 2: Getting Started
How SoundManager Works
It starts out easy, but you can go down the rabbit hole if you want.
SoundManager 2 Tutorial: What, Why, How
Problem: Browsers lack good, consistent native audio support. (HTML 5's Audio()
is the future, but is still in development.)
Solution: Javascript API using HTML5 Audio() + headless Flash via ExternalInterface, works almost everywhere. If HTML5 is supported but "non-free" MP3/MP4 formats are not, flash can be used as a fallback.
SoundManager 2 wraps and extends both the HTML Audio and Flash Audio APIs, providing a single, unified sound API to Javascript; the API is consistent regardless of the technology working under the hood to play sound. (The flash portion is hidden, transparent to both developers and end users.)
Including SoundManager 2
The soundmanager2.js core can get down to 11 KB over the wire, depending on what version you use. A few versions of the SM2 script are available, balancing code size between commented, debug-enabled and production-optimized builds.
Regardless of which build you use, take advantage of gzip compression on your server for big savings. As shown below, SoundManager 2 compresses quite well with gzip; the full debug-enabled version served with gzip is smaller than even the minified, no-debug version served without.
Build version | Recommended use | File size | + gzip |
---|---|---|---|
Original, formatted debug-enabled version with comments. Passes jslint. <script src="soundmanager2.js"></script>
|
Development, testing, debugging | 153 KB | 41 KB |
"No-debug", formatted (comments removed, whitespace retained) version <script src="soundmanager2-nodebug.js"></script>
|
Production, "clean" no-debug code | 78 KB | 17 KB |
Minified (Google Closure Compiler-munged, no comments or whitespace), debug-enabled version <script src="soundmanager2-jsmin.js"></script>
|
Production, with debug code | 47 KB | 16 KB |
Build-script optimized, minified, no-debug version <script src="soundmanager2-nodebug-jsmin.js"></script>
|
Production-optimized, debug code removed | 34 KB | 11 KB! |
You then need to tell SM2 where to find the flash .SWF it will need (depending on HTML5 support), and optionally what version of Flash (~2.8 KB for flash 8, and ~8.5 KB for flash 9) depending on what API features you want:
<script>
soundManager.setup({
url: '/path/to/swf-files/',
flashVersion: 9, // optional: shiny features (default = 8)
// optional: ignore Flash where possible, use 100% HTML5 mode
// preferFlash: false,
onready: function() {
// Ready to use; soundManager.createSound() etc. can now be called.
}
});
</script>
If you plan to eventually use the flash block handling feature (disabled in this example), you'll want to look at the flash block demo and include the relevant CSS it uses.
Basic SoundManager Template
For a live example of a page including SoundManager 2, check the bare-bones template.
SoundManager File Structure
Or, "What you get when you download SM2."
The core audio API bits require script/soundmanager2.js
and the SWF files swf/soundmanager2.swf
and swf/soundmanager2_flash9.swf
, as well as the _debug
versions of the SWFs. The flash 9 SWF enables some extra API features, and is only used if you set soundManager.flashVersion = 9
(the default is 8.)
-
soundmanager2/
- demo/ - Examples, MP3 player UIs etc.
- doc/ - API method documentation, notes, troubleshooting
- script/ - API core, soundmanager2.js
- src/ - AS2/AS3 Flash source used to build SWFs (for flash development)
- swf/ - API core, SoundManager 2 .SWF files
- troubleshoot/ - Tool for finding/fixing startup issues
How SoundManager 2 Really Works
SoundManager 2 is the result of Javascript talking to a hidden Flash movie. The Flash layer is not something you have to work with directly, but it is the component which makes audio control possible behind the scenes.
Flash can expose methods to Javascript via ExternalInterface, allowing bi-directional calls to be made and thus providing additional functionality to Javascript.
For the real gory details on the behind-the-scenes action of JS + Flash, see How SoundManager 2 Works on schillmania.com.
Startup / Initialization
In brief, here is now SM2 starts up:
- soundmanager2.js loads
- new SoundManager() constructor call, event listeners attached for dom ready/init
- document.createElement('embed') (or 'object' for IE), append Flash .SWF to document
- SWF loads, Flash makes call to JS function: "Hi, JS!"
- JS -> Flash test (JS calls Flash function): "Hello, Flash!"
- -- startup is complete, soundManager.onready() fires --
A single Javascript include will link in all of the required code for the library, which will automatically begin loading either at onDOMContentLoaded()
if supported, or alternately, after window.onload()
(eg., IE 6 and others.) The default behaviour is to start "as soon as possible", but the library can be configured to wait for window.onload()
in all cases as well. Loading and initialisation are separate events.
Once initialised, SM2 will call event handlers/listeners registered via soundManager.onready()
. There are also "old-skool" onload()/onerror() event handlers which you can define just as you would with window.onload()
.
If you want to lazy-load or defer SM2, see Lazy-loading and SM2_DEFER.
SoundManager onready() / ontimeout() Event Handlers
onready()
is a flexible method that can be used to queue numerous listeners for SM2's successful start-up. Simply pass a callback function, which will be called when SM2 has successfully started:
soundManager.onready(function() {
// SM2 is ready to go!
makeSomeNoise(); // soundManager.createSound(), etc.
});
ontimeout()
is used to add listeners for SM2 init failures, which can happen due to missing or blocked Flash support. They are not necessarily fatal as in the flash block case, where onready()
calls can follow ontimeout()
if the user unblocks flash after a failed init attempt.
soundManager.ontimeout(function() {
// SM2 could not start. Flash blocked, missing or security error? Complain, etc.?
});
Lazy-loading / Dynamically-loading SM2 on-the-fly
Let's say you wanted to load and start SM2 after your page has loaded, using JavaScript to insert a script node etc., or otherwise only start SM2 conditionally. You can load the library dynamically (at or after DOMContentReady
), and it will not attempt to init until you call setup()
with a url
parameter.
Example:
function loadSM2() {
// -- load soundmanager2.js via <script>, createElement('script') or XHR etc. --
// imaginary loadJS() function with callback ...
loadJS('/path/to/soundmanager2.js', function() {
// once soundmanager2.js has loaded, call soundManager.setup().
soundManager.setup({
url: '/path/to/swfs/',
onready: function() {
// soundManager.createSound() etc. here
}
});
});
}
For a live demo, check out the deferred loading example.
Sound Options Object Format
Object Literal, JSON-style data passed to createSound()
and play()
Object Literal Format
Sounds can be created with instance-specific parameters in an object literal (JSON-style) format, where omitted parameters inherit default values as defined in soundManager.
soundManager.createSound({
id: 'mySound',
url: '/path/to/some.mp3',
autoLoad: true,
autoPlay: false,
onload: function() {
alert('The sound '+this.id+' loaded!');
},
volume: 50
});
This object can also be passed as an optional argument to the play
method, overriding options set at creation time.
For a full list of available options, see Sound Properties Object
"Use Responsibly"
Only you can prevent audio pollution?
A Word Of Vice
Not every button, link, element or paragraph on the web needs to zoom, move, change colour and be noisy, repetitive and annoying all at the same time. Use your own discretion!
Sites which automatically start playing background sound, and/or don't have volume or mute controls are the kind of things you should avoid building. As a developer, gentle reader, you may eventually find yourself in such a situation. Please do your part in enhancing the web with sound if you use SM2, while at the same time keeping it audibly usable. :)
Troubleshooting
Console-style messaging, useful for troubleshooting start-up and runtime issues.
SoundManager 2 Start-up and Debug Tools
This troubleshooting tool can come in handy for debugging SM2 start-up problems, when Flash support is required.
Flash options: Flash 8 (default), Flash 9 (normal) or Flash 9 + highPerformance + fastPolling modes.
-
OKFAILN/AUnknownSoundManager 2 start-up
soundManager onready() or ontimeout() events are ultimately called when start-up completes.
If you're seeing a failure, refer to the below for troubleshooting details for common causes.
-
OKErrorN/AUnknownFlash
Flash 8 or 9 may be required for SoundManager 2 to start, depending on HTML5 support. You are currently using [unknown].
-
OKErrorN/AUnknownFlash SWF
SoundManager 2 must load a flash movie before initialisation can proceed. If you have errors here, check that soundManager.url is correctly defined and that the URL being loaded is correct.
If the Flash movie URL is OK, Flash security or flash blockers are the likely cause. Check the section below.
-
OKErrorN/AUnknownFlash -> JS
Once the flash component of SM2 has loaded, it tries to make a call to Javascript-land. This is a common point of failure, for security reasons.
-
Have a flash blocker? Check that the SM2 flash movie (below) is loading and is not being blocked.
-
First time opening SM2 after downloading it? Is your browser URL at file:// or c:/path/ or otherwise not using HTTP? Flash security "whitelisting" is required to allow Flash + JS to work when offline, placing it in the "LocalTrusted" Flash security sandbox rather than "localWithFile".
Offline viewing: Adding a "trusted location" to the Flash Security Settings Panel
The Flash Player Global Security Settings Panel is a web-based control panel which allows you to configure Flash security. You will need to add the path of the SoundManager 2 project in order for it to work "offline" (ie., when viewing via file:// or c:/)
Show me how: Adding a "trusted location"
- Flash blockers (FlashBlock, "click to flash" etc.) preventing flash load and start-up - need whitelisting/"allow this domain" to work smoothly. If you suspect blocking is the issue, try the SoundManager 2 Flashblock demo.
- Online viewing (HTTP/S): Same-domain security rules apply to HTML + Flash content by default (crossdomain.xml/allowDomain() in .AS source required to override.)
See Flash debug output for more security error details.
Online viewing: Cross-domain security restrictions
HTML page on domain A loading .SWF from domain B: Flash security prevents JS + Flash when a cross-domain XML permission file is not available on domain B, and/or flash movie was not compiled with allowDomain('domainA') or allowDomain('*') - note that the SWF distributed with SM2 does not use this by default; try using the cross-domain version of the SWF, or compile your own which whitelists your own domain(s).
Flash Blockers
Browser extensions/add-ons like "FlashBlock" and "click to flash" can prevent the .SWF from loading, and this will mean SM2 will time-out and fail waiting for a response from Flash. For development, it's best to whitelist the domain(s) or the .SWF for SM2 to allow it to work.
Have a flash blocker installed? Want to test it? Try the SoundManager 2 Flashblock demo.
-
-
OKErrorN/AUnknownJS -> Flash
At this point, Javascript attempts to respond to Flash's initial outgoing Flash -> JS call, completing the test for JS/flash communication. If SM2 does not receive a response from flash, it will eventually fail.
Offline viewing conditions and cross-domain security rules will prevent Flash <-> JS communication. See the details of Flash -> JS for information.
Special Firefox Note: Some versions of Firefox (9.0 and newer?) may break JS/Flash in the file:// or offline case even when the path has been whitelisted in the Flash player security settings panel. IE, Chrome, Safari and Opera do not have this issue.
-
OKErrorN/AUnknownSound test
Here, a simple createSound() call is made to test SM2's actual operation. A sound should load and play provided SM2 was able to start successfully.
Flash detection code from Flash Detect (featureblend.com)
Flash Movie Debug Output
When soundManager.debugFlash = true
, Flash will write debug info as text to the flash movie. This can be helpful for troubleshooting Flash/JS issues when timeouts or security errors are involved which prevent Flash from talking to Javascript, potentially hiding useful debug information. A CSS class of flash_debug
will also be appended to the Flash #sm2-container
DIV element when enabled, if you wish to style it differently.
You can also specify ?debug=1 in the URL to the SWF, and it will write debug output. Try soundmanager2_debug.swf?debug=1, or soundmanager2_flash9_debug.swf?debug=1.
Live Debug Output
SoundManager 2 relies on Javascript and Flash communicating via ExternalInterface, and this is subject to a number of timing, loading and browser security conditions. Because of this complexity, debug information is essential for troubleshooting start-up, loading, initialization and error conditions between Flash and Javascript.
With debug mode enabled via debugMode = true
, SM2 can write helpful troubleshooting information to javascript console.log()
-style interfaces. Additionally, output can be written to an optional DIV element with the ID of "soundmanager-debug
".
If loading from the local filesystem (offline eg. file://, not over HTTP), Flash security is likely preventing SM2 from talking to Javascript. You will need to add this project's directory to the trusted locations in the Flash global security settings panel, or simply view this page over HTTP.
Below is a live example of debug output.
For more examples of live debug output, see the Basic Template, API demo and other demos in the top navigation.
Standalone version of troubleshooting tool
For debugging your development/production environment with this widget, see the troubleshooting subdirectory of the SoundManager 2 package.