SoundManager 2: Download
Get SoundManager 2
Get the latest and greatest.
Download SoundManager 2
Latest changes: - HTML5 + iOS load fixes, Windows 8 App Store compatibility tweak, code pattern improvements. See revision history for details.
Download SoundManager 2.97a.20121104 or see on GitHub
Performance tip: SM2's code size varies from over 128 KB (commented, debug-enabled) down to 11 KB (optimized) over HTTP; check the pre-optimized builds for details.
Side reading + video talks, slides etc.
- Video, 02/2012: Web Audio: HTML5 + Flash (in a tree) (slides.) Updated HTML5 content, demos and SURVIVOR C64 game demo.
- Video, 12/2011: Adding Sound To HTML (slides.) Overview + updated content from 06/2011 talk.
- Video, 06/2011: The State Of HTML5 Audio
- Article: "Probably, Maybe, No": The State of HTML5 Audio.
Revision History
Latest changes and archived notes from bug fixes, API updates, feature development etc.
Revision History
A changelog of sorts.
-
V2.97a.20121104 - HTML5 + iOS load fixes, Windows 8 App Store compatibility tweak, code pattern improvements.
-
Bug fixes
-
Fix HTML5
unload()
->play()
case (re-use of same object without assigning new URL). -
More global (iOS) HTML5 object
unload()
/play()
re-use tweaks, improved handling of re-use and empty /load()
cases -
HTML5: Ensure
instanceOptions
are set afterplay()
call results inload()
. NotedinstanceOptions
not being set from withinwhileplaying()
. -
Fix call signature for Flash 8 load method, was tying
usePolicyFile
(enables remote crossdomain.xml request for ID3/waveform data on 3rd-party domains) to precence ofwhileloading()
due to driver error. Derp. :D -
Windows 8 Store Apps (IE 10/"MSAppHost" in UA) don't support Flash or ActiveX, except for (at time of writing), three special ActiveX controls. Thus,
new window.ActiveXObject('ShockwaveFlash.ShockwaveFlash')
seems to work without error. However, an error is thrown if an<object>
with a Flash ActiveX CLSID is appended to the DOM. http://msdn.microsoft.com/en-us/library/windows/apps/hh465143.aspx
-
-
Miscellaneous
-
Death to underscores! Removed legacy pattern of
var _foo = ...
for most private internals. -
Better
typeof x === 'undefined'
->x === undefined
pattern per newer jslint rules.
-
-
-
V2.97a.20120916 - Inline, deferred and lazy-load init improvements, HTML5 format / detection improvements, "re-use" load/play URL fix. (Download archived version)
-
API Updates
-
Init improvement: Don't fail if Flash URL is null in normal include + init case. Instead, show note in debug input and wait for
soundManager.setup()
withurl
param, then treat as delayed init case. Improved experience if including<script>
, then trying to dosetup()
after DOM Ready (common jQuery case). -
soundManager.setup({url:...})
+ lazy-loading (dynamically-loaded JS) case: Ifsetup()
given url parameter after DOMContentLoaded has fired, assume we should start right away. (Helps reduce need forbeginDelayedInit()
+ "just works" for most users) -
Don't init inline after
document.readyState === 'complete'
(improve lazy-loading case, wait for setup() with url: instead)
-
-
Bug fixes
-
Fix
'audio/mpeg'
canPlay()
checks, was incorrectly returning false due toaudio/mpeg; codecs="mp3"
working and preventingaudio/mpeg
from being checked. -
More paranoid
Audio()
handling for "bad" Opera (< 10) wherenew Audio()
would throw not_enough_arguments (always required URL). -
Safer HTML5 duration checks - null now assigned instead of undefined.
-
Improve durationEstimate under HTML5 during
whileloading()
. -
Flash 9/RTMP: Actually provide caption data to
oncaptiondata()
. -
Fix
SMSound.play({url:...})
"re-use" case where new URL wasn't being assigned + loaded right away, andSMSound.url
property was not being updated. -
Correct
load()
and play() with new URL parameter, so that subsequentplay()
call uses new URL (and not URL assigned with originalcreateSound()
call). -
Use seconds for
SMSound.buffered
(time ranges) whether HTML5 or Flash, since SM2 API uses seconds forsetPosition()
etc. -
Correct
play()
->pause()
->setPosition(0)
->play()
->pause()
case where the latter wasn't firing due to invalid state.
-
-
Miscellaneous
-
New Cassette Tape UI Prototype/demo (experimental).
-
Tweaked documentation layout for legibility. Webfont (deja vu sans mono) from dejavu-fonts.org for code examples.
-
Improved lazy-load / deferred example based on new
setup()
logic -
Added SMSound.buffered documentation
-
Added m4b extension as an mp4 format
-
Safer initial HTML5 support checks
-
-
-
V2.97a.20120624 - New
soundManager.setup()
method, numerous HTML5 improvements forcreateSound()
,load()
, progress and reuse cases, and minor flash audio bug fixes (Download archived version)-
API: New sugar-like stuff
-
New
soundManager.setup()
mixin-style method for assigning properties and common start-up callbacks. Collects top-level soundManager configuration properties and object collections -onready
,ontimeout
,defaultOptions
,flash9Options
andmovieStarOptions
- under a single method call.Upgrade / legacy note: This is a modern replacement for the direct property assignment method used in all previous versions - eg.,
soundManager.url = '/swfs/'
- the old method continues to work for legacy support, but you should migrate to using the new method as it's much cleaner. All included demos use the new method where applicable.New
soundManager.setup()
method examplesoundManager.setup({ // required url: '/path/to/swfs/', // optional flashVersion: 9, // convenience onready: function() { console.log('Ready to play sound!'); }, ontimeout: function() { console.log('SM2 start-up failed.'); }, // more custom parameters defaultOptions: { volume: 50 } });
See soundManager.setup() for details.
-
-
Bug fixes
-
Improve HTML5 audio load/playback reliability + stability on iOS, and for object reuse cases (
play()
->load({url: ...})
. Prior behaviour was making initial HTTP request when object was created (meta/preload, not necessarily loading entire file.) Request now only happens with preload/load/play-related calls. -
HTML5: Firefox seems to have changed when unloading HTML5 audio,
url = ''
now loads hosting page HTML (boo) instead ofnull
/ no request. Changed toabout:blank
like everyone else. Also fixed boolean logic onisMovieStar
assignment. -
Add
audio/mp3
and related MIME checks for flash, correct edge case whereplay({type:'audio/mp3'})
would use HTML5 whenpreferFlash = true
, due to seeming lack of Flash support for the MIME type. -
Fixed old Flash 8
onload()
edge case where loading from cache might return incorrectdidLoad: false
result - corrected by checking for a non-zero sound duration. -
Properly reset
SMSound.id3 = {}
with internal resetProperty and public methods likeload()
. -
Edge case fix: Don't attempt to remove flash unless reference exists (prevent false warning when
reboot()
called in 100% HTML5 mode.) -
Correct empty options JS error on internal
_setup_html5()
when reusing HTML5 audio object per V2.97a.20120527 bug report -
Fix minor false positive (undocumented error handler case) with HTML5
play()
falsely reporting 32-sound ceiling edge case and callingSMSound.onplayerror()
(if assigned) when using flashVersion = 9. Should only apply when flash 9 is being used for playback, and ceiling hit.
-
-
Miscellaneous
-
Finally assign + use
SMSound.id
(instead of sID), matchingcreateSound({id: 'foo'})
pattern; maintain legacy sID property (ancient behaviour, originally intended to avoid potential namespace conflicts many years ago - now silly and not a concern.) -
Improved handling of
whileloading()
vs. HTML5onload
(when using HTTP range/partial requests).HTML5
onload()
(now triggered via nativecanplaythrough
event) may fire early, followed by numerous HTML5progress
requests during playback as the audio object requests and buffers more audio ranges (eg., 0-10 seconds), eventually matching the total sound duration.Bytes loaded / total are not available, so bytesLoaded instead reflects a fraction of "duration loaded", between 0 and 1 as data is buffered in. Previously,
whileloading
events would not fire onceonload
had fired under HTML5. -
New (undocumented, for now)
buffered
array on SMSound objects; list of objects following the patternSMSound.buffered = [{ start: 0, end: 706 }]
representing loaded time ranges (somewhat similar to HTML5 TimeRanges spec, but using static properties instead of method calls with an index parameter.) Array will initially be empty, zero-length. This can be looped through to show overlays of "loaded" time fragments on progress bars, for example.SMSound
buffered
is updated duringwhileloading()
calls, where values are provided by the browser. For flash, will always be one item with{ start: 0, end: SMSound.duration }
assigned. Also stopped sending 1/1 values towhileplaying()
atonload()
, since HTML5 can fireonload()
(viacanplaythrough
) very early followed by many progress (whileloading()
) events.Support note: Not all browsers (eg., Safari 5.1.7) appear to provide buffer / TimeRanges data for HTML5 audio objects. At time of writing (06/2012), Firefox, Chrome Canary, IE 9 and Opera provide TimeRanges alongside progress events.
-
Upgraded demos to use to
soundManager.setup({...})
for most configuration cases (vs. settingsoundManager.url
,soundManager.defaultOptions.autoLoad
directly etc.) -
Warn if
soundManager.setup()
called withurl
orflashVersion
, and init has already fired (ie., flash options already set + movie already loaded) where changes will not take effect untilsoundManager.reboot()
. -
Assign top-level soundManager properties (eg.
soundManager.url
) fromsoundManager.setupOptions
atDOMReady
time; this allows legacysoundManager.url = ...
assignment to work, and helps to ensure legacy-style, directly-assigned top-level property values get written back tosoundManager.setupOptions
.
-
-
-
V2.97a.20120527 - Fix for
ontimeout()
regression. GWT/JSNI compatibility, slow connection and Safari "background tab" SWF load handling improvements (Download archived version)-
Bug fixes
-
Fix for
ontimeout()
regression seen when using lazy-loading / SM2_DEFER introduced with V2.97a.20120513; bug introduced when making edits to pass newer jslint rules regardingreturn
withinif...else
blocks. -
Replaced
instanceof Function
with "safer"typeof x === 'function'
foronready()
,ontimeout()
and related callback argument checks as GWT + JSNI was passing arguments that failed theinstanceof
check. (Related bug report.) -
Corrected another small regression for the
ontimeout()
->onready()
"recovery" edge case, ensuring "ready" does not fire after a timeout when init was unsuccessful.
-
-
Miscellaneous
-
Improved handling for special Safari page load case: When a new tab is opened that does not have focus, the Flash SWF does not load/init until the tab is brought to the foreground. SM2 now recognizes this special case and waits until
window.onfocus()
before attempting to do the JS/Flash part of init. Previously, it would fail with a timeout.Code written to originally handle Safari 3.1, which did not support
document.hasFocus()
, was modified and updated for this purpose. The Safari 3.1 logic previously deferred SM2's start-up in a similar fashion. (The old Safari 3.1mousemove()
focus-detection hack has been removed as Safari 4 has been out since mid-2009, and Safari 5 since mid-2010.) -
SM2 init process will now delay and retry if no Flash response, and SWF has loaded > 0 and < 100%. Timeout will now happen only after delay and when SWF has loaded 100%. Should help prevent first-visit (non-cached) failure on very slow or laggy connections.
-
Added note about potential Firefox regression: Offline JS/Flash start-up (viewing HTML pages via
file://
and/orc:/
and so forth), possibly not working as of Firefox 9 and newer (at time of writing, also up to and including Firefox 12), even despite special security whitelisting under Flash Player "trusted locations" preferences / control panel.After successful Flash -> JS call, SM2's "return" JS -> Flash call fails with unusual JS/Flash exception, "Error in ActionScript" error with no further detail. Offline viewing still works in other browsers.
-
-
-
V2.97a.20120513 - Fixes for Android 2.3 playback,
onPosition()
in HTML5, Flash 9 double-play edge case. Minor new Flash 9-specific features (Download archived version)-
Bug fixes
-
Android 2.3 playback fix (some sounds started only after 2+ play attempts due to Android not liking
load()
immediately followed byplay()
?) -
onPosition()
fix for HTML5 playback, items were mistakenly being removed. -
Fix RTMP stream duration reporting via
onmetadata()
(wrong value was being returned, previously.) -
Fix for Flash 9 double-play edge case found with
pause()
+setPosition()
calls. -
JSLINT validation per 04-15-2012 edition rules, mostly removal of multiple return statements within
if ... else
blocks and inverted loop tricks.
-
-
API updates
-
Enabled waveform/eq/spectrum data features for MovieStar (H.264/NetStream content.)
-
Added
oncaptiondata()
callback for caption data from Flash 9 (NetStream/RTMP-only, similar toonmetadata()
. Contributor: GitHub user karma.) -
Added
SMSound.onplayerror()
, presently for Flash 9 (non-MovieStar/NetStream) which can detect lack of available sound hardware or 32-channel ceiling as reasons for playback failure. -
Added
oncaptiondata()
callback for caption data from Flash 9 (NetStream/RTMP-only, similar toonmetadata()
.)
-
-
Miscellaneous
-
Scaling added to 360 UI (via GitHub user tomasdev)
-
-
-
V2.97a.20120318 - Minor updates.
from
/to
andonplay()
bug fixes,canPlayMIME()
andcanPlayLink()
Flash-specific corrections. (Download archived version)-
Bug fixes
-
Fix silly
undefined"soundID"
debug output message shown atSMSound.onload
(now saysSMSound._onload()
as previously.) -
soundManager.sounds = {}
instead of[]
on reboot (per bug report) -
Fix logic for calling
onplay()
, was always non-truthy. D'oh! -
Add missing
typeof
to fix html5 MIME check for playability tests -
Don't apply
width:auto
to SWF (invalid per HTML5, allegedly: Related patch.) -
Make
soundManager.canPlayMIME()
andcanPlayLink()
check flash support before returning (check afterontimeout()
was returning truthy when flash required under Firefox, for example, for'audio/mp3'
) -
Fix
play()
"from
" + "to
" sound sprite playback issue: In some cases, previously-fired "to" events were re-firing due to not being removed, because an equality check was comparing against a potential "to" value of a string rather than a number. (eg., 0-700 followed by 1500-2000; playback would stop in second case, saying 700 had been reached. (Related bug report.) -
Re-appeased the jslint gods, removed unused variables and two-statement reverse loop
(for i=x; i--;) { }
trickery.
-
-
Miscellaneous
-
The SoundManager project turned 10 years old, having originally launched in late 2001. Thanks for using it!
-
-
-
Older Release Info
For release and changelog history going back to 2010, see the archive page.