SoundManager 2 makes it easier to play audio using JavaScript.

roblem: 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 is used as a fallback.

SoundManager 2 wraps and extends both the Flash and HTML Audio Sound APIs, providing a single, unified sound API to Javascript; the API is the same, whether HTML or Flash is ultimately used to play sound. (The flash portion is hidden, transparent to both developers and end users.)

Including SoundManager

The soundmanager2.js core can get down to 10 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 104 KB ~27 KB
Minified (Google Closure Compiler-munged, no comments or whitespace), debug-enabled version

<script src="soundmanager2-jsmin.js"></script>
Production, with debug code 46 KB ~15 KB
Build-script optimized, minified, no-debug version

<script src="soundmanager2-nodebug-jsmin.js"></script>
Production-optimized, debug code removed 32 KB 10 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.url = '/path/to/swf-files/';
soundManager.flashVersion = 9; // optional: shiny features (default = 8)
soundManager.useFlashBlock = false; // optionally, enable when you're ready to dive in
/*
 * read up on HTML5 audio support, if you're feeling adventurous.
 * iPad/iPhone and devices without flash installed will always attempt to use it.
*/
soundManager.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.

soundmanager2.js <-flash externalinterface magic-> soundmanager2.swf <- HTTP -> .mp3/.mp4

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() and onload() / onerror() 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.? });

SoundManager onload() + onerror()

A more traditional, less-flexible style of event handling is to assign single onload() / onerror() handlers. You should use onready() as it can be assigned at any time once soundManager has been defined, and is more robust.

soundManager.onload = function() { // SM2 is ready to go! makeSomeNoise(); // soundManager.createSound(), etc. } soundManager.onerror = function() { // SM2 could not start, no sound support, something broke etc. Handle gracefully. disableSoundInMyApp(); // for example }

Lazy-loading SM2 (deferred start-up): SM2_DEFER

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 edit soundmanager2.js and take out the SoundManager() constructor call at the bottom, or set the global variable SM2_DEFER = true which will have the same effect.

Example:

function lazy_load_sm2() { window.SM2_DEFER = true; // -- load soundmanager2.js via <script>, createElement('script') or XHR etc. -- // imaginary load_script() function .. load_script('/path/to/soundmanager2.js', function() { // once soundmanager2.js has loaded and has parsed, construct + init. window.soundManager = new SoundManager(); // Flash expects window.soundManager. soundManager.beginDelayedInit(); // start SM2 init. }); }

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.sID+' 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.

Flash options: Flash 8 (default), Flash 9 (normal) or Flash 9 + highPerformance + fastPolling modes.

  • OKSoundManager 2 start-up

  • OKFlash version 10.3.r183

  • OKFlash SWF

  • OKFlash -> JS

  • OKJS -> Flash

  • OKSound test

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 soundManager.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.

SMSound._onload(): “sm2TestSound” failed to load? – http://www.schillmania.com/projects/soundmanager2/demo/_mp3/mouseover.mp3
soundManager.onload() complete
soundManager::initComplete(): calling soundManager.onload()
SMSound.play(): “sm2TestSound” is starting to play
(Flash): auto-play allowed
SMSound.load(): http://www.schillmania.com/projects/soundmanager2/demo/_mp3/mouseover.mp3
SMSound.play(): Attempting to load “sm2TestSound”
SMSound() merged options: { id: sm2TestSound, url: http://www.schillmania.com/projects/soundmanager2/demo/_mp3/mouseover.mp3, autoLoad: false, stream: true, autoPlay: false, loops: 1, onbeforefinishtime: 5000, onjustbeforefinishtime: 200, multiShot: true, multiShotEvents: false, pan: 0, usePolicyFile: false, volume: 100 }
soundManager.createSound(): sm2TestSound (http://www.schillmania.com/projects/soundmanager2/demo/_mp3/mouseover.mp3)
— SoundManager 2 loaded (OK) —
(Flash): Enabling polling, 50 ms interval
Flash security sandbox type: remote
(Flash): JS to/from Flash OK
(Flash): SM2 SWF V2.97a.20110801 (AS2/Flash 8)
soundManager: Attempting to call Flash from JS..
soundManager::init()
soundManager::externalInterfaceOK() (~-1 ms)
soundManager::initMovie(): Waiting for ExternalInterface call from Flash..
soundManager::createMovie(): Trying to load ../../swf/soundmanager2_debug.swf
— SoundManager 2 V2.97a.20110801 (AS2/Flash 8) + HTML5 audio, normal polling, flash debug mode, flashBlock mode —
— SoundManager 2: HTML5 support tests (/^(probably|maybe)$/i): mp3: false (using flash), mp4: false (using flash), ogg: true, wav: true —

More sound, in more places

SoundManager 2 speaker logo

Despite being one of the senses, sound has largely been missing from the web due to inconsistent technology support. SoundManager 2 bridges this gap, making it easier to use audio across a growing variety of devices and platforms.

Complexity, reduced

Supporting HTML5 audio in modern browsers can be tedious, let alone “legacy” HTML4-based ones. With technology ranging from mobile Safari down to IE 6, there’s a lot of ground to cover.

SoundManager 2 gives you a simple but powerful API that supports both new and old, using HTML5 audio where supported and an invisible Flash fallback where needed. Ideally when using SoundManager 2, audio “just works.”

Less talk, more shiny

wheelsofsteel.net: Online turntable demo (screenshot)

Experimental demo: The Wheels Of Steel, a browser-based DJ turntable prototype. For the tech details, read An Ode To Turntables (in HTML.)

Inline demos using SoundManager 2

360┬░ UI ┬╗
coins.mp3    glass0.mp3    glass1.mp3

mp3 buttons ┬╗

The Fugitives – Graffiti Sex

“Graffiti Sex” compliments of The Fugitives, from┬áthe album “In Streetlight Communion.”

360┬░ + spectrum UI ┬╗

  • Armstrong Beat
  • Untitled Groove
  • BC Quail (HE-AAC)
  • Ghosts+Goblins Reconstructed (OGG)
  • A corked beer bottle (WAV)
muxtape-style UI ┬╗

Not only do you get the ginsu knife…

Even more demos and examples using the SoundManager 2 API…

  • Playable MP3 links
  • MPC sampler/drum machine
  • Basic animation + sound
  • Smashable christmas lights
  • Live API + code examples

Big features, small footprint

SoundManager 2 packs a full-featured API (100 KB of code) into as little as 10 KB over the wire. The source is provided in fully-commented, -no-debug and compiler-optimized “minified” versions appropriate for development and production use.

Technical details

HTML5 Audio Support (Beta-ish)

  • 100% Flash-free MP3 + MP4/AAC where supported. Works on iPad, iPhone (iOS4)
  • Seamless flash fallback for MP3/MP4 content, if needed
  • HTML5/Flash API switching is transparent, handled internally
  • WAV + OGG playback possible via HTML5, if supported
  • See useHTML5Audio for implementation details
  • Want more on the state of HTML5 audio? Read the article (12/2010), or watch the video talk + turntable demo (05/2011)
  • This browser’s <HTML5> vs. Flash support (best guess):mp3mp4<ogg><wav>
    (Flash is required for this browser to play MP3/MP4.)

Basic API Features (HTML5, Flash 8*)

  • Load, stop, play, pause, mute, seek, pan*, volume control from JavaScript
  • Events: onload(), whileloading(), whileplaying(), onfinish() and more
  • ID3V1 and ID3V2 tag support for MP3s (title, artist, genre etc.)*

Shiny Flash 9-only Features

  • RTMP / Flash Media Server streaming support (experimental) – see serverURL
  • MPEG-4 (AAC, HE-AAC, H.264) audio support
  • “MultiShot” play (layered/chorusing effects)
  • Waveform/frequency spectrum data
  • Peak (L/R channel volume) data
  • Audio buffering state/event handling

General Tech Stuff

  • Extensive API Documentation with examples and notes
  • console.log()-style debug output and troubleshooting tools
  • Community-based discussion/support

As Heard On TV The Internets

A few nifty places SoundManager 2 has been seen in use on the Wild World Web:

  • SoundCloud / The Cloud Player
  • last.fm
  • Opera Software ASA
  • 8tracks
  • Discogs
  • The Hype Machine
  • NON-STOP NYAN CAT!
  • Turntable.fm
  • Audiogalaxy

Download!

Get SoundManager 2

Playing MP3s with JavaScript

Play audio in one line, or get fancy with multiple options.

How To Play Audio Using SoundManager 2

Simple ID / URL method:

soundManager.play('mySound','/path/to/an.mp3');And, setting the volume:

soundManager.setVolume('mySound',50);More flexible method supporting option parameters as an object literal:

var mySound = soundManager.createSound({ id: 'someSound', url: '/path/to/some.mp3', volume: 50, onload: soundLoadedFunction }); mySound.play();

See API Demos

Using SM2 on your site

How to include SoundManager 2 from HTML, and some basic event handlers.

Include the SoundManager 2 core script, tell it where to look for the flash .SWF and provide an onready() callback.

<script src="/path/to/soundmanager2.js"></script> <script> soundManager.url = '/path/to/swfs/'; soundManager.onready(function() { // SM2 is ready to go!  // soundManager.createSound(...) calls can now be made, etc. }); </script>
); ga('send', 'pageview');