vendor/assets/javascripts/soundmanager2.js in soundmanager-rails-0.1.2 vs vendor/assets/javascripts/soundmanager2.js in soundmanager-rails-0.1.3
- old
+ new
@@ -6,19 +6,19 @@
*
* Copyright (c) 2007, Scott Schiller. All rights reserved.
* Code provided under the BSD License:
* http://schillmania.com/projects/soundmanager2/license.txt
*
- * V2.97a.20120916
+ * V2.97a.20130101
*/
-/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */
+/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
/*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */
/**
* About this file
- * ---------------
+ * -------------------------------------------------------------------------------------
* This is the fully-commented source version of the SoundManager 2 API,
* recommended for use during development and testing.
*
* See soundmanager2-nodebug-jsmin.js for an optimized build (~11KB with gzip.)
* http://schillmania.com/projects/soundmanager2/doc/getstarted/#basic-inclusion
@@ -28,12 +28,14 @@
* debug blocks which are removed in the -nodebug builds, further optimizing code size.
*
* Also, as you may note: Whoa, reliable cross-platform/device audio support is hard! ;)
*/
-(function(window) {
+(function(window, _undefined) {
+"use strict";
+
var soundManager = null;
/**
* The SoundManager constructor.
*
@@ -179,11 +181,11 @@
this.debugID = 'soundmanager-debug';
this.debugURLParam = /([#?&])debug=1/i;
// dynamic attributes
- this.versionNumber = 'V2.97a.20120916';
+ this.versionNumber = 'V2.97a.20130101';
this.version = null;
this.movieURL = null;
this.altURL = null;
this.swfLoaded = false;
this.enabled = false;
@@ -231,25 +233,10 @@
// </d>
};
/**
- * basic HTML5 Audio() support test
- * try...catch because of IE 9 "not implemented" nonsense
- * https://github.com/Modernizr/Modernizr/issues/224
- */
-
- this.hasHTML5 = (function() {
- try {
- // new Audio(null) for stupid Opera 9.64 case, which throws not_enough_arguments exception otherwise.
- return (typeof Audio !== 'undefined' && typeof (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== 'undefined');
- } catch(e) {
- return false;
- }
- }());
-
- /**
* format support (html5/flash)
* stores canPlayType() results based on audioFormats.
* eg. { mp3: boolean, mp4: boolean }
* treat as read-only.
*/
@@ -270,34 +257,32 @@
/**
* a few private internals (OK, a lot. :D)
*/
var SMSound,
- _s = this, _flash = null, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _setProperties, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _assign, _extraOptions, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _winOnLoad, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _swfCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _startTimer, _stopTimer, _timerExecute, _h5TimerCount = 0, _h5IntervalTimer = null, _parseURL,
- _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport,
- _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)),
- _mobileHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice),
- _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && !_ua.match(/silk/i) && _ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159
- _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && (typeof _doc.hasFocus === 'undefined' || !_doc.hasFocus())), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i,
- _emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)
- _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null),
- _http = (!_overHTTP ? 'http:/'+'/' : ''),
+ sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
+ needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages,
+ is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)),
+ mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
+ isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159
+ hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i,
+ emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)
+ overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
+ http = (!overHTTP ? 'http:/'+'/' : ''),
// mp3, mp4, aac etc.
- _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,
+ netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,
// Flash v9.0r115+ "moviestar" formats
- _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'],
- _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
+ netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'm4b', 'mp4v', '3gp', '3g2'],
+ netStreamPattern = new RegExp('\\.(' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // default mp3 set
// use altURL if not "online"
- this.useAltURL = !_overHTTP;
+ this.useAltURL = !overHTTP;
- this._global_a = null;
+ swfCSS = {
- _swfCSS = {
-
'swfBox': 'sm2-object-box',
'swfDefault': 'movieContainer',
'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error)
'swfTimedout': 'swf_timedout',
'swfLoaded': 'swf_loaded',
@@ -306,24 +291,25 @@
'highPerf': 'high_performance',
'flashDebug': 'flash_debug'
};
- if (_mobileHTML5) {
+ /**
+ * basic HTML5 Audio() support test
+ * try...catch because of IE 9 "not implemented" nonsense
+ * https://github.com/Modernizr/Modernizr/issues/224
+ */
- // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point.
- _s.useHTML5Audio = true;
- _s.preferFlash = false;
-
- if (_is_iDevice) {
- // by default, use global feature. iOS onfinish() -> next may fail otherwise.
- _s.ignoreFlash = true;
- _useGlobalHTML5Audio = true;
+ this.hasHTML5 = (function() {
+ try {
+ // new Audio(null) for stupid Opera 9.64 case, which throws not_enough_arguments exception otherwise.
+ return (Audio !== _undefined && (isOpera && opera !== _undefined && opera.version() < 10 ? new Audio(null) : new Audio()).canPlayType !== _undefined);
+ } catch(e) {
+ return false;
}
+ }());
- }
-
/**
* Public SoundManager API
* -----------------------
*/
@@ -334,50 +320,50 @@
* onready and ontimeout are also accepted parameters. call soundManager.setup() to see the full list.
*/
this.setup = function(options) {
- var noURL = (!_s.url);
+ var noURL = (!sm2.url);
// warn if flash options have already been applied
- if (typeof options !== 'undefined' && _didInit && _needsFlash && _s.ok() && (typeof options.flashVersion !== 'undefined' || typeof options.url !== 'undefined')) {
- _complain(_str('setupLate'));
+ if (options !== _undefined && didInit && needsFlash && sm2.ok() && (options.flashVersion !== _undefined || options.url !== _undefined || options.html5Test !== _undefined)) {
+ complain(str('setupLate'));
}
// TODO: defer: true?
- _assign(options);
+ assign(options);
// special case 1: "Late setup". SM2 loaded normally, but user didn't assign flash URL eg., setup({url:...}) before SM2 init. Treat as delayed init.
- if (noURL && _didDCLoaded && typeof options.url !== 'undefined') {
- _s.beginDelayedInit();
+ if (noURL && didDCLoaded && options.url !== _undefined) {
+ sm2.beginDelayedInit();
}
// special case 2: If lazy-loading SM2 (DOMContentLoaded has already happened) and user calls setup() with url: parameter, try to init ASAP.
- if (!_didDCLoaded && typeof options.url !== 'undefined' && _doc.readyState === 'complete') {
- setTimeout(_domContentLoaded, 1);
+ if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
+ setTimeout(domContentLoaded, 1);
}
- return _s;
+ return sm2;
};
this.ok = function() {
- return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5));
+ return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5));
};
this.supported = this.ok; // legacy
this.getMovie = function(smID) {
// safety net: some old browsers differ on SWF references, possibly related to ExternalInterface / flash version
- return _id(smID) || _doc[smID] || _win[smID];
+ return id(smID) || doc[smID] || window[smID];
};
/**
* Creates a SMSound sound object instance.
@@ -386,108 +372,105 @@
* @return {object} SMSound The new SMSound object.
*/
this.createSound = function(oOptions, _url) {
- var _cs, _cs_string, thisOptions = null, oSound = null, _tO = null;
+ var cs, cs_string, options, oSound = null;
// <d>
- _cs = _sm+'.createSound(): ';
- _cs_string = _cs + _str(!_didInit?'notReady':'notOK');
+ cs = sm + '.createSound(): ';
+ cs_string = cs + str(!didInit?'notReady':'notOK');
// </d>
- if (!_didInit || !_s.ok()) {
- _complain(_cs_string);
+ if (!didInit || !sm2.ok()) {
+ complain(cs_string);
return false;
}
- if (typeof _url !== 'undefined') {
+ if (_url !== _undefined) {
// function overloading in JS! :) ..assume simple createSound(id,url) use case
oOptions = {
'id': oOptions,
'url': _url
};
}
// inherit from defaultOptions
- thisOptions = _mixin(oOptions);
+ options = mixin(oOptions);
- thisOptions.url = _parseURL(thisOptions.url);
+ options.url = parseURL(options.url);
- // local shortcut
- _tO = thisOptions;
-
// <d>
- if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) {
- _s._wD(_cs + _str('badID', _tO.id), 2);
+ if (options.id.toString().charAt(0).match(/^[0-9]$/)) {
+ sm2._wD(cs + str('badID', options.id), 2);
}
- _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1);
+ sm2._wD(cs + options.id + ' (' + options.url + ')', 1);
// </d>
- if (_idCheck(_tO.id, true)) {
- _s._wD(_cs + _tO.id + ' exists', 1);
- return _s.sounds[_tO.id];
+ if (idCheck(options.id, true)) {
+ sm2._wD(cs + options.id + ' exists', 1);
+ return sm2.sounds[options.id];
}
function make() {
- thisOptions = _loopFix(thisOptions);
- _s.sounds[_tO.id] = new SMSound(_tO);
- _s.soundIDs.push(_tO.id);
- return _s.sounds[_tO.id];
+ options = loopFix(options);
+ sm2.sounds[options.id] = new SMSound(options);
+ sm2.soundIDs.push(options.id);
+ return sm2.sounds[options.id];
}
- if (_html5OK(_tO)) {
+ if (html5OK(options)) {
oSound = make();
- _s._wD('Creating sound '+_tO.id+', using HTML5');
- oSound._setup_html5(_tO);
+ sm2._wD(options.id + ': Using HTML5');
+ oSound._setup_html5(options);
} else {
- if (_fV > 8) {
- if (_tO.isMovieStar === null) {
+ if (fV > 8) {
+ if (options.isMovieStar === null) {
// attempt to detect MPEG-4 formats
- _tO.isMovieStar = !!(_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern));
+ options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern));
}
// <d>
- if (_tO.isMovieStar) {
- _s._wD(_cs + 'using MovieStar handling');
- if (_tO.loops > 1) {
+ if (options.isMovieStar) {
+ sm2._wD(cs + 'using MovieStar handling');
+ if (options.loops > 1) {
_wDS('noNSLoop');
}
}
// </d>
}
- _tO = _policyFix(_tO, _cs);
+ options = policyFix(options, cs);
oSound = make();
- if (_fV === 8) {
- _flash._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile);
+ if (fV === 8) {
+ flash._createSound(options.id, options.loops||1, options.usePolicyFile);
} else {
- _flash._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile);
- if (!_tO.serverURL) {
+ flash._createSound(options.id, options.url, options.usePeakData, options.useWaveformData, options.useEQData, options.isMovieStar, (options.isMovieStar?options.bufferTime:false), options.loops||1, options.serverURL, options.duration||null, options.autoPlay, true, options.autoLoad, options.usePolicyFile);
+ if (!options.serverURL) {
// We are connected immediately
oSound.connected = true;
- if (_tO.onconnect) {
- _tO.onconnect.apply(oSound);
+ if (options.onconnect) {
+ options.onconnect.apply(oSound);
}
}
}
- if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) {
+ if (!options.serverURL && (options.autoLoad || options.autoPlay)) {
// call load for non-rtmp streams
- oSound.load(_tO);
+ oSound.load(options);
}
}
// rtmp will play in onconnect
- if (!_tO.serverURL && _tO.autoPlay) {
+ if (!options.serverURL && options.autoPlay) {
oSound.play();
}
return oSound;
@@ -501,36 +484,36 @@
this.destroySound = function(sID, _bFromSound) {
// explicitly destroy a sound before normal page unload, etc.
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- var oS = _s.sounds[sID], i;
+ var oS = sm2.sounds[sID], i;
// Disable all callbacks while the sound is being destroyed
oS._iO = {};
oS.stop();
oS.unload();
- for (i = 0; i < _s.soundIDs.length; i++) {
- if (_s.soundIDs[i] === sID) {
- _s.soundIDs.splice(i, 1);
+ for (i = 0; i < sm2.soundIDs.length; i++) {
+ if (sm2.soundIDs[i] === sID) {
+ sm2.soundIDs.splice(i, 1);
break;
}
}
if (!_bFromSound) {
// ignore if being called from SMSound instance
oS.destruct(true);
}
oS = null;
- delete _s.sounds[sID];
+ delete sm2.sounds[sID];
return true;
};
@@ -541,14 +524,14 @@
* @param {object} oOptions Optional: Sound options
*/
this.load = function(sID, oOptions) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].load(oOptions);
+ return sm2.sounds[sID].load(oOptions);
};
/**
* Calls the unload() method of a SMSound object by ID.
@@ -556,14 +539,14 @@
* @param {string} sID The ID of the sound
*/
this.unload = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].unload();
+ return sm2.sounds[sID].unload();
};
/**
* Calls the onPosition() method of a SMSound object by ID.
@@ -575,14 +558,14 @@
* @return {SMSound} The SMSound object
*/
this.onPosition = function(sID, nPosition, oMethod, oScope) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].onposition(nPosition, oMethod, oScope);
+ return sm2.sounds[sID].onposition(nPosition, oMethod, oScope);
};
// legacy/backwards-compability: lower-case method name
this.onposition = this.onPosition;
@@ -596,14 +579,14 @@
* @return {SMSound} The SMSound object
*/
this.clearOnPosition = function(sID, nPosition, oMethod) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].clearOnPosition(nPosition, oMethod);
+ return sm2.sounds[sID].clearOnPosition(nPosition, oMethod);
};
/**
* Calls the play() method of a SMSound object by ID.
@@ -615,32 +598,32 @@
this.play = function(sID, oOptions) {
var result = false;
- if (!_didInit || !_s.ok()) {
- _complain(_sm+'.play(): ' + _str(!_didInit?'notReady':'notOK'));
+ if (!didInit || !sm2.ok()) {
+ complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK'));
return result;
}
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
if (!(oOptions instanceof Object)) {
// overloading use case: play('mySound','/path/to/some.mp3');
oOptions = {
url: oOptions
};
}
if (oOptions && oOptions.url) {
// overloading use case, create+play: .play('someID',{url:'/path/to.mp3'});
- _s._wD(_sm+'.play(): attempting to create "' + sID + '"', 1);
+ sm2._wD(sm + '.play(): attempting to create "' + sID + '"', 1);
oOptions.id = sID;
- result = _s.createSound(oOptions).play();
+ result = sm2.createSound(oOptions).play();
}
return result;
}
- return _s.sounds[sID].play(oOptions);
+ return sm2.sounds[sID].play(oOptions);
};
this.start = this.play; // just for convenience
@@ -652,14 +635,14 @@
* @return {SMSound} The SMSound object
*/
this.setPosition = function(sID, nMsecOffset) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].setPosition(nMsecOffset);
+ return sm2.sounds[sID].setPosition(nMsecOffset);
};
/**
* Calls the stop() method of a SMSound object by ID.
@@ -668,32 +651,32 @@
* @return {SMSound} The SMSound object
*/
this.stop = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- _s._wD(_sm+'.stop(' + sID + ')', 1);
- return _s.sounds[sID].stop();
+ sm2._wD(sm + '.stop(' + sID + ')', 1);
+ return sm2.sounds[sID].stop();
};
/**
* Stops all currently-playing sounds.
*/
this.stopAll = function() {
var oSound;
- _s._wD(_sm+'.stopAll()', 1);
+ sm2._wD(sm + '.stopAll()', 1);
- for (oSound in _s.sounds) {
- if (_s.sounds.hasOwnProperty(oSound)) {
+ for (oSound in sm2.sounds) {
+ if (sm2.sounds.hasOwnProperty(oSound)) {
// apply only to sound objects
- _s.sounds[oSound].stop();
+ sm2.sounds[oSound].stop();
}
}
};
@@ -704,26 +687,26 @@
* @return {SMSound} The SMSound object
*/
this.pause = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].pause();
+ return sm2.sounds[sID].pause();
};
/**
* Pauses all currently-playing sounds.
*/
this.pauseAll = function() {
var i;
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _s.sounds[_s.soundIDs[i]].pause();
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ sm2.sounds[sm2.soundIDs[i]].pause();
}
};
/**
@@ -733,26 +716,26 @@
* @return {SMSound} The SMSound object
*/
this.resume = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].resume();
+ return sm2.sounds[sID].resume();
};
/**
* Resumes all currently-paused sounds.
*/
this.resumeAll = function() {
var i;
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _s.sounds[_s.soundIDs[i]].resume();
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ sm2.sounds[sm2.soundIDs[i]].resume();
}
};
/**
@@ -762,14 +745,14 @@
* @return {SMSound} The SMSound object
*/
this.togglePause = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].togglePause();
+ return sm2.sounds[sID].togglePause();
};
/**
* Calls the setPan() method of a SMSound object by ID.
@@ -779,14 +762,14 @@
* @return {SMSound} The SMSound object
*/
this.setPan = function(sID, nPan) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].setPan(nPan);
+ return sm2.sounds[sID].setPan(nPan);
};
/**
* Calls the setVolume() method of a SMSound object by ID.
@@ -796,14 +779,14 @@
* @return {SMSound} The SMSound object
*/
this.setVolume = function(sID, nVol) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].setVolume(nVol);
+ return sm2.sounds[sID].setVolume(nVol);
};
/**
* Calls the mute() method of either a single SMSound object by ID, or all sound objects.
@@ -813,26 +796,30 @@
this.mute = function(sID) {
var i = 0;
- if (typeof sID !== 'string') {
+ if (sID instanceof String) {
sID = null;
}
if (!sID) {
- _s._wD(_sm+'.mute(): Muting all sounds');
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _s.sounds[_s.soundIDs[i]].mute();
+
+ sm2._wD(sm + '.mute(): Muting all sounds');
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ sm2.sounds[sm2.soundIDs[i]].mute();
}
- _s.muted = true;
+ sm2.muted = true;
+
} else {
- if (!_idCheck(sID)) {
+
+ if (!idCheck(sID)) {
return false;
}
- _s._wD(_sm+'.mute(): Muting "' + sID + '"');
- return _s.sounds[sID].mute();
+ sm2._wD(sm + '.mute(): Muting "' + sID + '"');
+ return sm2.sounds[sID].mute();
+
}
return true;
};
@@ -841,11 +828,11 @@
* Mutes all sounds.
*/
this.muteAll = function() {
- _s.mute();
+ sm2.mute();
};
/**
* Calls the unmute() method of either a single SMSound object by ID, or all sound objects.
@@ -855,29 +842,29 @@
this.unmute = function(sID) {
var i;
- if (typeof sID !== 'string') {
+ if (sID instanceof String) {
sID = null;
}
if (!sID) {
- _s._wD(_sm+'.unmute(): Unmuting all sounds');
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _s.sounds[_s.soundIDs[i]].unmute();
+ sm2._wD(sm + '.unmute(): Unmuting all sounds');
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ sm2.sounds[sm2.soundIDs[i]].unmute();
}
- _s.muted = false;
+ sm2.muted = false;
} else {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- _s._wD(_sm+'.unmute(): Unmuting "' + sID + '"');
- return _s.sounds[sID].unmute();
+ sm2._wD(sm + '.unmute(): Unmuting "' + sID + '"');
+ return sm2.sounds[sID].unmute();
}
return true;
@@ -887,11 +874,11 @@
* Unmutes all sounds.
*/
this.unmuteAll = function() {
- _s.unmute();
+ sm2.unmute();
};
/**
* Calls the toggleMute() method of a SMSound object by ID.
@@ -900,14 +887,14 @@
* @return {SMSound} The SMSound object
*/
this.toggleMute = function(sID) {
- if (!_idCheck(sID)) {
+ if (!idCheck(sID)) {
return false;
}
- return _s.sounds[sID].toggleMute();
+ return sm2.sounds[sID].toggleMute();
};
/**
* Retrieves the memory used by the flash plugin.
@@ -918,12 +905,12 @@
this.getMemoryUse = function() {
// flash-only
var ram = 0;
- if (_flash && _fV !== 8) {
- ram = parseInt(_flash._getMemoryUse(), 10);
+ if (flash && fV !== 8) {
+ ram = parseInt(flash._getMemoryUse(), 10);
}
return ram;
};
@@ -935,28 +922,28 @@
this.disable = function(bNoDisable) {
// destroy all functions
var i;
- if (typeof bNoDisable === 'undefined') {
+ if (bNoDisable === _undefined) {
bNoDisable = false;
}
- if (_disabled) {
+ if (disabled) {
return false;
}
- _disabled = true;
+ disabled = true;
_wDS('shutdown', 1);
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _disableObject(_s.sounds[_s.soundIDs[i]]);
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ disableObject(sm2.sounds[sm2.soundIDs[i]]);
}
// fire "complete", despite fail
- _initComplete(bNoDisable);
- _event.remove(_win, 'load', _initUserOnload);
+ initComplete(bNoDisable);
+ event.remove(window, 'load', initUserOnload);
return true;
};
@@ -966,17 +953,17 @@
this.canPlayMIME = function(sMIME) {
var result;
- if (_s.hasHTML5) {
- result = _html5CanPlay({type:sMIME});
+ if (sm2.hasHTML5) {
+ result = html5CanPlay({type:sMIME});
}
- if (!result && _needsFlash) {
+ if (!result && needsFlash) {
// if flash 9, test netStream (movieStar) types as well.
- result = (sMIME && _s.ok() ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null);
+ result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null);
}
return result;
};
@@ -990,16 +977,16 @@
this.canPlayURL = function(sURL) {
var result;
- if (_s.hasHTML5) {
- result = _html5CanPlay({url: sURL});
+ if (sm2.hasHTML5) {
+ result = html5CanPlay({url: sURL});
}
- if (!result && _needsFlash) {
- result = (sURL && _s.ok() ? !!(sURL.match(_s.filePattern)) : null);
+ if (!result && needsFlash) {
+ result = (sURL && sm2.ok() ? !!(sURL.match(sm2.filePattern)) : null);
}
return result;
};
@@ -1011,17 +998,17 @@
* @return {boolean} URL playability
*/
this.canPlayLink = function(oLink) {
- if (typeof oLink.type !== 'undefined' && oLink.type) {
- if (_s.canPlayMIME(oLink.type)) {
+ if (oLink.type !== _undefined && oLink.type) {
+ if (sm2.canPlayMIME(oLink.type)) {
return true;
}
}
- return _s.canPlayURL(oLink.href);
+ return sm2.canPlayURL(oLink.href);
};
/**
* Retrieves a SMSound object by ID.
@@ -1031,18 +1018,18 @@
*/
this.getSoundById = function(sID, _suppressDebug) {
if (!sID) {
- throw new Error(_sm+'.getSoundById(): sID is null/undefined');
+ throw new Error(sm + '.getSoundById(): sID is null/_undefined');
}
- var result = _s.sounds[sID];
+ var result = sm2.sounds[sID];
// <d>
if (!result && !_suppressDebug) {
- _s._wD('"' + sID + '" is an invalid sound ID.', 2);
+ sm2._wD('"' + sID + '" is an invalid sound ID.', 2);
}
// </d>
return result;
@@ -1061,27 +1048,27 @@
result = false;
if (typeof oMethod === 'function') {
// <d>
- if (_didInit) {
- _s._wD(_str('queue', sType));
+ if (didInit) {
+ sm2._wD(str('queue', sType));
}
// </d>
if (!oScope) {
- oScope = _win;
+ oScope = window;
}
- _addOnEvent(sType, oMethod, oScope);
- _processOnEvents();
+ addOnEvent(sType, oMethod, oScope);
+ processOnEvents();
result = true;
} else {
- throw _str('needFunction', sType);
+ throw str('needFunction', sType);
}
return result;
@@ -1100,27 +1087,27 @@
result = false;
if (typeof oMethod === 'function') {
// <d>
- if (_didInit) {
- _s._wD(_str('queue', sType));
+ if (didInit) {
+ sm2._wD(str('queue', sType));
}
// </d>
if (!oScope) {
- oScope = _win;
+ oScope = window;
}
- _addOnEvent(sType, oMethod, oScope);
- _processOnEvents({type:sType});
+ addOnEvent(sType, oMethod, oScope);
+ processOnEvents({type:sType});
result = true;
} else {
- throw _str('needFunction', sType);
+ throw str('needFunction', sType);
}
return result;
@@ -1129,89 +1116,89 @@
/**
* Writes console.log()-style debug output to a console or in-browser element.
* Applies when debugMode = true
*
* @param {string} sText The console message
- * @param {string} sType Optional: Log type of 'info', 'warn' or 'error'
- * @param {object} Optional: The scope to apply to the callback
+ * @param {object} sType Optional string: Log type of 'info', 'warn' or 'error', or object (to be dumped)
*/
- this._writeDebug = function(sText, sType, _bTimestamp) {
+ this._writeDebug = function(sText, sType) {
// pseudo-private console.log()-style output
// <d>
- var sDID = 'soundmanager-debug', o, oItem, sMethod;
+ var sDID = 'soundmanager-debug', o, oItem;
- if (!_s.debugMode) {
+ if (!sm2.debugMode) {
return false;
}
- if (typeof _bTimestamp !== 'undefined' && _bTimestamp) {
- sText = sText + ' | ' + new Date().getTime();
- }
-
- if (_hasConsole && _s.useConsole) {
- sMethod = _debugLevels[sType];
- if (typeof console[sMethod] !== 'undefined') {
- console[sMethod](sText);
+ if (hasConsole && sm2.useConsole) {
+ if (sType && typeof sType === 'object') {
+ // object passed; dump to console.
+ console.log(sText, sType);
+ } else if (debugLevels[sType] !== _undefined) {
+ console[debugLevels[sType]](sText);
} else {
console.log(sText);
}
- if (_s.consoleOnly) {
+ if (sm2.consoleOnly) {
return true;
}
}
- try {
+ o = id(sDID);
- o = _id(sDID);
+ if (!o) {
+ return false;
+ }
- if (!o) {
- return false;
- }
+ oItem = doc.createElement('div');
- oItem = _doc.createElement('div');
+ if (++wdCount % 2 === 0) {
+ oItem.className = 'sm2-alt';
+ }
- if (++_wdCount % 2 === 0) {
- oItem.className = 'sm2-alt';
- }
+ if (sType === _undefined) {
+ sType = 0;
+ } else {
+ sType = parseInt(sType, 10);
+ }
- if (typeof sType === 'undefined') {
- sType = 0;
- } else {
- sType = parseInt(sType, 10);
- }
+ oItem.appendChild(doc.createTextNode(sText));
- oItem.appendChild(_doc.createTextNode(sText));
-
- if (sType) {
- if (sType >= 2) {
- oItem.style.fontWeight = 'bold';
- }
- if (sType === 3) {
- oItem.style.color = '#ff3333';
- }
+ if (sType) {
+ if (sType >= 2) {
+ oItem.style.fontWeight = 'bold';
}
+ if (sType === 3) {
+ oItem.style.color = '#ff3333';
+ }
+ }
- // top-to-bottom
- // o.appendChild(oItem);
+ // top-to-bottom
+ // o.appendChild(oItem);
- // bottom-to-top
- o.insertBefore(oItem, o.firstChild);
+ // bottom-to-top
+ o.insertBefore(oItem, o.firstChild);
- } catch(e) {
- // oh well
- }
-
o = null;
// </d>
return true;
};
+ // <d>
+ // last-resort debugging option
+ if (wl.indexOf('sm2-debug=alert') !== -1) {
+ this._writeDebug = function(sText) {
+ window.alert(sText);
+ };
+ }
+ // </d>
+
// alias
this._wD = this._writeDebug;
/**
* Provides debug / state information on all SMSound objects.
@@ -1221,122 +1208,191 @@
// <d>
var i, j;
_wDS('currentObj', 1);
- for (i = 0, j = _s.soundIDs.length; i < j; i++) {
- _s.sounds[_s.soundIDs[i]]._debug();
+ for (i = 0, j = sm2.soundIDs.length; i < j; i++) {
+ sm2.sounds[sm2.soundIDs[i]]._debug();
}
// </d>
};
/**
* Restarts and re-initializes the SoundManager instance.
+ *
+ * @param {boolean} resetEvents Optional: When true, removes all registered onready and ontimeout event callbacks.
+ * @param {boolean} excludeInit Options: When true, does not call beginDelayedInit() (which would restart SM2).
+ * @return {object} soundManager The soundManager instance.
*/
- this.reboot = function() {
+ this.reboot = function(resetEvents, excludeInit) {
- // attempt to reset and init SM2
- _s._wD(_sm+'.reboot()');
+ // reset some (or all) state, and re-init unless otherwise specified.
// <d>
- if (_s.soundIDs.length) {
- _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...');
+ if (sm2.soundIDs.length) {
+ sm2._wD('Destroying ' + sm2.soundIDs.length + ' SMSound objects...');
}
// </d>
- var i, j;
+ var i, j, k;
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
- _s.sounds[_s.soundIDs[i]].destruct();
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
+ sm2.sounds[sm2.soundIDs[i]].destruct();
}
// trash ze flash
- if (_flash) {
+ if (flash) {
+
try {
- if (_isIE) {
- _oRemovedHTML = _flash.innerHTML;
+
+ if (isIE) {
+ oRemovedHTML = flash.innerHTML;
}
- _oRemoved = _flash.parentNode.removeChild(_flash);
- _s._wD('Flash movie removed.');
+
+ oRemoved = flash.parentNode.removeChild(flash);
+
+ _wDS('flRemoved');
+
} catch(e) {
- // uh-oh.
+
+ // Remove failed? May be due to flash blockers silently removing the SWF object/embed node from the DOM. Warn and continue.
+
_wDS('badRemove', 2);
+
}
+
}
// actually, force recreate of movie.
- _oRemovedHTML = _oRemoved = _needsFlash = null;
- _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false;
- _s.soundIDs = [];
- _s.sounds = {};
- _flash = null;
+ oRemovedHTML = oRemoved = needsFlash = flash = null;
- for (i in _on_queue) {
- if (_on_queue.hasOwnProperty(i)) {
- for (j = _on_queue[i].length-1; j >= 0; j--) {
- _on_queue[i][j].fired = false;
+ sm2.enabled = didDCLoaded = didInit = waitingForEI = initPending = didAppend = appendSuccess = disabled = useGlobalHTML5Audio = sm2.swfLoaded = false;
+
+ sm2.soundIDs = [];
+ sm2.sounds = {};
+
+ if (!resetEvents) {
+ // reset callbacks for onready, ontimeout etc. so that they will fire again on re-init
+ for (i in on_queue) {
+ if (on_queue.hasOwnProperty(i)) {
+ for (j = 0, k = on_queue[i].length; j < k; j++) {
+ on_queue[i][j].fired = false;
+ }
}
}
+ } else {
+ // remove all callbacks entirely
+ on_queue = [];
}
- _s._wD(_sm + ': Rebooting...');
- _win.setTimeout(_s.beginDelayedInit, 20);
+ // <d>
+ if (!excludeInit) {
+ sm2._wD(sm + ': Rebooting...');
+ }
+ // </d>
+ // reset HTML5 and flash canPlay test results
+
+ sm2.html5 = {
+ 'usingFlash': null
+ };
+
+ sm2.flash = {};
+
+ // reset device-specific HTML/flash mode switches
+
+ sm2.html5Only = false;
+ sm2.ignoreFlash = false;
+
+ window.setTimeout(function() {
+
+ preInit();
+
+ // by default, re-init
+
+ if (!excludeInit) {
+ sm2.beginDelayedInit();
+ }
+
+ }, 20);
+
+ return sm2;
+
};
+ this.reset = function() {
+
+ /**
+ * Shuts down and restores the SoundManager instance to its original loaded state, without an explicit reboot. All onready/ontimeout handlers are removed.
+ * After this call, SM2 may be re-initialized via soundManager.beginDelayedInit().
+ * @return {object} soundManager The soundManager instance.
+ */
+
+ _wDS('reset');
+ return sm2.reboot(true, true);
+
+ };
+
/**
* Undocumented: Determines the SM2 flash movie's load progress.
*
* @return {number or null} Percent loaded, or if invalid/unsupported, null.
*/
this.getMoviePercent = function() {
- // interesting note: flash/ExternalInterface bridge methods are not typeof "function" nor instanceof Function, but are still valid.
- return (_flash && typeof _flash.PercentLoaded !== 'undefined' ? _flash.PercentLoaded() : null);
+ /**
+ * Interesting syntax notes...
+ * Flash/ExternalInterface (ActiveX/NPAPI) bridge methods are not typeof "function" nor instanceof Function, but are still valid.
+ * Additionally, JSLint dislikes ('PercentLoaded' in flash)-style syntax and recommends hasOwnProperty(), which does not work in this case.
+ * Furthermore, using (flash && flash.PercentLoaded) causes IE to throw "object doesn't support this property or method".
+ * Thus, 'in' syntax must be used.
+ */
+ return (flash && 'PercentLoaded' in flash ? flash.PercentLoaded() : null); // Yes, JSLint. See nearby comment in source for explanation.
+
};
/**
* Additional helper for manually invoking SM2's init process after DOM Ready / window.onload().
*/
this.beginDelayedInit = function() {
- _windowLoaded = true;
- _domContentLoaded();
+ windowLoaded = true;
+ domContentLoaded();
setTimeout(function() {
- if (_initPending) {
+ if (initPending) {
return false;
}
- _createMovie();
- _initMovie();
- _initPending = true;
+ createMovie();
+ initMovie();
+ initPending = true;
return true;
}, 20);
- _delayWaitForEI();
+ delayWaitForEI();
};
/**
* Destroys the SoundManager instance and all SMSound instances.
*/
this.destruct = function() {
- _s._wD(_sm+'.destruct()');
- _s.disable(true);
+ sm2._wD(sm + '.destruct()');
+ sm2.disable(true);
};
/**
* SMSound() (sound object) constructor
@@ -1346,13 +1402,13 @@
* @return {SMSound} The new SMSound object
*/
SMSound = function(oOptions) {
- var _t = this, _resetProperties, _add_html5_events, _remove_html5_events, _stop_html5_timer, _start_html5_timer, _attachOnPosition, _onplay_called = false, _onPositionItems = [], _onPositionFired = 0, _detachOnPosition, _applyFromTo, _lastURL = null, _lastHTML5State;
+ var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State;
- _lastHTML5State = {
+ lastHTML5State = {
// tracks duration + position (time)
duration: null,
time: null
};
@@ -1360,11 +1416,11 @@
// legacy
this.sID = this.id;
this.url = oOptions.url;
- this.options = _mixin(oOptions);
+ this.options = mixin(oOptions);
// per-play-instance-specific options
this.instanceOptions = this.options;
// short alias
@@ -1392,172 +1448,140 @@
*/
this._debug = function() {
// <d>
- // pseudo-private console.log()-style output
-
- if (_s.debugMode) {
-
- var stuff = null, msg = [], sF, sfBracket, maxLength = 64;
-
- for (stuff in _t.options) {
- if (_t.options[stuff] !== null) {
- if (typeof _t.options[stuff] === 'function') {
- // handle functions specially
- sF = _t.options[stuff].toString();
- // normalize spaces
- sF = sF.replace(/\s\s+/g, ' ');
- sfBracket = sF.indexOf('{');
- msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }');
- } else {
- msg.push(' ' + stuff + ': ' + _t.options[stuff]);
- }
- }
- }
-
- _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}');
-
- }
+ sm2._wD(s.id + ': Merged options:', s.options);
// </d>
};
- // <d>
- this._debug();
- // </d>
-
/**
* Begins loading a sound per its *url*.
*
* @param {object} oOptions Optional: Sound options
* @return {SMSound} The SMSound object
*/
this.load = function(oOptions) {
- var oS = null, _iO;
+ var oSound = null, instanceOptions;
- if (typeof oOptions !== 'undefined') {
- _t._iO = _mixin(oOptions, _t.options);
- _t.instanceOptions = _t._iO;
+ if (oOptions !== _undefined) {
+ s._iO = mixin(oOptions, s.options);
} else {
- oOptions = _t.options;
- _t._iO = oOptions;
- _t.instanceOptions = _t._iO;
- if (_lastURL && _lastURL !== _t.url) {
+ oOptions = s.options;
+ s._iO = oOptions;
+ if (lastURL && lastURL !== s.url) {
_wDS('manURL');
- _t._iO.url = _t.url;
- _t.url = null;
+ s._iO.url = s.url;
+ s.url = null;
}
}
- if (!_t._iO.url) {
- _t._iO.url = _t.url;
+ if (!s._iO.url) {
+ s._iO.url = s.url;
}
- _t._iO.url = _parseURL(_t._iO.url);
+ s._iO.url = parseURL(s._iO.url);
- _s._wD('SMSound.load(): ' + _t._iO.url, 1);
+ // ensure we're in sync
+ s.instanceOptions = s._iO;
- if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) {
+ // local shortcut
+ instanceOptions = s._iO;
+
+ sm2._wD(s.id + ': load (' + instanceOptions.url + ')');
+
+ if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) {
_wDS('onURL', 1);
// if loaded and an onload() exists, fire immediately.
- if (_t.readyState === 3 && _t._iO.onload) {
+ if (s.readyState === 3 && instanceOptions.onload) {
// assume success based on truthy duration.
- _t._iO.onload.apply(_t, [(!!_t.duration)]);
+ instanceOptions.onload.apply(s, [(!!s.duration)]);
}
- return _t;
+ return s;
}
- // local shortcut
- _iO = _t._iO;
-
- // make a local copy of the old url before we re-assign it
- _lastURL = (_t.url && _t.url.toString ? _t.url.toString() : null);
-
// reset a few state properties
- _t.loaded = false;
- _t.readyState = 1;
- _t.playState = 0;
- _t.id3 = {};
+ s.loaded = false;
+ s.readyState = 1;
+ s.playState = 0;
+ s.id3 = {};
// TODO: If switching from HTML5 -> flash (or vice versa), stop currently-playing audio.
- if (_html5OK(_iO)) {
+ if (html5OK(instanceOptions)) {
- oS = _t._setup_html5(_iO);
+ oSound = s._setup_html5(instanceOptions);
- if (!oS._called_load) {
+ if (!oSound._called_load) {
- _s._wD(_h5+'load: '+_t.id);
+ s._html5_canplay = false;
- _t._html5_canplay = false;
-
// TODO: review called_load / html5_canplay logic
// if url provided directly to load(), assign it here.
- if (_t._a.src !== _iO.url) {
+ if (s.url !== instanceOptions.url) {
- _s._wD(_wDS('manURL') + ': ' + _iO.url);
+ sm2._wD(_wDS('manURL') + ': ' + instanceOptions.url);
- _t._a.src = _iO.url;
+ s._a.src = instanceOptions.url;
// TODO: review / re-apply all relevant options (volume, loop, onposition etc.)
// reset position for new URL
- _t.setPosition(0);
+ s.setPosition(0);
}
// given explicit load call, try to preload.
// early HTML5 implementation (non-standard)
- _t._a.autobuffer = 'auto';
+ s._a.autobuffer = 'auto';
// standard
- _t._a.preload = 'auto';
+ s._a.preload = 'auto';
- oS._called_load = true;
+ s._a._called_load = true;
- if (_iO.autoPlay) {
- _t.play();
+ if (instanceOptions.autoPlay) {
+ s.play();
}
} else {
- _s._wD(_h5+'ignoring request to load again: '+_t.id);
+ sm2._wD(s.id + ': Ignoring request to load again');
}
} else {
try {
- _t.isHTML5 = false;
- _t._iO = _policyFix(_loopFix(_iO));
+ s.isHTML5 = false;
+ s._iO = policyFix(loopFix(instanceOptions));
// re-assign local shortcut
- _iO = _t._iO;
- if (_fV === 8) {
- _flash._load(_t.id, _iO.url, _iO.stream, _iO.autoPlay, (_iO.whileloading?1:0), _iO.loops||1, _iO.usePolicyFile);
+ instanceOptions = s._iO;
+ if (fV === 8) {
+ flash._load(s.id, instanceOptions.url, instanceOptions.stream, instanceOptions.autoPlay, instanceOptions.usePolicyFile);
} else {
- _flash._load(_t.id, _iO.url, !!(_iO.stream), !!(_iO.autoPlay), _iO.loops||1, !!(_iO.autoLoad), _iO.usePolicyFile);
+ flash._load(s.id, instanceOptions.url, !!(instanceOptions.stream), !!(instanceOptions.autoPlay), instanceOptions.loops||1, !!(instanceOptions.autoLoad), instanceOptions.usePolicyFile);
}
} catch(e) {
_wDS('smError', 2);
- _debugTS('onload', false);
- _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});
-
+ debugTS('onload', false);
+ catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});
}
}
// after all of this, ensure sound url is up to date.
- _t.url = _iO.url;
+ s.url = instanceOptions.url;
- return _t;
+ return s;
};
/**
* Unloads a sound, canceling any open HTTP requests.
@@ -1569,82 +1593,82 @@
// Flash 8/AS2 can't "close" a stream - fake it by loading an empty URL
// Flash 9/AS3: Close stream, preventing further load
// HTML5: Most UAs will use empty URL
- if (_t.readyState !== 0) {
+ if (s.readyState !== 0) {
- _s._wD('SMSound.unload(): "' + _t.id + '"');
+ sm2._wD(s.id + ': unload()');
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
- if (_fV === 8) {
- _flash._unload(_t.id, _emptyURL);
+ if (fV === 8) {
+ flash._unload(s.id, emptyURL);
} else {
- _flash._unload(_t.id);
+ flash._unload(s.id);
}
} else {
- _stop_html5_timer();
+ stop_html5_timer();
- if (_t._a) {
+ if (s._a) {
- _t._a.pause();
- _html5Unload(_t._a, _emptyURL);
+ s._a.pause();
+ html5Unload(s._a, emptyURL);
- // reset local URL for next load / play call, too
- _t.url = _emptyURL;
+ // update empty URL, too
+ lastURL = emptyURL;
}
}
// reset load/status flags
- _resetProperties();
+ resetProperties();
}
- return _t;
+ return s;
};
/**
* Unloads and destroys a sound.
*/
this.destruct = function(_bFromSM) {
- _s._wD('SMSound.destruct(): "' + _t.id + '"');
+ sm2._wD(s.id + ': Destruct');
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
// kill sound within Flash
// Disable the onfailure handler
- _t._iO.onfailure = null;
- _flash._destroySound(_t.id);
+ s._iO.onfailure = null;
+ flash._destroySound(s.id);
} else {
- _stop_html5_timer();
+ stop_html5_timer();
- if (_t._a) {
- _t._a.pause();
- _html5Unload(_t._a);
- if (!_useGlobalHTML5Audio) {
- _remove_html5_events();
+ if (s._a) {
+ s._a.pause();
+ html5Unload(s._a);
+ if (!useGlobalHTML5Audio) {
+ remove_html5_events();
}
// break obvious circular reference
- _t._a._t = null;
- _t._a = null;
+ s._a._s = null;
+ s._a = null;
}
}
if (!_bFromSM) {
// ensure deletion from controller
- _s.destroySound(_t.id, true);
+ sm2.destroySound(s.id, true);
}
};
@@ -1659,110 +1683,113 @@
var fN, allowMulti, a, onready, startOK = true,
exit = null;
// <d>
- fN = 'SMSound.play(): ';
+ fN = s.id + ': play(): ';
// </d>
// default to true
- _updatePlayState = (typeof _updatePlayState === 'undefined' ? true : _updatePlayState);
+ _updatePlayState = (_updatePlayState === _undefined ? true : _updatePlayState);
if (!oOptions) {
oOptions = {};
}
// first, use local URL (if specified)
- if (_t.url) {
- _t._iO.url = _t.url;
+ if (s.url) {
+ s._iO.url = s.url;
}
// mix in any options defined at createSound()
- _t._iO = _mixin(_t._iO, _t.options);
+ s._iO = mixin(s._iO, s.options);
// mix in any options specific to this method
- _t._iO = _mixin(oOptions, _t._iO);
+ s._iO = mixin(oOptions, s._iO);
- _t._iO.url = _parseURL(_t._iO.url);
+ s._iO.url = parseURL(s._iO.url);
- _t.instanceOptions = _t._iO;
+ s.instanceOptions = s._iO;
// RTMP-only
- if (_t._iO.serverURL && !_t.connected) {
- if (!_t.getAutoPlay()) {
- _s._wD(fN+' Netstream not connected yet - setting autoPlay');
- _t.setAutoPlay(true);
+ if (s._iO.serverURL && !s.connected) {
+ if (!s.getAutoPlay()) {
+ sm2._wD(fN +' Netstream not connected yet - setting autoPlay');
+ s.setAutoPlay(true);
}
- // play will be called in _onconnect()
- return _t;
+ // play will be called in onconnect()
+ return s;
}
- if (_html5OK(_t._iO)) {
- _t._setup_html5(_t._iO);
- _start_html5_timer();
+ if (html5OK(s._iO)) {
+ s._setup_html5(s._iO);
+ start_html5_timer();
}
- if (_t.playState === 1 && !_t.paused) {
- allowMulti = _t._iO.multiShot;
+ if (s.playState === 1 && !s.paused) {
+ allowMulti = s._iO.multiShot;
if (!allowMulti) {
- _s._wD(fN + '"' + _t.id + '" already playing (one-shot)', 1);
- exit = _t;
+ sm2._wD(fN + 'Already playing (one-shot)', 1);
+ exit = s;
} else {
- _s._wD(fN + '"' + _t.id + '" already playing (multi-shot)', 1);
+ sm2._wD(fN + 'Already playing (multi-shot)', 1);
}
}
if (exit !== null) {
return exit;
}
// edge case: play() with explicit URL parameter
- if (oOptions.url && oOptions.url !== _t.url) {
+ if (oOptions.url && oOptions.url !== s.url) {
// load using merged options
- _t.load(_t._iO);
+ s.load(s._iO);
}
- if (!_t.loaded) {
+ if (!s.loaded) {
- if (_t.readyState === 0) {
+ if (s.readyState === 0) {
- _s._wD(fN + 'Attempting to load "' + _t.id + '"', 1);
+ sm2._wD(fN + 'Attempting to load');
// try to get this sound playing ASAP
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
// assign directly because setAutoPlay() increments the instanceCount
- _t._iO.autoPlay = true;
- _t.load(_t._iO);
+ s._iO.autoPlay = true;
+ s.load(s._iO);
} else {
// iOS needs this when recycling sounds, loading a new URL on an existing object.
- _t.load(_t._iO);
+ s.load(s._iO);
}
- } else if (_t.readyState === 2) {
+ // HTML5 hack - re-set instanceOptions?
+ s.instanceOptions = s._iO;
- _s._wD(fN + 'Could not load "' + _t.id + '" - exiting', 2);
- exit = _t;
+ } else if (s.readyState === 2) {
+ sm2._wD(fN + 'Could not load - exiting', 2);
+ exit = s;
+
} else {
- _s._wD(fN + '"' + _t.id + '" is loading - attempting to play..', 1);
+ sm2._wD(fN + 'Loading - attempting to play...');
}
} else {
- _s._wD(fN + '"' + _t.id + '"');
+ sm2._wD(fN);
}
if (exit !== null) {
return exit;
}
- if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) {
+ if (!s.isHTML5 && fV === 9 && s.position > 0 && s.position === s.duration) {
// flash 9 needs a position reset if play() is called while at the end of a sound.
- _s._wD(fN + '"' + _t.id + '": Sound at end, resetting to position:0');
+ sm2._wD(fN + 'Sound at end, resetting to position:0');
oOptions.position = 0;
}
/**
* Streams will pause when their buffer is full if they are being loaded.
@@ -1771,49 +1798,50 @@
* So only call resume() if the position is > 0.
* Another reason is because options like volume won't have been applied yet.
* For normal sounds, just resume.
*/
- if (_t.paused && _t.position >= 0 && (!_t._iO.serverURL || _t.position > 0)) {
+ if (s.paused && s.position >= 0 && (!s._iO.serverURL || s.position > 0)) {
// https://gist.github.com/37b17df75cc4d7a90bf6
- _s._wD(fN + '"' + _t.id + '" is resuming from paused state',1);
- _t.resume();
+ sm2._wD(fN + 'Resuming from paused state', 1);
+ s.resume();
} else {
- _t._iO = _mixin(oOptions, _t._iO);
+ s._iO = mixin(oOptions, s._iO);
// apply from/to parameters, if they exist (and not using RTMP)
- if (_t._iO.from !== null && _t._iO.to !== null && _t.instanceCount === 0 && _t.playState === 0 && !_t._iO.serverURL) {
+ if (s._iO.from !== null && s._iO.to !== null && s.instanceCount === 0 && s.playState === 0 && !s._iO.serverURL) {
onready = function() {
// sound "canplay" or onload()
// re-apply from/to to instance options, and start playback
- _t._iO = _mixin(oOptions, _t._iO);
- _t.play(_t._iO);
+ s._iO = mixin(oOptions, s._iO);
+ s.play(s._iO);
};
// HTML5 needs to at least have "canplay" fired before seeking.
- if (_t.isHTML5 && !_t._html5_canplay) {
+ if (s.isHTML5 && !s._html5_canplay) {
// this hasn't been loaded yet. load it first, and then do this again.
- _s._wD(fN+'Beginning load of "'+ _t.id+'" for from/to case');
+ sm2._wD(fN + 'Beginning load for from/to case');
- _t.load({
- _oncanplay: onready
+ s.load({
+ // TODO: was _oncanplay. Sounds wrong.
+ oncanplay: onready
});
exit = false;
- } else if (!_t.isHTML5 && !_t.loaded && (!_t.readyState || _t.readyState !== 2)) {
+ } else if (!s.isHTML5 && !s.loaded && (!s.readyState || s.readyState !== 2)) {
// to be safe, preload the whole thing in Flash.
- _s._wD(fN+'Preloading "'+ _t.id+'" for from/to case');
+ sm2._wD(fN + 'Preloading for from/to case');
- _t.load({
+ s.load({
onload: onready
});
exit = false;
@@ -1823,72 +1851,72 @@
return exit;
}
// otherwise, we're ready to go. re-apply local options, and continue
- _t._iO = _applyFromTo();
+ s._iO = applyFromTo();
}
- _s._wD(fN+'"'+ _t.id+'" is starting to play');
+ sm2._wD(fN + 'Starting to play');
- if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) {
- _t.instanceCount++;
+ if (!s.instanceCount || s._iO.multiShotEvents || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) {
+ s.instanceCount++;
}
// if first play and onposition parameters exist, apply them now
- if (_t._iO.onposition && _t.playState === 0) {
- _attachOnPosition(_t);
+ if (s._iO.onposition && s.playState === 0) {
+ attachOnPosition(s);
}
- _t.playState = 1;
- _t.paused = false;
+ s.playState = 1;
+ s.paused = false;
- _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position) ? _t._iO.position : 0);
+ s.position = (s._iO.position !== _undefined && !isNaN(s._iO.position) ? s._iO.position : 0);
- if (!_t.isHTML5) {
- _t._iO = _policyFix(_loopFix(_t._iO));
+ if (!s.isHTML5) {
+ s._iO = policyFix(loopFix(s._iO));
}
- if (_t._iO.onplay && _updatePlayState) {
- _t._iO.onplay.apply(_t);
- _onplay_called = true;
+ if (s._iO.onplay && _updatePlayState) {
+ s._iO.onplay.apply(s);
+ onplay_called = true;
}
- _t.setVolume(_t._iO.volume, true);
- _t.setPan(_t._iO.pan, true);
+ s.setVolume(s._iO.volume, true);
+ s.setPan(s._iO.pan, true);
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
- startOK = _flash._start(_t.id, _t._iO.loops || 1, (_fV === 9 ? _t._iO.position : _t._iO.position / 1000), _t._iO.multiShot);
+ startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s._iO.position : s._iO.position / 1000), s._iO.multiShot);
- if (_fV === 9 && !startOK) {
+ if (fV === 9 && !startOK) {
// edge case: no sound hardware, or 32-channel flash ceiling hit.
// applies only to Flash 9, non-NetStream/MovieStar sounds.
// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#play%28%29
- _s._wD(fN+ _t.id+': No sound hardware, or 32-sound ceiling hit');
- if (_t._iO.onplayerror) {
- _t._iO.onplayerror.apply(_t);
+ sm2._wD(fN + 'No sound hardware, or 32-sound ceiling hit');
+ if (s._iO.onplayerror) {
+ s._iO.onplayerror.apply(s);
}
}
} else {
- _start_html5_timer();
+ start_html5_timer();
- a = _t._setup_html5();
+ a = s._setup_html5();
- _t.setPosition(_t._iO.position);
+ s.setPosition(s._iO.position);
a.play();
}
}
- return _t;
+ return s;
};
// just for convenience
this.start = this.play;
@@ -1900,76 +1928,79 @@
* @return {SMSound} The SMSound object
*/
this.stop = function(bAll) {
- var _iO = _t._iO, _oP;
+ var instanceOptions = s._iO,
+ originalPosition;
- if (_t.playState === 1) {
+ if (s.playState === 1) {
- _t._onbufferchange(0);
- _t._resetOnPosition(0);
- _t.paused = false;
+ sm2._wD(s.id + ': stop()');
- if (!_t.isHTML5) {
- _t.playState = 0;
+ s._onbufferchange(0);
+ s._resetOnPosition(0);
+ s.paused = false;
+
+ if (!s.isHTML5) {
+ s.playState = 0;
}
// remove onPosition listeners, if any
- _detachOnPosition();
+ detachOnPosition();
// and "to" position, if set
- if (_iO.to) {
- _t.clearOnPosition(_iO.to);
+ if (instanceOptions.to) {
+ s.clearOnPosition(instanceOptions.to);
}
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
- _flash._stop(_t.id, bAll);
+ flash._stop(s.id, bAll);
// hack for netStream: just unload
- if (_iO.serverURL) {
- _t.unload();
+ if (instanceOptions.serverURL) {
+ s.unload();
}
} else {
- if (_t._a) {
+ if (s._a) {
- _oP = _t.position;
+ originalPosition = s.position;
// act like Flash, though
- _t.setPosition(0);
+ s.setPosition(0);
// hack: reflect old position for onstop() (also like Flash)
- _t.position = _oP;
+ s.position = originalPosition;
// html5 has no stop()
// NOTE: pausing means iOS requires interaction to resume.
- _t._a.pause();
+ s._a.pause();
- _t.playState = 0;
+ s.playState = 0;
// and update UI
- _t._onTimer();
+ s._onTimer();
- _stop_html5_timer();
+ stop_html5_timer();
}
}
- _t.instanceCount = 0;
- _t._iO = {};
+ s.instanceCount = 0;
+ s._iO = {};
- if (_iO.onstop) {
- _iO.onstop.apply(_t);
+ if (instanceOptions.onstop) {
+ instanceOptions.onstop.apply(s);
}
}
- return _t;
+ return s;
};
/**
* Undocumented/internal: Sets autoPlay for RTMP.
@@ -1977,20 +2008,20 @@
* @param {boolean} autoPlay state
*/
this.setAutoPlay = function(autoPlay) {
- _s._wD('sound '+_t.id+' turned autoplay ' + (autoPlay ? 'on' : 'off'));
- _t._iO.autoPlay = autoPlay;
+ sm2._wD(s.id + ': Autoplay turned ' + (autoPlay ? 'on' : 'off'));
+ s._iO.autoPlay = autoPlay;
- if (!_t.isHTML5) {
- _flash._setAutoPlay(_t.id, autoPlay);
+ if (!s.isHTML5) {
+ flash._setAutoPlay(s.id, autoPlay);
if (autoPlay) {
// only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP)
- if (!_t.instanceCount && _t.readyState === 1) {
- _t.instanceCount++;
- _s._wD('sound '+_t.id+' incremented instance count to '+_t.instanceCount);
+ if (!s.instanceCount && s.readyState === 1) {
+ s.instanceCount++;
+ sm2._wD(s.id + ': Incremented instance count to '+s.instanceCount);
}
}
}
};
@@ -2001,11 +2032,11 @@
* @return {boolean} The current autoPlay value
*/
this.getAutoPlay = function() {
- return _t._iO.autoPlay;
+ return s._iO.autoPlay;
};
/**
* Sets the position of a sound.
@@ -2014,70 +2045,70 @@
* @return {SMSound} The SMSound object
*/
this.setPosition = function(nMsecOffset) {
- if (typeof nMsecOffset === 'undefined') {
+ if (nMsecOffset === _undefined) {
nMsecOffset = 0;
}
var original_pos,
position, position1K,
// Use the duration from the instance options, if we don't have a track duration yet.
// position >= 0 and <= current available (loaded) duration
- offset = (_t.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0)));
+ offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0)));
- original_pos = _t.position;
- _t.position = offset;
- position1K = _t.position/1000;
- _t._resetOnPosition(_t.position);
- _t._iO.position = offset;
+ original_pos = s.position;
+ s.position = offset;
+ position1K = s.position/1000;
+ s._resetOnPosition(s.position);
+ s._iO.position = offset;
- if (!_t.isHTML5) {
+ if (!s.isHTML5) {
- position = (_fV === 9 ? _t.position : position1K);
- if (_t.readyState && _t.readyState !== 2) {
+ position = (fV === 9 ? s.position : position1K);
+ if (s.readyState && s.readyState !== 2) {
// if paused or not playing, will not resume (by playing)
- _flash._setPosition(_t.id, position, (_t.paused || !_t.playState), _t._iO.multiShot);
+ flash._setPosition(s.id, position, (s.paused || !s.playState), s._iO.multiShot);
}
- } else if (_t._a) {
+ } else if (s._a) {
// Set the position in the canplay handler if the sound is not ready yet
- if (_t._html5_canplay) {
- if (_t._a.currentTime !== position1K) {
+ if (s._html5_canplay) {
+ if (s._a.currentTime !== position1K) {
/**
* DOM/JS errors/exceptions to watch out for:
* if seek is beyond (loaded?) position, "DOM exception 11"
* "INDEX_SIZE_ERR": DOM exception 1
*/
- _s._wD('setPosition('+position1K+'): setting position');
+ sm2._wD(s.id + ': setPosition('+position1K+')');
try {
- _t._a.currentTime = position1K;
- if (_t.playState === 0 || _t.paused) {
+ s._a.currentTime = position1K;
+ if (s.playState === 0 || s.paused) {
// allow seek without auto-play/resume
- _t._a.pause();
+ s._a.pause();
}
} catch(e) {
- _s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2);
+ sm2._wD(s.id + ': setPosition(' + position1K + ') failed: ' + e.message, 2);
}
}
} else {
- _s._wD('setPosition('+position1K+'): delaying, sound not ready');
+ sm2._wD(s.id + ': setPosition(' + position1K + '): Cannot seek yet, sound not ready');
}
}
- if (_t.isHTML5) {
- if (_t.paused) {
+ if (s.isHTML5) {
+ if (s.paused) {
// if paused, refresh UI right away
// force update
- _t._onTimer(true);
+ s._onTimer(true);
}
}
- return _t;
+ return s;
};
/**
* Pauses sound playback.
@@ -2085,31 +2116,31 @@
* @return {SMSound} The SMSound object
*/
this.pause = function(_bCallFlash) {
- if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) {
- return _t;
+ if (s.paused || (s.playState === 0 && s.readyState !== 1)) {
+ return s;
}
- _s._wD('SMSound.pause()');
- _t.paused = true;
+ sm2._wD(s.id + ': pause()');
+ s.paused = true;
- if (!_t.isHTML5) {
- if (_bCallFlash || typeof _bCallFlash === 'undefined') {
- _flash._pause(_t.id, _t._iO.multiShot);
+ if (!s.isHTML5) {
+ if (_bCallFlash || _bCallFlash === _undefined) {
+ flash._pause(s.id, s._iO.multiShot);
}
} else {
- _t._setup_html5().pause();
- _stop_html5_timer();
+ s._setup_html5().pause();
+ stop_html5_timer();
}
- if (_t._iO.onpause) {
- _t._iO.onpause.apply(_t);
+ if (s._iO.onpause) {
+ s._iO.onpause.apply(s);
}
- return _t;
+ return s;
};
/**
* Resumes sound playback.
@@ -2125,40 +2156,40 @@
* first time, I think it's more appropriate to call onplay() rather than onresume().
*/
this.resume = function() {
- var _iO = _t._iO;
+ var instanceOptions = s._iO;
- if (!_t.paused) {
- return _t;
+ if (!s.paused) {
+ return s;
}
- _s._wD('SMSound.resume()');
- _t.paused = false;
- _t.playState = 1;
+ sm2._wD(s.id + ': resume()');
+ s.paused = false;
+ s.playState = 1;
- if (!_t.isHTML5) {
- if (_iO.isMovieStar && !_iO.serverURL) {
+ if (!s.isHTML5) {
+ if (instanceOptions.isMovieStar && !instanceOptions.serverURL) {
// Bizarre Webkit bug (Chrome reported via 8tracks.com dudes): AAC content paused for 30+ seconds(?) will not resume without a reposition.
- _t.setPosition(_t.position);
+ s.setPosition(s.position);
}
// flash method is toggle-based (pause/resume)
- _flash._pause(_t.id, _iO.multiShot);
+ flash._pause(s.id, instanceOptions.multiShot);
} else {
- _t._setup_html5().play();
- _start_html5_timer();
+ s._setup_html5().play();
+ start_html5_timer();
}
- if (!_onplay_called && _iO.onplay) {
- _iO.onplay.apply(_t);
- _onplay_called = true;
- } else if (_iO.onresume) {
- _iO.onresume.apply(_t);
+ if (!onplay_called && instanceOptions.onplay) {
+ instanceOptions.onplay.apply(s);
+ onplay_called = true;
+ } else if (instanceOptions.onresume) {
+ instanceOptions.onresume.apply(s);
}
- return _t;
+ return s;
};
/**
* Toggles sound playback.
@@ -2166,26 +2197,26 @@
* @return {SMSound} The SMSound object
*/
this.togglePause = function() {
- _s._wD('SMSound.togglePause()');
+ sm2._wD(s.id + ': togglePause()');
- if (_t.playState === 0) {
- _t.play({
- position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000)
+ if (s.playState === 0) {
+ s.play({
+ position: (fV === 9 && !s.isHTML5 ? s.position : s.position / 1000)
});
- return _t;
+ return s;
}
- if (_t.paused) {
- _t.resume();
+ if (s.paused) {
+ s.resume();
} else {
- _t.pause();
+ s.pause();
}
- return _t;
+ return s;
};
/**
* Sets the panning (L-R) effect.
@@ -2194,30 +2225,30 @@
* @return {SMSound} The SMSound object
*/
this.setPan = function(nPan, bInstanceOnly) {
- if (typeof nPan === 'undefined') {
+ if (nPan === _undefined) {
nPan = 0;
}
- if (typeof bInstanceOnly === 'undefined') {
+ if (bInstanceOnly === _undefined) {
bInstanceOnly = false;
}
- if (!_t.isHTML5) {
- _flash._setPan(_t.id, nPan);
+ if (!s.isHTML5) {
+ flash._setPan(s.id, nPan);
} // else { no HTML5 pan? }
- _t._iO.pan = nPan;
+ s._iO.pan = nPan;
if (!bInstanceOnly) {
- _t.pan = nPan;
- _t.options.pan = nPan;
+ s.pan = nPan;
+ s.options.pan = nPan;
}
- return _t;
+ return s;
};
/**
* Sets the volume.
@@ -2233,33 +2264,33 @@
* Hardware volume control overrides software, and volume
* will always return 1 per Apple docs. (iOS 4 + 5.)
* http://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/AddingSoundtoCanvasAnimations/AddingSoundtoCanvasAnimations.html
*/
- if (typeof nVol === 'undefined') {
+ if (nVol === _undefined) {
nVol = 100;
}
- if (typeof _bInstanceOnly === 'undefined') {
+ if (_bInstanceOnly === _undefined) {
_bInstanceOnly = false;
}
- if (!_t.isHTML5) {
- _flash._setVolume(_t.id, (_s.muted && !_t.muted) || _t.muted?0:nVol);
- } else if (_t._a) {
+ if (!s.isHTML5) {
+ flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol);
+ } else if (s._a) {
// valid range: 0-1
- _t._a.volume = Math.max(0, Math.min(1, nVol/100));
+ s._a.volume = Math.max(0, Math.min(1, nVol/100));
}
- _t._iO.volume = nVol;
+ s._iO.volume = nVol;
if (!_bInstanceOnly) {
- _t.volume = nVol;
- _t.options.volume = nVol;
+ s.volume = nVol;
+ s.options.volume = nVol;
}
- return _t;
+ return s;
};
/**
* Mutes the sound.
@@ -2267,19 +2298,19 @@
* @return {SMSound} The SMSound object
*/
this.mute = function() {
- _t.muted = true;
+ s.muted = true;
- if (!_t.isHTML5) {
- _flash._setVolume(_t.id, 0);
- } else if (_t._a) {
- _t._a.muted = true;
+ if (!s.isHTML5) {
+ flash._setVolume(s.id, 0);
+ } else if (s._a) {
+ s._a.muted = true;
}
- return _t;
+ return s;
};
/**
* Unmutes the sound.
@@ -2287,20 +2318,20 @@
* @return {SMSound} The SMSound object
*/
this.unmute = function() {
- _t.muted = false;
- var hasIO = (typeof _t._iO.volume !== 'undefined');
+ s.muted = false;
+ var hasIO = (s._iO.volume !== _undefined);
- if (!_t.isHTML5) {
- _flash._setVolume(_t.id, hasIO?_t._iO.volume:_t.options.volume);
- } else if (_t._a) {
- _t._a.muted = false;
+ if (!s.isHTML5) {
+ flash._setVolume(s.id, hasIO?s._iO.volume:s.options.volume);
+ } else if (s._a) {
+ s._a.muted = false;
}
- return _t;
+ return s;
};
/**
* Toggles the muted state of a sound.
@@ -2308,11 +2339,11 @@
* @return {SMSound} The SMSound object
*/
this.toggleMute = function() {
- return (_t.muted?_t.unmute():_t.mute());
+ return (s.muted?s.unmute():s.mute());
};
/**
* Registers a callback to be fired when a sound reaches a given position during playback.
@@ -2325,18 +2356,18 @@
this.onPosition = function(nPosition, oMethod, oScope) {
// TODO: basic dupe checking?
- _onPositionItems.push({
+ onPositionItems.push({
position: parseInt(nPosition, 10),
method: oMethod,
- scope: (typeof oScope !== 'undefined' ? oScope : _t),
+ scope: (oScope !== _undefined ? oScope : s),
fired: false
});
- return _t;
+ return s;
};
// legacy/backwards-compability: lower-case method name
this.onposition = this.onPosition;
@@ -2358,40 +2389,40 @@
if (isNaN(nPosition)) {
// safety check
return false;
}
- for (i=0; i < _onPositionItems.length; i++) {
+ for (i=0; i < onPositionItems.length; i++) {
- if (nPosition === _onPositionItems[i].position) {
+ if (nPosition === onPositionItems[i].position) {
// remove this item if no method was specified, or, if the method matches
- if (!oMethod || (oMethod === _onPositionItems[i].method)) {
- if (_onPositionItems[i].fired) {
+ if (!oMethod || (oMethod === onPositionItems[i].method)) {
+ if (onPositionItems[i].fired) {
// decrement "fired" counter, too
- _onPositionFired--;
+ onPositionFired--;
}
- _onPositionItems.splice(i, 1);
+ onPositionItems.splice(i, 1);
}
}
}
};
this._processOnPosition = function() {
- var i, item, j = _onPositionItems.length;
+ var i, item, j = onPositionItems.length;
- if (!j || !_t.playState || _onPositionFired >= j) {
+ if (!j || !s.playState || onPositionFired >= j) {
return false;
}
for (i=j-1; i >= 0; i--) {
- item = _onPositionItems[i];
- if (!item.fired && _t.position >= item.position) {
+ item = onPositionItems[i];
+ if (!item.fired && s.position >= item.position) {
item.fired = true;
- _onPositionFired++;
+ onPositionFired++;
item.method.apply(item.scope, [item.position]);
}
}
return true;
@@ -2399,21 +2430,21 @@
};
this._resetOnPosition = function(nPosition) {
// reset "fired" for items interested in this position
- var i, item, j = _onPositionItems.length;
+ var i, item, j = onPositionItems.length;
if (!j) {
return false;
}
for (i=j-1; i >= 0; i--) {
- item = _onPositionItems[i];
+ item = onPositionItems[i];
if (item.fired && nPosition <= item.position) {
item.fired = false;
- _onPositionFired--;
+ onPositionFired--;
}
}
return true;
@@ -2422,167 +2453,167 @@
/**
* SMSound() private internals
* --------------------------------
*/
- _applyFromTo = function() {
+ applyFromTo = function() {
- var _iO = _t._iO,
- f = _iO.from,
- t = _iO.to,
+ var instanceOptions = s._iO,
+ f = instanceOptions.from,
+ t = instanceOptions.to,
start, end;
end = function() {
// end has been reached.
- _s._wD(_t.id + ': "to" time of ' + t + ' reached.');
+ sm2._wD(s.id + ': "To" time of ' + t + ' reached.');
// detach listener
- _t.clearOnPosition(t, end);
+ s.clearOnPosition(t, end);
// stop should clear this, too
- _t.stop();
+ s.stop();
};
start = function() {
- _s._wD(_t.id + ': playing "from" ' + f);
+ sm2._wD(s.id + ': Playing "from" ' + f);
// add listener for end
if (t !== null && !isNaN(t)) {
- _t.onPosition(t, end);
+ s.onPosition(t, end);
}
};
if (f !== null && !isNaN(f)) {
// apply to instance options, guaranteeing correct start position.
- _iO.position = f;
+ instanceOptions.position = f;
// multiShot timing can't be tracked, so prevent that.
- _iO.multiShot = false;
+ instanceOptions.multiShot = false;
start();
}
// return updated instanceOptions including starting position
- return _iO;
+ return instanceOptions;
};
- _attachOnPosition = function() {
+ attachOnPosition = function() {
var item,
- op = _t._iO.onposition;
+ op = s._iO.onposition;
// attach onposition things, if any, now.
if (op) {
for (item in op) {
if (op.hasOwnProperty(item)) {
- _t.onPosition(parseInt(item, 10), op[item]);
+ s.onPosition(parseInt(item, 10), op[item]);
}
}
}
};
- _detachOnPosition = function() {
+ detachOnPosition = function() {
var item,
- op = _t._iO.onposition;
+ op = s._iO.onposition;
// detach any onposition()-style listeners.
if (op) {
for (item in op) {
if (op.hasOwnProperty(item)) {
- _t.clearOnPosition(parseInt(item, 10));
+ s.clearOnPosition(parseInt(item, 10));
}
}
}
};
- _start_html5_timer = function() {
+ start_html5_timer = function() {
- if (_t.isHTML5) {
- _startTimer(_t);
+ if (s.isHTML5) {
+ startTimer(s);
}
};
- _stop_html5_timer = function() {
+ stop_html5_timer = function() {
- if (_t.isHTML5) {
- _stopTimer(_t);
+ if (s.isHTML5) {
+ stopTimer(s);
}
};
- _resetProperties = function(retainPosition) {
+ resetProperties = function(retainPosition) {
if (!retainPosition) {
- _onPositionItems = [];
- _onPositionFired = 0;
+ onPositionItems = [];
+ onPositionFired = 0;
}
- _onplay_called = false;
+ onplay_called = false;
- _t._hasTimer = null;
- _t._a = null;
- _t._html5_canplay = false;
- _t.bytesLoaded = null;
- _t.bytesTotal = null;
- _t.duration = (_t._iO && _t._iO.duration ? _t._iO.duration : null);
- _t.durationEstimate = null;
- _t.buffered = [];
+ s._hasTimer = null;
+ s._a = null;
+ s._html5_canplay = false;
+ s.bytesLoaded = null;
+ s.bytesTotal = null;
+ s.duration = (s._iO && s._iO.duration ? s._iO.duration : null);
+ s.durationEstimate = null;
+ s.buffered = [];
// legacy: 1D array
- _t.eqData = [];
+ s.eqData = [];
- _t.eqData.left = [];
- _t.eqData.right = [];
+ s.eqData.left = [];
+ s.eqData.right = [];
- _t.failures = 0;
- _t.isBuffering = false;
- _t.instanceOptions = {};
- _t.instanceCount = 0;
- _t.loaded = false;
- _t.metadata = {};
+ s.failures = 0;
+ s.isBuffering = false;
+ s.instanceOptions = {};
+ s.instanceCount = 0;
+ s.loaded = false;
+ s.metadata = {};
// 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success
- _t.readyState = 0;
+ s.readyState = 0;
- _t.muted = false;
- _t.paused = false;
+ s.muted = false;
+ s.paused = false;
- _t.peakData = {
+ s.peakData = {
left: 0,
right: 0
};
- _t.waveformData = {
+ s.waveformData = {
left: [],
right: []
};
- _t.playState = 0;
- _t.position = null;
+ s.playState = 0;
+ s.position = null;
- _t.id3 = {};
+ s.id3 = {};
};
- _resetProperties();
+ resetProperties();
/**
* Pseudo-private SMSound internals
* --------------------------------
*/
@@ -2595,47 +2626,47 @@
* mimics flash and fires only when time/duration change, so as to be polling-friendly
*/
var duration, isNew = false, time, x = {};
- if (_t._hasTimer || bForce) {
+ if (s._hasTimer || bForce) {
// TODO: May not need to track readyState (1 = loading)
- if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) {
+ if (s._a && (bForce || ((s.playState > 0 || s.readyState === 1) && !s.paused))) {
- duration = _t._get_html5_duration();
+ duration = s._get_html5_duration();
- if (duration !== _lastHTML5State.duration) {
+ if (duration !== lastHTML5State.duration) {
- _lastHTML5State.duration = duration;
- _t.duration = duration;
+ lastHTML5State.duration = duration;
+ s.duration = duration;
isNew = true;
}
// TODO: investigate why this goes wack if not set/re-set each time.
- _t.durationEstimate = _t.duration;
+ s.durationEstimate = s.duration;
- time = (_t._a.currentTime * 1000 || 0);
+ time = (s._a.currentTime * 1000 || 0);
- if (time !== _lastHTML5State.time) {
+ if (time !== lastHTML5State.time) {
- _lastHTML5State.time = time;
+ lastHTML5State.time = time;
isNew = true;
}
if (isNew || bForce) {
- _t._whileplaying(time,x,x,x,x);
+ s._whileplaying(time,x,x,x,x);
}
}/* else {
- // _s._wD('_onTimer: Warn for "'+_t.id+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK'));
+ // sm2._wD('_onTimer: Warn for "'+s.id+'": '+(!s._a?'Could not find element. ':'')+(s.playState === 0?'playState bad, 0?':'playState = '+s.playState+', OK'));
return false;
}*/
@@ -2645,13 +2676,13 @@
};
this._get_html5_duration = function() {
- var _iO = _t._iO,
+ var instanceOptions = s._iO,
// if audio object exists, use its duration - else, instance option duration (if provided - it's a hack, really, and should be retired) OR null
- d = (_t._a && _t._a.duration ? _t._a.duration*1000 : (_iO && _iO.duration ? _iO.duration : null)),
+ d = (s._a && s._a.duration ? s._a.duration*1000 : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)),
result = (d && !isNaN(d) && d !== Infinity ? d : null);
return result;
};
@@ -2663,172 +2694,185 @@
* note that loop is either off or infinite under HTML5, unlike Flash which allows arbitrary loop counts to be specified.
*/
// <d>
if (!a.loop && nLoops > 1) {
- _s._wD('Note: Native HTML5 looping is infinite.');
+ sm2._wD('Note: Native HTML5 looping is infinite.', 1);
}
// </d>
a.loop = (nLoops > 1 ? 'loop' : '');
};
this._setup_html5 = function(oOptions) {
- var _iO = _mixin(_t._iO, oOptions), d = decodeURI,
- _a = _useGlobalHTML5Audio ? _s._global_a : _t._a,
- _dURL = d(_iO.url),
- _oldIO = (_a && _a._t ? _a._t.instanceOptions : null),
- result;
+ var instanceOptions = mixin(s._iO, oOptions), d = decodeURI,
+ a = useGlobalHTML5Audio ? globalHTML5Audio : s._a,
+ dURL = d(instanceOptions.url),
+ sameURL;
- if (_a) {
+ /**
+ * "First things first, I, Poppa..." (reset the previous state of the old sound, if playing)
+ * Fixes case with devices that can only play one sound at a time
+ * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state
+ */
- if (_a._t) {
+ if (useGlobalHTML5Audio) {
- if (!_useGlobalHTML5Audio && _dURL === d(_lastURL)) {
+ if (dURL === lastGlobalHTML5URL) {
+ // global HTML5 audio: re-use of URL
+ sameURL = true;
+ }
- // same url, ignore request
- result = _a;
+ } else if (dURL === lastURL) {
- } else if (_useGlobalHTML5Audio && _oldIO.url === _iO.url && (!_lastURL || (_lastURL === _oldIO.url))) {
+ // options URL is the same as the "last" URL, and we used (loaded) it
+ sameURL = true;
- // iOS-type reuse case
- result = _a;
+ }
- }
+ if (a) {
- if (result) {
+ if (a._s) {
- _t._apply_loop(_a, _iO.loops);
- return result;
+ if (useGlobalHTML5Audio) {
+ if (a._s && a._s.playState && !sameURL) {
+
+ // global HTML5 audio case, and loading a new URL. stop the currently-playing one.
+ a._s.stop();
+
+ }
+
+ } else if (!useGlobalHTML5Audio && dURL === d(lastURL)) {
+
+ // non-global HTML5 reuse case: same url, ignore request
+ s._apply_loop(a, instanceOptions.loops);
+
+ return a;
+
}
}
- _s._wD('setting URL on existing object: ' + _dURL + (_lastURL ? ', old URL: ' + _lastURL : ''));
+ if (!sameURL) {
- /**
- * "First things first, I, Poppa.." (reset the previous state of the old sound, if playing)
- * Fixes case with devices that can only play one sound at a time
- * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state
- */
+ // don't retain onPosition() stuff with new URL.
- if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) {
+ resetProperties(false);
- _a._t.stop();
+ // assign new HTML5 URL
- }
+ a.src = instanceOptions.url;
- // reset load/playstate, onPosition etc. if the URL is new.
- // somewhat-tricky object re-use vs. new SMSound object, old vs. new URL comparisons
- _resetProperties((_oldIO && _oldIO.url ? _iO.url === _oldIO.url : (_lastURL ? _lastURL === _iO.url : false)));
+ s.url = instanceOptions.url;
- _a.src = _iO.url;
- _t.url = _iO.url;
- _lastURL = _iO.url;
- _a._called_load = false;
+ lastURL = instanceOptions.url;
- } else {
+ lastGlobalHTML5URL = instanceOptions.url;
- _wDS('h5a');
+ a._called_load = false;
- if (_iO.autoLoad || _iO.autoPlay) {
+ }
- _t._a = new Audio(_iO.url);
+ } else {
+ if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
+
+ s._a = new Audio(instanceOptions.url);
+
} else {
// null for stupid Opera 9.64 case
- _t._a = (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio());
+ s._a = (isOpera && opera.version() < 10 ? new Audio(null) : new Audio());
}
// assign local reference
- _a = _t._a;
+ a = s._a;
- _a._called_load = false;
+ a._called_load = false;
- if (_useGlobalHTML5Audio) {
+ if (useGlobalHTML5Audio) {
- _s._global_a = _a;
+ globalHTML5Audio = a;
}
}
- _t.isHTML5 = true;
+ s.isHTML5 = true;
// store a ref on the track
- _t._a = _a;
+ s._a = a;
// store a ref on the audio
- _a._t = _t;
+ a._s = s;
- _add_html5_events();
+ add_html5_events();
- _t._apply_loop(_a, _iO.loops);
+ s._apply_loop(a, instanceOptions.loops);
- if (_iO.autoLoad || _iO.autoPlay) {
+ if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
- _t.load();
+ s.load();
} else {
// early HTML5 implementation (non-standard)
- _a.autobuffer = false;
+ a.autobuffer = false;
// standard ('none' is also an option.)
- _a.preload = 'auto';
+ a.preload = 'auto';
}
- return _a;
+ return a;
};
- _add_html5_events = function() {
+ add_html5_events = function() {
- if (_t._a._added_events) {
+ if (s._a._added_events) {
return false;
}
var f;
function add(oEvt, oFn, bCapture) {
- return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null;
+ return s._a ? s._a.addEventListener(oEvt, oFn, bCapture||false) : null;
}
- _t._a._added_events = true;
+ s._a._added_events = true;
- for (f in _html5_events) {
- if (_html5_events.hasOwnProperty(f)) {
- add(f, _html5_events[f]);
+ for (f in html5_events) {
+ if (html5_events.hasOwnProperty(f)) {
+ add(f, html5_events[f]);
}
}
return true;
};
- _remove_html5_events = function() {
+ remove_html5_events = function() {
// Remove event listeners
var f;
function remove(oEvt, oFn, bCapture) {
- return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null);
+ return (s._a ? s._a.removeEventListener(oEvt, oFn, bCapture||false) : null);
}
- _s._wD(_h5+'removing event listeners: '+_t.id);
- _t._a._added_events = false;
+ sm2._wD(s.id + ': Removing event listeners');
+ s._a._added_events = false;
- for (f in _html5_events) {
- if (_html5_events.hasOwnProperty(f)) {
- remove(f, _html5_events[f]);
+ for (f in html5_events) {
+ if (html5_events.hasOwnProperty(f)) {
+ remove(f, html5_events[f]);
}
}
};
@@ -2837,71 +2881,70 @@
* ------------------------------
*/
this._onload = function(nSuccess) {
-
var fN,
// check for duration to prevent false positives from flash 8 when loading from cache.
- loadOK = (!!(nSuccess) || (!_t.isHTML5 && _fV === 8 && _t.duration));
+ loadOK = !!nSuccess || (!s.isHTML5 && fV === 8 && s.duration);
// <d>
- fN = 'SMSound._onload(): ';
- _s._wD(fN + '"' + _t.id + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2));
- if (!loadOK && !_t.isHTML5) {
- if (_s.sandbox.noRemote === true) {
- _s._wD(fN + _str('noNet'), 1);
+ fN = s.id + ': ';
+ sm2._wD(fN + (loadOK ? 'onload()' : 'Failed to load? - ' + s.url), (loadOK ? 1 : 2));
+ if (!loadOK && !s.isHTML5) {
+ if (sm2.sandbox.noRemote === true) {
+ sm2._wD(fN + str('noNet'), 1);
}
- if (_s.sandbox.noLocal === true) {
- _s._wD(fN + _str('noLocal'), 1);
+ if (sm2.sandbox.noLocal === true) {
+ sm2._wD(fN + str('noLocal'), 1);
}
}
// </d>
- _t.loaded = loadOK;
- _t.readyState = loadOK?3:2;
- _t._onbufferchange(0);
+ s.loaded = loadOK;
+ s.readyState = loadOK?3:2;
+ s._onbufferchange(0);
- if (_t._iO.onload) {
- _t._iO.onload.apply(_t, [loadOK]);
+ if (s._iO.onload) {
+ s._iO.onload.apply(s, [loadOK]);
}
return true;
};
this._onbufferchange = function(nIsBuffering) {
- if (_t.playState === 0) {
+ if (s.playState === 0) {
// ignore if not playing
return false;
}
- if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) {
+ if ((nIsBuffering && s.isBuffering) || (!nIsBuffering && !s.isBuffering)) {
return false;
}
- _t.isBuffering = (nIsBuffering === 1);
- if (_t._iO.onbufferchange) {
- _s._wD('SMSound._onbufferchange(): ' + nIsBuffering);
- _t._iO.onbufferchange.apply(_t);
+ s.isBuffering = (nIsBuffering === 1);
+ if (s._iO.onbufferchange) {
+ sm2._wD(s.id + ': Buffer state change: ' + nIsBuffering);
+ s._iO.onbufferchange.apply(s);
}
return true;
};
/**
- * Notify Mobile Safari that user action is required
- * to continue playing / loading the audio file.
+ * Playback may have stopped due to buffering, or related reason.
+ * This state can be encountered on iOS < 6 when auto-play is blocked.
*/
this._onsuspend = function() {
- if (_t._iO.onsuspend) {
- _s._wD('SMSound._onsuspend()');
- _t._iO.onsuspend.apply(_t);
+ if (s._iO.onsuspend) {
+ sm2._wD(s.id + ': Playback suspended');
+ s._iO.onsuspend.apply(s);
}
return true;
};
@@ -2911,159 +2954,159 @@
* at this point we just recreate failed sounds rather than trying to reconnect
*/
this._onfailure = function(msg, level, code) {
- _t.failures++;
- _s._wD('SMSound._onfailure(): "'+_t.id+'" count '+_t.failures);
+ s.failures++;
+ sm2._wD(s.id + ': Failures = ' + s.failures);
- if (_t._iO.onfailure && _t.failures === 1) {
- _t._iO.onfailure(_t, msg, level, code);
+ if (s._iO.onfailure && s.failures === 1) {
+ s._iO.onfailure(s, msg, level, code);
} else {
- _s._wD('SMSound._onfailure(): ignoring');
+ sm2._wD(s.id + ': Ignoring failure');
}
};
this._onfinish = function() {
- // store local copy before it gets trashed..
- var _io_onfinish = _t._iO.onfinish;
+ // store local copy before it gets trashed...
+ var io_onfinish = s._iO.onfinish;
- _t._onbufferchange(0);
- _t._resetOnPosition(0);
+ s._onbufferchange(0);
+ s._resetOnPosition(0);
// reset some state items
- if (_t.instanceCount) {
+ if (s.instanceCount) {
- _t.instanceCount--;
+ s.instanceCount--;
- if (!_t.instanceCount) {
+ if (!s.instanceCount) {
// remove onPosition listeners, if any
- _detachOnPosition();
+ detachOnPosition();
// reset instance options
- _t.playState = 0;
- _t.paused = false;
- _t.instanceCount = 0;
- _t.instanceOptions = {};
- _t._iO = {};
- _stop_html5_timer();
+ s.playState = 0;
+ s.paused = false;
+ s.instanceCount = 0;
+ s.instanceOptions = {};
+ s._iO = {};
+ stop_html5_timer();
// reset position, too
- if (_t.isHTML5) {
- _t.position = 0;
+ if (s.isHTML5) {
+ s.position = 0;
}
}
- if (!_t.instanceCount || _t._iO.multiShotEvents) {
+ if (!s.instanceCount || s._iO.multiShotEvents) {
// fire onfinish for last, or every instance
- if (_io_onfinish) {
- _s._wD('SMSound._onfinish(): "' + _t.id + '"');
- _io_onfinish.apply(_t);
+ if (io_onfinish) {
+ sm2._wD(s.id + ': onfinish()');
+ io_onfinish.apply(s);
}
}
}
};
this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {
- var _iO = _t._iO;
+ var instanceOptions = s._iO;
- _t.bytesLoaded = nBytesLoaded;
- _t.bytesTotal = nBytesTotal;
- _t.duration = Math.floor(nDuration);
- _t.bufferLength = nBufferLength;
+ s.bytesLoaded = nBytesLoaded;
+ s.bytesTotal = nBytesTotal;
+ s.duration = Math.floor(nDuration);
+ s.bufferLength = nBufferLength;
- if (!_t.isHTML5 && !_iO.isMovieStar) {
+ if (!s.isHTML5 && !instanceOptions.isMovieStar) {
- if (_iO.duration) {
+ if (instanceOptions.duration) {
// use duration from options, if specified and larger. nobody should be specifying duration in options, actually, and it should be retired.
- _t.durationEstimate = (_t.duration > _iO.duration) ? _t.duration : _iO.duration;
+ s.durationEstimate = (s.duration > instanceOptions.duration) ? s.duration : instanceOptions.duration;
} else {
- _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);
+ s.durationEstimate = parseInt((s.bytesTotal / s.bytesLoaded) * s.duration, 10);
}
} else {
- _t.durationEstimate = _t.duration;
+ s.durationEstimate = s.duration;
}
// for flash, reflect sequential-load-style buffering
- if (!_t.isHTML5) {
- _t.buffered = [{
+ if (!s.isHTML5) {
+ s.buffered = [{
'start': 0,
- 'end': _t.duration
+ 'end': s.duration
}];
}
// allow whileloading to fire even if "load" fired under HTML5, due to HTTP range/partials
- if ((_t.readyState !== 3 || _t.isHTML5) && _iO.whileloading) {
- _iO.whileloading.apply(_t);
+ if ((s.readyState !== 3 || s.isHTML5) && instanceOptions.whileloading) {
+ instanceOptions.whileloading.apply(s);
}
};
this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {
- var _iO = _t._iO,
+ var instanceOptions = s._iO,
eqLeft;
if (isNaN(nPosition) || nPosition === null) {
// flash safety net
return false;
}
// Safari HTML5 play() may return small -ve values when starting from position: 0, eg. -50.120396875. Unexpected/invalid per W3, I think. Normalize to 0.
- _t.position = Math.max(0, nPosition);
+ s.position = Math.max(0, nPosition);
- _t._processOnPosition();
+ s._processOnPosition();
- if (!_t.isHTML5 && _fV > 8) {
+ if (!s.isHTML5 && fV > 8) {
- if (_iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) {
- _t.peakData = {
+ if (instanceOptions.usePeakData && oPeakData !== _undefined && oPeakData) {
+ s.peakData = {
left: oPeakData.leftPeak,
right: oPeakData.rightPeak
};
}
- if (_iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) {
- _t.waveformData = {
+ if (instanceOptions.useWaveformData && oWaveformDataLeft !== _undefined && oWaveformDataLeft) {
+ s.waveformData = {
left: oWaveformDataLeft.split(','),
right: oWaveformDataRight.split(',')
};
}
- if (_iO.useEQData) {
- if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) {
+ if (instanceOptions.useEQData) {
+ if (oEQData !== _undefined && oEQData && oEQData.leftEQ) {
eqLeft = oEQData.leftEQ.split(',');
- _t.eqData = eqLeft;
- _t.eqData.left = eqLeft;
- if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) {
- _t.eqData.right = oEQData.rightEQ.split(',');
+ s.eqData = eqLeft;
+ s.eqData.left = eqLeft;
+ if (oEQData.rightEQ !== _undefined && oEQData.rightEQ) {
+ s.eqData.right = oEQData.rightEQ.split(',');
}
}
}
}
- if (_t.playState === 1) {
+ if (s.playState === 1) {
// special case/hack: ensure buffering is false if loading from cache (and not yet started)
- if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) {
- _t._onbufferchange(0);
+ if (!s.isHTML5 && fV === 8 && !s.position && s.isBuffering) {
+ s._onbufferchange(0);
}
- if (_iO.whileplaying) {
+ if (instanceOptions.whileplaying) {
// flash may call after actual finish
- _iO.whileplaying.apply(_t);
+ instanceOptions.whileplaying.apply(s);
}
}
return true;
@@ -3076,19 +3119,19 @@
* internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
*
* @param {object} oData
*/
- _s._wD('SMSound._oncaptiondata(): "' + this.id + '" caption data received.');
+ sm2._wD(s.id + ': Caption data received.');
- _t.captiondata = oData;
+ s.captiondata = oData;
- if (_t._iO.oncaptiondata) {
- _t._iO.oncaptiondata.apply(_t, [oData]);
+ if (s._iO.oncaptiondata) {
+ s._iO.oncaptiondata.apply(s, [oData]);
}
- };
+ };
this._onmetadata = function(oMDProps, oMDData) {
/**
* internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
@@ -3096,24 +3139,24 @@
*
* @param {array} oMDProps (names)
* @param {array} oMDData (values)
*/
- _s._wD('SMSound._onmetadata(): "' + this.id + '" metadata received.');
+ sm2._wD(s.id + ': Metadata received.');
var oData = {}, i, j;
for (i = 0, j = oMDProps.length; i < j; i++) {
oData[oMDProps[i]] = oMDData[i];
}
- _t.metadata = oData;
+ s.metadata = oData;
- if (_t._iO.onmetadata) {
- _t._iO.onmetadata.apply(_t);
+ if (s._iO.onmetadata) {
+ s._iO.onmetadata.apply(s);
}
- };
+ };
this._onid3 = function(oID3Props, oID3Data) {
/**
* internal: flash 8 + flash 9 ID3 feature
@@ -3121,107 +3164,111 @@
*
* @param {array} oID3Props (names)
* @param {array} oID3Data (values)
*/
- _s._wD('SMSound._onid3(): "' + this.id + '" ID3 data received.');
+ sm2._wD(s.id + ': ID3 data received.');
var oData = [], i, j;
for (i = 0, j = oID3Props.length; i < j; i++) {
oData[oID3Props[i]] = oID3Data[i];
}
- _t.id3 = _mixin(_t.id3, oData);
+ s.id3 = mixin(s.id3, oData);
- if (_t._iO.onid3) {
- _t._iO.onid3.apply(_t);
+ if (s._iO.onid3) {
+ s._iO.onid3.apply(s);
}
};
// flash/RTMP-only
this._onconnect = function(bSuccess) {
bSuccess = (bSuccess === 1);
- _s._wD('SMSound._onconnect(): "'+_t.id+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2));
- _t.connected = bSuccess;
+ sm2._wD(s.id + ': ' + (bSuccess ? 'Connected.' : 'Failed to connect? - ' + s.url), (bSuccess ? 1 : 2));
+ s.connected = bSuccess;
if (bSuccess) {
- _t.failures = 0;
+ s.failures = 0;
- if (_idCheck(_t.id)) {
- if (_t.getAutoPlay()) {
+ if (idCheck(s.id)) {
+ if (s.getAutoPlay()) {
// only update the play state if auto playing
- _t.play(undefined, _t.getAutoPlay());
- } else if (_t._iO.autoLoad) {
- _t.load();
+ s.play(_undefined, s.getAutoPlay());
+ } else if (s._iO.autoLoad) {
+ s.load();
}
}
- if (_t._iO.onconnect) {
- _t._iO.onconnect.apply(_t, [bSuccess]);
+ if (s._iO.onconnect) {
+ s._iO.onconnect.apply(s, [bSuccess]);
}
}
};
this._ondataerror = function(sError) {
// flash 9 wave/eq data handler
// hack: called at start, and end from flash at/after onfinish()
- if (_t.playState > 0) {
- _s._wD('SMSound._ondataerror(): ' + sError);
- if (_t._iO.ondataerror) {
- _t._iO.ondataerror.apply(_t);
+ if (s.playState > 0) {
+ sm2._wD(s.id + ': Data error: ' + sError);
+ if (s._iO.ondataerror) {
+ s._iO.ondataerror.apply(s);
}
}
};
+ // <d>
+ this._debug();
+ // </d>
+
}; // SMSound()
/**
* Private SoundManager internals
* ------------------------------
*/
- _getDocument = function() {
+ getDocument = function() {
- return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]);
+ return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]);
};
- _id = function(sID) {
+ id = function(sID) {
- return _doc.getElementById(sID);
+ return doc.getElementById(sID);
};
- _mixin = function(oMain, oAdd) {
+ mixin = function(oMain, oAdd) {
// non-destructive merge
var o1 = (oMain || {}), o2, o;
// if unspecified, o2 is the default options object
- o2 = (typeof oAdd === 'undefined' ? _s.defaultOptions : oAdd);
+ o2 = (oAdd === _undefined ? sm2.defaultOptions : oAdd);
for (o in o2) {
- if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') {
+ if (o2.hasOwnProperty(o) && o1[o] === _undefined) {
if (typeof o2[o] !== 'object' || o2[o] === null) {
// assign directly
o1[o] = o2[o];
} else {
// recurse through o2
- o1[o] = _mixin(o1[o], o2[o]);
+ o1[o] = mixin(o1[o], o2[o]);
}
}
@@ -3231,36 +3278,36 @@
};
// additional soundManager properties that soundManager.setup() will accept
- _extraOptions = {
+ extraOptions = {
'onready': 1,
'ontimeout': 1,
'defaultOptions': 1,
'flash9Options': 1,
'movieStarOptions': 1
};
- _assign = function(o, oParent) {
+ assign = function(o, oParent) {
/**
* recursive assignment of properties, soundManager.setup() helper
* allows property assignment based on whitelist
*/
var i,
result = true,
- hasParent = (typeof oParent !== 'undefined'),
- setupOptions = _s.setupOptions,
- extraOptions = _extraOptions;
+ hasParent = (oParent !== _undefined),
+ setupOptions = sm2.setupOptions,
+ bonusOptions = extraOptions;
// <d>
// if soundManager.setup() called, show accepted parameters.
- if (typeof o === 'undefined') {
+ if (o === _undefined) {
result = [];
for (i in setupOptions) {
@@ -3268,19 +3315,19 @@
result.push(i);
}
}
- for (i in extraOptions) {
+ for (i in bonusOptions) {
- if (extraOptions.hasOwnProperty(i)) {
+ if (bonusOptions.hasOwnProperty(i)) {
- if (typeof _s[i] === 'object') {
+ if (typeof sm2[i] === 'object') {
result.push(i+': {...}');
- } else if (_s[i] instanceof Function) {
+ } else if (sm2[i] instanceof Function) {
result.push(i+': function() {...}');
} else {
@@ -3290,11 +3337,11 @@
}
}
- _s._wD(_str('setup', result.join(', ')));
+ sm2._wD(str('setup', result.join(', ')));
return false;
}
@@ -3304,70 +3351,70 @@
if (o.hasOwnProperty(i)) {
// if not an {object} we want to recurse through...
- if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array) {
+ if (typeof o[i] !== 'object' || o[i] === null || o[i] instanceof Array || o[i] instanceof RegExp) {
// check "allowed" options
- if (hasParent && typeof extraOptions[oParent] !== 'undefined') {
+ if (hasParent && bonusOptions[oParent] !== _undefined) {
// valid recursive / nested object option, eg., { defaultOptions: { volume: 50 } }
- _s[oParent][i] = o[i];
+ sm2[oParent][i] = o[i];
- } else if (typeof setupOptions[i] !== 'undefined') {
+ } else if (setupOptions[i] !== _undefined) {
// special case: assign to setupOptions object, which soundManager property references
- _s.setupOptions[i] = o[i];
+ sm2.setupOptions[i] = o[i];
// assign directly to soundManager, too
- _s[i] = o[i];
+ sm2[i] = o[i];
- } else if (typeof extraOptions[i] === 'undefined') {
+ } else if (bonusOptions[i] === _undefined) {
// invalid or disallowed parameter. complain.
- _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2);
+ complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
result = false;
} else {
/**
- * valid extraOptions parameter.
+ * valid extraOptions (bonusOptions) parameter.
* is it a method, like onready/ontimeout? call it.
* multiple parameters should be in an array, eg. soundManager.setup({onready: [myHandler, myScope]});
*/
- if (_s[i] instanceof Function) {
+ if (sm2[i] instanceof Function) {
- _s[i].apply(_s, (o[i] instanceof Array? o[i] : [o[i]]));
+ sm2[i].apply(sm2, (o[i] instanceof Array? o[i] : [o[i]]));
} else {
// good old-fashioned direct assignment
- _s[i] = o[i];
+ sm2[i] = o[i];
}
}
} else {
// recursion case, eg., { defaultOptions: { ... } }
- if (typeof extraOptions[i] === 'undefined') {
+ if (bonusOptions[i] === _undefined) {
// invalid or disallowed parameter. complain.
- _complain(_str((typeof _s[i] === 'undefined' ? 'setupUndef' : 'setupError'), i), 2);
+ complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
result = false;
} else {
// recurse through object
- return _assign(o[i], i);
+ return assign(o[i], i);
}
}
@@ -3377,33 +3424,35 @@
return result;
};
- function _preferFlashCheck(kind) {
+ function preferFlashCheck(kind) {
// whether flash should play a given type
- return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind]));
+ return (sm2.preferFlash && hasFlash && !sm2.ignoreFlash && (sm2.flash[kind] !== _undefined && sm2.flash[kind]));
}
/**
* Internal DOM2-level event helpers
* ---------------------------------
*/
- _event = (function() {
+ event = (function() {
- var old = (_win.attachEvent),
+ // normalize event methods
+ var old = (window.attachEvent),
evt = {
add: (old?'attachEvent':'addEventListener'),
remove: (old?'detachEvent':'removeEventListener')
};
+ // normalize "on" event prefix, optional capture argument
function getArgs(oArgs) {
- var args = _slice.call(oArgs),
+ var args = slice.call(oArgs),
len = args.length;
if (old) {
// prefix
args[1] = 'on' + args[1];
@@ -3419,14 +3468,16 @@
}
function apply(args, sType) {
+ // normalize and call the event method, with the proper arguments
var element = args.shift(),
method = [evt[sType]];
if (old) {
+ // old IE can't do apply().
element[method](args[0], args[1]);
} else {
element[method].apply(element, args);
}
@@ -3454,25 +3505,25 @@
/**
* Internal HTML5 event handling
* -----------------------------
*/
- function _html5_event(oFn) {
+ function html5_event(oFn) {
- // wrap html5 event handlers so we don't call them on destroyed sounds
+ // wrap html5 event handlers so we don't call them on destroyed and/or unloaded sounds
return function(e) {
- var t = this._t,
+ var s = this._s,
result;
- if (!t || !t._a) {
+ if (!s || !s._a) {
// <d>
- if (t && t.id) {
- _s._wD(_h5+'ignoring '+e.type+': '+t.id);
+ if (s && s.id) {
+ sm2._wD(s.id + ': Ignoring ' + e.type);
} else {
- _s._wD(_h5+'ignoring '+e.type);
+ sm2._wD(h5 + 'Ignoring ' + e.type);
}
// </d>
result = null;
} else {
result = oFn.call(this, e);
@@ -3482,163 +3533,163 @@
};
}
- _html5_events = {
+ html5_events = {
// HTML5 event-name-to-handler map
- abort: _html5_event(function() {
+ abort: html5_event(function() {
- _s._wD(_h5+'abort: '+this._t.id);
+ sm2._wD(this._s.id + ': abort');
}),
// enough has loaded to play
- canplay: _html5_event(function() {
+ canplay: html5_event(function() {
- var t = this._t,
+ var s = this._s,
position1K;
- if (t._html5_canplay) {
+ if (s._html5_canplay) {
// this event has already fired. ignore.
return true;
}
- t._html5_canplay = true;
- _s._wD(_h5+'canplay: '+t.id+', '+t.url);
- t._onbufferchange(0);
+ s._html5_canplay = true;
+ sm2._wD(s.id + ': canplay');
+ s._onbufferchange(0);
// position according to instance options
- position1K = (typeof t._iO.position !== 'undefined' && !isNaN(t._iO.position)?t._iO.position/1000:null);
+ position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/1000:null);
// set the position if position was set before the sound loaded
- if (t.position && this.currentTime !== position1K) {
- _s._wD(_h5+'canplay: setting position to '+position1K);
+ if (s.position && this.currentTime !== position1K) {
+ sm2._wD(s.id + ': canplay: Setting position to ' + position1K);
try {
this.currentTime = position1K;
} catch(ee) {
- _s._wD(_h5+'setting position of ' + position1K + ' failed: '+ee.message, 2);
+ sm2._wD(s.id + ': canplay: Setting position of ' + position1K + ' failed: ' + ee.message, 2);
}
}
// hack for HTML5 from/to case
- if (t._iO._oncanplay) {
- t._iO._oncanplay();
+ if (s._iO._oncanplay) {
+ s._iO._oncanplay();
}
}),
- canplaythrough: _html5_event(function() {
+ canplaythrough: html5_event(function() {
- var t = this._t;
+ var s = this._s;
- if (!t.loaded) {
- t._onbufferchange(0);
- t._whileloading(t.bytesLoaded, t.bytesTotal, t._get_html5_duration());
- t._onload(true);
+ if (!s.loaded) {
+ s._onbufferchange(0);
+ s._whileloading(s.bytesLoaded, s.bytesTotal, s._get_html5_duration());
+ s._onload(true);
}
}),
// TODO: Reserved for potential use
/*
- emptied: _html5_event(function() {
+ emptied: html5_event(function() {
- _s._wD(_h5+'emptied: '+this._t.id);
+ sm2._wD(this._s.id + ': emptied');
}),
*/
- ended: _html5_event(function() {
+ ended: html5_event(function() {
- var t = this._t;
+ var s = this._s;
- _s._wD(_h5+'ended: '+t.id);
- t._onfinish();
+ sm2._wD(s.id + ': ended');
+ s._onfinish();
+
}),
- error: _html5_event(function() {
+ error: html5_event(function() {
- _s._wD(_h5+'error: '+this.error.code);
+ sm2._wD(this._s.id + ': HTML5 error, code ' + this.error.code);
// call load with error state?
- this._t._onload(false);
+ this._s._onload(false);
}),
- loadeddata: _html5_event(function() {
+ loadeddata: html5_event(function() {
- var t = this._t;
+ var s = this._s;
- _s._wD(_h5+'loadeddata: '+this._t.id);
+ sm2._wD(s.id + ': loadeddata');
// safari seems to nicely report progress events, eventually totalling 100%
- if (!t._loaded && !_isSafari) {
- t.duration = t._get_html5_duration();
+ if (!s._loaded && !isSafari) {
+ s.duration = s._get_html5_duration();
}
}),
- loadedmetadata: _html5_event(function() {
+ loadedmetadata: html5_event(function() {
- _s._wD(_h5+'loadedmetadata: '+this._t.id);
+ sm2._wD(this._s.id + ': loadedmetadata');
}),
- loadstart: _html5_event(function() {
+ loadstart: html5_event(function() {
- _s._wD(_h5+'loadstart: '+this._t.id);
+ sm2._wD(this._s.id + ': loadstart');
// assume buffering at first
- this._t._onbufferchange(1);
+ this._s._onbufferchange(1);
}),
- play: _html5_event(function() {
+ play: html5_event(function() {
- _s._wD(_h5+'play: '+this._t.id+', '+this._t.url);
+ sm2._wD(this._s.id + ': play()');
// once play starts, no buffering
- this._t._onbufferchange(0);
+ this._s._onbufferchange(0);
}),
- playing: _html5_event(function() {
+ playing: html5_event(function() {
- _s._wD(_h5+'playing: '+this._t.id);
-
+ sm2._wD(this._s.id + ': playing');
// once play starts, no buffering
- this._t._onbufferchange(0);
+ this._s._onbufferchange(0);
}),
- progress: _html5_event(function(e) {
+ progress: html5_event(function(e) {
// note: can fire repeatedly after "loaded" event, due to use of HTTP range/partials
- var t = this._t,
+ var s = this._s,
i, j, str, buffered = 0,
isProgress = (e.type === 'progress'),
ranges = e.target.buffered,
// firefox 3.6 implements e.loaded/total (bytes)
loaded = (e.loaded||0),
total = (e.total||1),
// HTML5 returns msec. SM2 API uses seconds for setPosition() etc., whether Flash or HTML5.
scale = 1000;
// reset the "buffered" (loaded byte ranges) array
- t.buffered = [];
+ s.buffered = [];
if (ranges && ranges.length) {
// if loaded is 0, try TimeRanges implementation as % of load
// https://developer.mozilla.org/en/DOM/TimeRanges
// re-build "buffered" array
for (i=0, j=ranges.length; i<j; i++) {
- t.buffered.push({
+ s.buffered.push({
'start': ranges.start(i) * scale,
'end': ranges.end(i) * scale
});
}
@@ -3653,206 +3704,218 @@
str = [];
j = ranges.length;
for (i=0; i<j; i++) {
str.push(e.target.buffered.start(i)*scale +'-'+ e.target.buffered.end(i)*scale);
}
- _s._wD(_h5+'progress: timeRanges: '+str.join(', '));
+ sm2._wD(this._s.id + ': progress, timeRanges: ' + str.join(', '));
}
if (isProgress && !isNaN(loaded)) {
- _s._wD(_h5+'progress: '+t.id+': ' + Math.floor(loaded*100)+'% loaded');
+ sm2._wD(this._s.id + ': progress, ' + Math.floor(loaded*100) + '% loaded');
}
// </d>
}
if (!isNaN(loaded)) {
// if progress, likely not buffering
- t._onbufferchange(0);
+ s._onbufferchange(0);
// TODO: prevent calls with duplicate values.
- t._whileloading(loaded, total, t._get_html5_duration());
+ s._whileloading(loaded, total, s._get_html5_duration());
if (loaded && total && loaded === total) {
// in case "onload" doesn't fire (eg. gecko 1.9.2)
- _html5_events.canplaythrough.call(this, e);
+ html5_events.canplaythrough.call(this, e);
}
}
}),
- ratechange: _html5_event(function() {
+ ratechange: html5_event(function() {
- _s._wD(_h5+'ratechange: '+this._t.id);
+ sm2._wD(this._s.id + ': ratechange');
}),
- suspend: _html5_event(function(e) {
+ suspend: html5_event(function(e) {
// download paused/stopped, may have finished (eg. onload)
- var t = this._t;
+ var s = this._s;
- _s._wD(_h5+'suspend: '+t.id);
- _html5_events.progress.call(this, e);
- t._onsuspend();
+ sm2._wD(this._s.id + ': suspend');
+ html5_events.progress.call(this, e);
+ s._onsuspend();
}),
- stalled: _html5_event(function() {
+ stalled: html5_event(function() {
- _s._wD(_h5+'stalled: '+this._t.id);
+ sm2._wD(this._s.id + ': stalled');
}),
- timeupdate: _html5_event(function() {
+ timeupdate: html5_event(function() {
- this._t._onTimer();
+ this._s._onTimer();
}),
- waiting: _html5_event(function() {
+ waiting: html5_event(function() {
- var t = this._t;
+ var s = this._s;
// see also: seeking
- _s._wD(_h5+'waiting: '+t.id);
+ sm2._wD(this._s.id + ': waiting');
// playback faster than download rate, etc.
- t._onbufferchange(1);
+ s._onbufferchange(1);
})
};
- _html5OK = function(iO) {
+ html5OK = function(iO) {
// playability test based on URL or MIME type
var result;
- if (iO.serverURL || (iO.type && _preferFlashCheck(iO.type))) {
+ if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) {
// RTMP, or preferring flash
result = false;
} else {
// Use type, if specified. If HTML5-only mode, no other options, so just give 'er
- result = ((iO.type ? _html5CanPlay({type:iO.type}) : _html5CanPlay({url:iO.url}) || _s.html5Only));
+ result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only));
}
return result;
};
- _html5Unload = function(oAudio, url) {
+ html5Unload = function(oAudio, url) {
/**
* Internal method: Unload media, and cancel any current/pending network requests.
* Firefox can load an empty URL, which allegedly destroys the decoder and stops the download.
* https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media
* However, Firefox has been seen loading a relative URL from '' and thus requesting the hosting page on unload.
* Other UA behaviour is unclear, so everyone else gets an about:blank-style URL.
*/
if (oAudio) {
+
// Firefox likes '' for unload (used to work?) - however, may request hosting page URL (bad.) Most other UAs dislike '' and fail to unload.
oAudio.src = url;
+
+ // reset some state, too
+ oAudio._called_load = false;
+
}
+ if (useGlobalHTML5Audio) {
+
+ // ensure URL state is trashed, also
+ lastGlobalHTML5URL = null;
+
+ }
+
};
- _html5CanPlay = function(o) {
+ html5CanPlay = function(o) {
/**
* Try to find MIME, test and return truthiness
* o = {
* url: '/path/to/an.mp3',
* type: 'audio/mp3'
* }
*/
- if (!_s.useHTML5Audio || !_s.hasHTML5) {
+ if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
return false;
}
var url = (o.url || null),
mime = (o.type || null),
- aF = _s.audioFormats,
+ aF = sm2.audioFormats,
result,
offset,
fileExt,
item;
// account for known cases like audio/mp3
- if (mime && typeof _s.html5[mime] !== 'undefined') {
- return (_s.html5[mime] && !_preferFlashCheck(mime));
+ if (mime && sm2.html5[mime] !== _undefined) {
+ return (sm2.html5[mime] && !preferFlashCheck(mime));
}
- if (!_html5Ext) {
- _html5Ext = [];
+ if (!html5Ext) {
+ html5Ext = [];
for (item in aF) {
if (aF.hasOwnProperty(item)) {
- _html5Ext.push(item);
+ html5Ext.push(item);
if (aF[item].related) {
- _html5Ext = _html5Ext.concat(aF[item].related);
+ html5Ext = html5Ext.concat(aF[item].related);
}
}
}
- _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i');
+ html5Ext = new RegExp('\\.('+html5Ext.join('|')+')(\\?.*)?$','i');
}
// TODO: Strip URL queries, etc.
- fileExt = (url ? url.toLowerCase().match(_html5Ext) : null);
+ fileExt = (url ? url.toLowerCase().match(html5Ext) : null);
if (!fileExt || !fileExt.length) {
if (!mime) {
result = false;
} else {
// audio/mp3 -> mp3, result should be known
offset = mime.indexOf(';');
- // strip "audio/X; codecs.."
+ // strip "audio/X; codecs..."
fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);
}
} else {
// match the raw extension name - "mp3", for example
fileExt = fileExt[1];
}
- if (fileExt && typeof _s.html5[fileExt] !== 'undefined') {
+ if (fileExt && sm2.html5[fileExt] !== _undefined) {
// result known
- result = (_s.html5[fileExt] && !_preferFlashCheck(fileExt));
+ result = (sm2.html5[fileExt] && !preferFlashCheck(fileExt));
} else {
mime = 'audio/'+fileExt;
- result = _s.html5.canPlayType({type:mime});
- _s.html5[fileExt] = result;
- // _s._wD('canPlayType, found result: '+result);
- result = (result && _s.html5[mime] && !_preferFlashCheck(mime));
+ result = sm2.html5.canPlayType({type:mime});
+ sm2.html5[fileExt] = result;
+ // sm2._wD('canPlayType, found result: ' + result);
+ result = (result && sm2.html5[mime] && !preferFlashCheck(mime));
}
return result;
};
- _testHTML5 = function() {
+ testHTML5 = function() {
/**
* Internal: Iterates over audioFormats, determining support eg. audio/mp3, audio/mpeg and so on
* assigns results to html5[] and flash[].
*/
- if (!_s.useHTML5Audio || !_s.hasHTML5) {
+ if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
return false;
}
// double-whammy: Opera 9.64 throws WRONG_ARGUMENTS_ERR if no parameter passed to Audio(), and Webkit + iOS happily tries to load "null" as a URL. :/
- var a = (typeof Audio !== 'undefined' ? (_isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null),
+ var a = (Audio !== _undefined ? (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null),
item, lookup, support = {}, aF, i;
- function _cp(m) {
+ function cp(m) {
var canPlay, i, j,
result = false,
isOK = false;
@@ -3861,52 +3924,52 @@
}
if (m instanceof Array) {
// iterate through all mime types, return any successes
for (i=0, j=m.length; i<j; i++) {
- if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) {
+ if (sm2.html5[m[i]] || a.canPlayType(m[i]).match(sm2.html5Test)) {
isOK = true;
- _s.html5[m[i]] = true;
+ sm2.html5[m[i]] = true;
// note flash support, too
- _s.flash[m[i]] = !!(m[i].match(_flashMIME));
+ sm2.flash[m[i]] = !!(m[i].match(flashMIME));
}
}
result = isOK;
} else {
canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);
- result = !!(canPlay && (canPlay.match(_s.html5Test)));
+ result = !!(canPlay && (canPlay.match(sm2.html5Test)));
}
return result;
}
// test all registered formats + codecs
- aF = _s.audioFormats;
+ aF = sm2.audioFormats;
for (item in aF) {
if (aF.hasOwnProperty(item)) {
lookup = 'audio/' + item;
- support[item] = _cp(aF[item].type);
+ support[item] = cp(aF[item].type);
// write back generic type too, eg. audio/mp3
support[lookup] = support[item];
// assign flash
- if (item.match(_flashMIME)) {
+ if (item.match(flashMIME)) {
- _s.flash[item] = true;
- _s.flash[lookup] = true;
+ sm2.flash[item] = true;
+ sm2.flash[lookup] = true;
} else {
- _s.flash[item] = false;
- _s.flash[lookup] = false;
+ sm2.flash[item] = false;
+ sm2.flash[lookup] = false;
}
// assign result to related formats, too
@@ -3914,97 +3977,95 @@
for (i=aF[item].related.length-1; i >= 0; i--) {
// eg. audio/m4a
support['audio/'+aF[item].related[i]] = support[item];
- _s.html5[aF[item].related[i]] = support[item];
- _s.flash[aF[item].related[i]] = support[item];
+ sm2.html5[aF[item].related[i]] = support[item];
+ sm2.flash[aF[item].related[i]] = support[item];
}
}
}
}
- support.canPlayType = (a?_cp:null);
- _s.html5 = _mixin(_s.html5, support);
+ support.canPlayType = (a?cp:null);
+ sm2.html5 = mixin(sm2.html5, support);
return true;
};
- _strings = {
+ strings = {
// <d>
- notReady: 'Not loaded yet - wait for soundManager.onready()',
+ notReady: 'Unavailable - wait until onready() has fired.',
notOK: 'Audio support is not available.',
- domError: _smc + 'createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.',
- spcWmode: _smc + 'createMovie(): Removing wmode, preventing known SWF loading issue(s)',
- swf404: _sm + ': Verify that %s is a valid path.',
- tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)',
+ domError: sm + 'exception caught while appending SWF to DOM.',
+ spcWmode: 'Removing wmode, preventing known SWF loading issue(s)',
+ swf404: smc + 'Verify that %s is a valid path.',
+ tryDebug: 'Try ' + sm + '.debugFlash = true for more security details (output goes to SWF.)',
checkSWF: 'See SWF output for more debug info.',
- localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/',
- waitFocus: _sm + ': Special case: Waiting for SWF to load with window focus...',
- waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...',
- waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...',
- waitSWF: _sm + ': Retrying, waiting for 100% SWF load...',
- needFunction: _sm + ': Function object expected for %s',
+ localFail: smc + 'Non-HTTP page (' + doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/',
+ waitFocus: smc + 'Special case: Waiting for SWF to load with window focus...',
+ waitForever: smc + 'Waiting indefinitely for Flash (will recover if unblocked)...',
+ waitSWF: smc + 'Waiting for 100% SWF load...',
+ needFunction: smc + 'Function object expected for %s',
badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',
- currentObj: '--- ' + _sm + '._debug(): Current sound objects ---',
- waitEI: _smc + 'initMovie(): Waiting for ExternalInterface call from Flash...',
- waitOnload: _sm + ': Waiting for window.onload()',
- docLoaded: _sm + ': Document already loaded',
- onload: _smc + 'initComplete(): calling soundManager.onload()',
- onloadOK: _sm + '.onload() complete',
- init: _smc + 'init()',
- didInit: _smc + 'init(): Already called?',
- flashJS: _sm + ': Attempting JS to Flash call...',
+ currentObj: smc + '_debug(): Current sound objects',
+ waitOnload: smc + 'Waiting for window.onload()',
+ docLoaded: smc + 'Document already loaded',
+ onload: smc + 'initComplete(): calling soundManager.onload()',
+ onloadOK: sm + '.onload() complete',
+ didInit: smc + 'init(): Already called?',
secNote: 'Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html',
- badRemove: 'Warning: Failed to remove flash movie.',
- shutdown: _sm + '.disable(): Shutting down',
- queue: _sm + ': Queueing %s handler',
- smFail: _sm + ': Failed to initialise.',
+ badRemove: smc + 'Failed to remove Flash node.',
+ shutdown: sm + '.disable(): Shutting down',
+ queue: smc + 'Queueing %s handler',
smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',
- fbTimeout: 'No flash response, applying .'+_swfCSS.swfTimedout+' CSS...',
+ fbTimeout: 'No flash response, applying .'+swfCSS.swfTimedout+' CSS...',
fbLoaded: 'Flash loaded',
- fbHandler: _smc+'flashBlockHandler()',
+ flRemoved: smc + 'Flash movie removed.',
+ fbHandler: smc + 'flashBlockHandler()',
manURL: 'SMSound.load(): Using manually-assigned URL',
- onURL: _sm + '.load(): current URL already assigned.',
- badFV: _sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',
+ onURL: sm + '.load(): current URL already assigned.',
+ badFV: sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',
as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)',
noNSLoop: 'Note: Looping not implemented for MovieStar formats',
needfl9: 'Note: Switching to flash 9, required for MP4 formats.',
mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case',
- needFlash: _sm + ': Fatal error: Flash is needed to play some required formats, but is not available.',
- gotFocus: _sm + ': Got window focus.',
- mfOn: 'mobileFlash::enabling on-screen flash repositioning',
+ needFlash: smc + 'Fatal error: Flash is needed to play some required formats, but is not available.',
+ gotFocus: smc + 'Got window focus.',
policy: 'Enabling usePolicyFile for data access',
- setup: _sm + '.setup(): allowed parameters: %s',
- setupError: _sm + '.setup(): "%s" cannot be assigned with this method.',
- setupUndef: _sm + '.setup(): Could not find option "%s"',
- setupLate: _sm + '.setup(): url + flashVersion changes will not take effect until reboot().',
- h5a: 'creating HTML5 Audio() object',
- noURL: _sm + ': Flash URL required. Call soundManager.setup({url:...}) to get started.'
+ setup: sm + '.setup(): allowed parameters: %s',
+ setupError: sm + '.setup(): "%s" cannot be assigned with this method.',
+ setupUndef: sm + '.setup(): Could not find option "%s"',
+ setupLate: sm + '.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().',
+ noURL: smc + 'Flash URL required. Call soundManager.setup({url:...}) to get started.',
+ sm2Loaded: 'SoundManager 2: Ready.',
+ reset: sm + '.reset(): Removing event callbacks',
+ mobileUA: 'Mobile UA detected, preferring HTML5 by default.',
+ globalHTML5: 'Using singleton HTML5 Audio() pattern for this device.'
// </d>
};
- _str = function() {
+ str = function() {
// internal string replace helper.
// arguments: o [,items to replace]
// <d>
// real array, please
- var args = _slice.call(arguments),
+ var args = slice.call(arguments),
// first arg
o = args.shift(),
- str = (_strings && _strings[o]?_strings[o]:''), i, j;
+ str = (strings && strings[o]?strings[o]:''), i, j;
if (str && args && args.length) {
for (i = 0, j = args.length; i < j; i++) {
str = str.replace('%s', args[i]);
}
}
@@ -4012,81 +4073,80 @@
return str;
// </d>
};
- _loopFix = function(sOpt) {
+ loopFix = function(sOpt) {
// flash 8 requires stream = false for looping to work
- if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) {
+ if (fV === 8 && sOpt.loops > 1 && sOpt.stream) {
_wDS('as2loop');
sOpt.stream = false;
}
return sOpt;
};
- _policyFix = function(sOpt, sPre) {
+ policyFix = function(sOpt, sPre) {
if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) {
- _s._wD((sPre || '') + _str('policy'));
+ sm2._wD((sPre || '') + str('policy'));
sOpt.usePolicyFile = true;
}
return sOpt;
};
- _complain = function(sMsg) {
+ complain = function(sMsg) {
// <d>
- if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') {
+ if (console !== _undefined && console.warn !== _undefined) {
console.warn(sMsg);
} else {
- _s._wD(sMsg);
+ sm2._wD(sMsg);
}
// </d>
};
- _doNothing = function() {
+ doNothing = function() {
return false;
};
- _disableObject = function(o) {
+ disableObject = function(o) {
var oProp;
for (oProp in o) {
if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {
- o[oProp] = _doNothing;
+ o[oProp] = doNothing;
}
}
oProp = null;
};
- _failSafely = function(bNoDisable) {
+ failSafely = function(bNoDisable) {
// general failure exception handler
- if (typeof bNoDisable === 'undefined') {
+ if (bNoDisable === _undefined) {
bNoDisable = false;
}
- if (_disabled || bNoDisable) {
- _wDS('smFail', 2);
- _s.disable(bNoDisable);
+ if (disabled || bNoDisable) {
+ sm2.disable(bNoDisable);
}
};
- _normalizeMovieURL = function(smURL) {
+ normalizeMovieURL = function(smURL) {
var urlParams = null, url;
if (smURL) {
if (smURL.match(/\.swf(\?.*)?$/i)) {
@@ -4099,95 +4159,95 @@
// append trailing slash, if needed
smURL += '/';
}
}
- url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL;
+ url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + sm2.movieURL;
- if (_s.noSWFCache) {
+ if (sm2.noSWFCache) {
url += ('?ts=' + new Date().getTime());
}
return url;
};
- _setVersionInfo = function() {
+ setVersionInfo = function() {
// short-hand for internal use
- _fV = parseInt(_s.flashVersion, 10);
+ fV = parseInt(sm2.flashVersion, 10);
- if (_fV !== 8 && _fV !== 9) {
- _s._wD(_str('badFV', _fV, _defaultFlashVersion));
- _s.flashVersion = _fV = _defaultFlashVersion;
+ if (fV !== 8 && fV !== 9) {
+ sm2._wD(str('badFV', fV, defaultFlashVersion));
+ sm2.flashVersion = fV = defaultFlashVersion;
}
// debug flash movie, if applicable
- var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf');
+ var isDebug = (sm2.debugMode || sm2.debugFlash?'_debug.swf':'.swf');
- if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) {
- _s._wD(_str('needfl9'));
- _s.flashVersion = _fV = 9;
+ if (sm2.useHTML5Audio && !sm2.html5Only && sm2.audioFormats.mp4.required && fV < 9) {
+ sm2._wD(str('needfl9'));
+ sm2.flashVersion = fV = 9;
}
- _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));
+ sm2.version = sm2.versionNumber + (sm2.html5Only?' (HTML5-only mode)':(fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));
// set up default options
- if (_fV > 8) {
+ if (fV > 8) {
// +flash 9 base options
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options);
- _s.features.buffering = true;
+ sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.flash9Options);
+ sm2.features.buffering = true;
// +moviestar support
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions);
- _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
- _s.features.movieStar = true;
+ sm2.defaultOptions = mixin(sm2.defaultOptions, sm2.movieStarOptions);
+ sm2.filePatterns.flash9 = new RegExp('\\.(mp3|' + netStreamTypes.join('|') + ')(\\?.*)?$', 'i');
+ sm2.features.movieStar = true;
} else {
- _s.features.movieStar = false;
+ sm2.features.movieStar = false;
}
// regExp for flash canPlay(), etc.
- _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')];
+ sm2.filePattern = sm2.filePatterns[(fV !== 8?'flash9':'flash8')];
// if applicable, use _debug versions of SWFs
- _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);
+ sm2.movieURL = (fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);
- _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8);
+ sm2.features.peakData = sm2.features.waveformData = sm2.features.eqData = (fV > 8);
};
- _setPolling = function(bPolling, bHighPerformance) {
+ setPolling = function(bPolling, bHighPerformance) {
- if (!_flash) {
+ if (!flash) {
return false;
}
- _flash._setPolling(bPolling, bHighPerformance);
+ flash._setPolling(bPolling, bHighPerformance);
};
- _initDebug = function() {
+ initDebug = function() {
// starts debug mode, creating output <div> for UAs without console object
// allow force of debug mode via URL
- if (_s.debugURLParam.test(_wl)) {
- _s.debugMode = true;
+ if (sm2.debugURLParam.test(wl)) {
+ sm2.debugMode = true;
}
// <d>
- if (_id(_s.debugID)) {
+ if (id(sm2.debugID)) {
return false;
}
var oD, oDebug, oTarget, oToggle, tmp;
- if (_s.debugMode && !_id(_s.debugID) && (!_hasConsole || !_s.useConsole || !_s.consoleOnly)) {
+ if (sm2.debugMode && !id(sm2.debugID) && (!hasConsole || !sm2.useConsole || !sm2.consoleOnly)) {
- oD = _doc.createElement('div');
- oD.id = _s.debugID + '-toggle';
+ oD = doc.createElement('div');
+ oD.id = sm2.debugID + '-toggle';
oToggle = {
'position': 'fixed',
'bottom': '0px',
'right': '0px',
@@ -4201,35 +4261,35 @@
'background': '#fff',
'color': '#333',
'zIndex': 10001
};
- oD.appendChild(_doc.createTextNode('-'));
- oD.onclick = _toggleDebug;
+ oD.appendChild(doc.createTextNode('-'));
+ oD.onclick = toggleDebug;
oD.title = 'Toggle SM2 debug console';
- if (_ua.match(/msie 6/i)) {
+ if (ua.match(/msie 6/i)) {
oD.style.position = 'absolute';
oD.style.cursor = 'hand';
}
for (tmp in oToggle) {
if (oToggle.hasOwnProperty(tmp)) {
oD.style[tmp] = oToggle[tmp];
}
}
- oDebug = _doc.createElement('div');
- oDebug.id = _s.debugID;
- oDebug.style.display = (_s.debugMode?'block':'none');
+ oDebug = doc.createElement('div');
+ oDebug.id = sm2.debugID;
+ oDebug.style.display = (sm2.debugMode?'block':'none');
- if (_s.debugMode && !_id(oD.id)) {
+ if (sm2.debugMode && !id(oD.id)) {
try {
- oTarget = _getDocument();
+ oTarget = getDocument();
oTarget.appendChild(oD);
} catch(e2) {
- throw new Error(_str('domError')+' \n'+e2.toString());
+ throw new Error(str('domError')+' \n'+e2.toString());
}
oTarget.appendChild(oDebug);
}
}
@@ -4237,52 +4297,46 @@
oTarget = null;
// </d>
};
- _idCheck = this.getSoundById;
+ idCheck = this.getSoundById;
// <d>
_wDS = function(o, errorLevel) {
- return (!o ? '' : _s._wD(_str(o), errorLevel));
+ return (!o ? '' : sm2._wD(str(o), errorLevel));
};
- // last-resort debugging option
+ toggleDebug = function() {
- if (_wl.indexOf('sm2-debug=alert') + 1 && _s.debugMode) {
- _s._wD = function(sText) {window.alert(sText);};
- }
+ var o = id(sm2.debugID),
+ oT = id(sm2.debugID + '-toggle');
- _toggleDebug = function() {
-
- var o = _id(_s.debugID),
- oT = _id(_s.debugID + '-toggle');
-
if (!o) {
return false;
}
- if (_debugOpen) {
+ if (debugOpen) {
// minimize
oT.innerHTML = '+';
o.style.display = 'none';
} else {
oT.innerHTML = '-';
o.style.display = 'block';
}
- _debugOpen = !_debugOpen;
+ debugOpen = !debugOpen;
};
- _debugTS = function(sEventType, bSuccess, sMessage) {
+ debugTS = function(sEventType, bSuccess, sMessage) {
// troubleshooter debug hooks
- if (typeof sm2Debugger !== 'undefined') {
+ if (window.sm2Debugger !== _undefined) {
try {
sm2Debugger.handleEvent(sEventType, bSuccess, sMessage);
} catch(e) {
// oh well
}
@@ -4291,119 +4345,119 @@
return true;
};
// </d>
- _getSWFCSS = function() {
+ getSWFCSS = function() {
var css = [];
- if (_s.debugMode) {
- css.push(_swfCSS.sm2Debug);
+ if (sm2.debugMode) {
+ css.push(swfCSS.sm2Debug);
}
- if (_s.debugFlash) {
- css.push(_swfCSS.flashDebug);
+ if (sm2.debugFlash) {
+ css.push(swfCSS.flashDebug);
}
- if (_s.useHighPerformance) {
- css.push(_swfCSS.highPerf);
+ if (sm2.useHighPerformance) {
+ css.push(swfCSS.highPerf);
}
return css.join(' ');
};
- _flashBlockHandler = function() {
+ flashBlockHandler = function() {
// *possible* flash block situation.
- var name = _str('fbHandler'),
- p = _s.getMoviePercent(),
- css = _swfCSS,
+ var name = str('fbHandler'),
+ p = sm2.getMoviePercent(),
+ css = swfCSS,
error = {type:'FLASHBLOCK'};
- if (_s.html5Only) {
+ if (sm2.html5Only) {
return false;
}
- if (!_s.ok()) {
+ if (!sm2.ok()) {
- if (_needsFlash) {
+ if (needsFlash) {
// make the movie more visible, so user can fix
- _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);
- _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':''));
+ sm2.oMC.className = getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);
+ sm2._wD(name + ': ' + str('fbTimeout') + (p ? ' (' + str('fbLoaded') + ')' : ''));
}
- _s.didFlashBlock = true;
+ sm2.didFlashBlock = true;
// fire onready(), complain lightly
- _processOnEvents({type:'ontimeout', ignoreInit:true, error:error});
- _catchError(error);
+ processOnEvents({type:'ontimeout', ignoreInit:true, error:error});
+ catchError(error);
} else {
// SM2 loaded OK (or recovered)
// <d>
- if (_s.didFlashBlock) {
- _s._wD(name+': Unblocked');
+ if (sm2.didFlashBlock) {
+ sm2._wD(name + ': Unblocked');
}
// </d>
- if (_s.oMC) {
- _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');
+ if (sm2.oMC) {
+ sm2.oMC.className = [getSWFCSS(), css.swfDefault, css.swfLoaded + (sm2.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');
}
}
};
- _addOnEvent = function(sType, oMethod, oScope) {
+ addOnEvent = function(sType, oMethod, oScope) {
- if (typeof _on_queue[sType] === 'undefined') {
- _on_queue[sType] = [];
+ if (on_queue[sType] === _undefined) {
+ on_queue[sType] = [];
}
- _on_queue[sType].push({
+ on_queue[sType].push({
'method': oMethod,
'scope': (oScope || null),
'fired': false
});
};
- _processOnEvents = function(oOptions) {
+ processOnEvents = function(oOptions) {
// if unspecified, assume OK/error
if (!oOptions) {
oOptions = {
- type: (_s.ok() ? 'onready' : 'ontimeout')
+ type: (sm2.ok() ? 'onready' : 'ontimeout')
};
}
- if (!_didInit && oOptions && !oOptions.ignoreInit) {
+ if (!didInit && oOptions && !oOptions.ignoreInit) {
// not ready yet.
return false;
}
- if (oOptions.type === 'ontimeout' && (_s.ok() || (_disabled && !oOptions.ignoreInit))) {
+ if (oOptions.type === 'ontimeout' && (sm2.ok() || (disabled && !oOptions.ignoreInit))) {
// invalid case
return false;
}
var status = {
- success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled)
+ success: (oOptions && oOptions.ignoreInit?sm2.ok():!disabled)
},
// queue specified by type, or none
- srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]),
+ srcQueue = (oOptions && oOptions.type?on_queue[oOptions.type]||[]:[]),
queue = [], i, j,
args = [status],
- canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok());
+ canRetry = (needsFlash && !sm2.ok());
if (oOptions.error) {
args[0].error = oOptions.error;
}
@@ -4412,153 +4466,156 @@
queue.push(srcQueue[i]);
}
}
if (queue.length) {
- _s._wD(_sm + ': Firing ' + queue.length + ' '+oOptions.type+'() item' + (queue.length === 1?'':'s'));
+ // sm2._wD(sm + ': Firing ' + queue.length + ' ' + oOptions.type + '() item' + (queue.length === 1 ? '' : 's'));
for (i = 0, j = queue.length; i < j; i++) {
if (queue[i].scope) {
queue[i].method.apply(queue[i].scope, args);
} else {
queue[i].method.apply(this, args);
}
if (!canRetry) {
- // flashblock case doesn't count here
+ // useFlashBlock and SWF timeout case doesn't count here.
queue[i].fired = true;
}
}
}
return true;
};
- _initUserOnload = function() {
+ initUserOnload = function() {
- _win.setTimeout(function() {
+ window.setTimeout(function() {
- if (_s.useFlashBlock) {
- _flashBlockHandler();
+ if (sm2.useFlashBlock) {
+ flashBlockHandler();
}
- _processOnEvents();
+ processOnEvents();
// call user-defined "onload", scoped to window
- if (typeof _s.onload === 'function') {
+ if (typeof sm2.onload === 'function') {
_wDS('onload', 1);
- _s.onload.apply(_win);
+ sm2.onload.apply(window);
_wDS('onloadOK', 1);
}
- if (_s.waitForWindowLoad) {
- _event.add(_win, 'load', _initUserOnload);
+ if (sm2.waitForWindowLoad) {
+ event.add(window, 'load', initUserOnload);
}
},1);
};
- _detectFlash = function() {
+ detectFlash = function() {
// hat tip: Flash Detect library (BSD, (C) 2007) by Carl "DocYes" S. Yestrau - http://featureblend.com/javascript-flash-detection-library.html / http://featureblend.com/license.txt
- if (typeof _hasFlash !== 'undefined') {
+ if (hasFlash !== _undefined) {
// this work has already been done.
- return _hasFlash;
+ return hasFlash;
}
- var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject;
+ var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = window.ActiveXObject;
if (nP && nP.length) {
type = 'application/x-shockwave-flash';
types = n.mimeTypes;
if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {
hasPlugin = true;
}
- } else if (typeof AX !== 'undefined') {
+ } else if (AX !== _undefined && !ua.match(/MSAppHost/i)) {
+ // Windows 8 Store Apps (MSAppHost) are weird (compatibility?) and won't complain here, but will barf if Flash/ActiveX object is appended to the DOM.
try {
obj = new AX('ShockwaveFlash.ShockwaveFlash');
} catch(e) {
// oh well
}
hasPlugin = (!!obj);
+ // cleanup, because it is ActiveX after all
+ obj = null;
}
- _hasFlash = hasPlugin;
+ hasFlash = hasPlugin;
return hasPlugin;
};
- _featureCheck = function() {
+ featureCheck = function() {
var needsFlash,
item,
result = true,
- formats = _s.audioFormats,
+ formats = sm2.audioFormats,
// iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (original iPad) + iOS4 works.
- isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i)));
+ isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i)));
if (isSpecial) {
// has Audio(), but is broken; let it load links directly.
- _s.hasHTML5 = false;
+ sm2.hasHTML5 = false;
// ignore flash case, however
- _s.html5Only = true;
+ sm2.html5Only = true;
- if (_s.oMC) {
- _s.oMC.style.display = 'none';
+ if (sm2.oMC) {
+ sm2.oMC.style.display = 'none';
}
result = false;
} else {
- if (_s.useHTML5Audio) {
+ if (sm2.useHTML5Audio) {
- if (!_s.html5 || !_s.html5.canPlayType) {
- _s._wD('SoundManager: No HTML5 Audio() support detected.');
- _s.hasHTML5 = false;
+ if (!sm2.html5 || !sm2.html5.canPlayType) {
+ sm2._wD('SoundManager: No HTML5 Audio() support detected.');
+ sm2.hasHTML5 = false;
}
// <d>
- if (_isBadSafari) {
- _s._wD(_smc+'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - '+(!_hasFlash?' would use flash fallback for MP3/MP4, but none detected.':'will use flash fallback for MP3/MP4, if available'),1);
+ if (isBadSafari) {
+ sm2._wD(smc + 'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - ' + (!hasFlash ?' would use flash fallback for MP3/MP4, but none detected.' : 'will use flash fallback for MP3/MP4, if available'), 1);
}
// </d>
}
}
- if (_s.useHTML5Audio && _s.hasHTML5) {
+ if (sm2.useHTML5Audio && sm2.hasHTML5) {
for (item in formats) {
if (formats.hasOwnProperty(item)) {
- if ((formats[item].required && !_s.html5.canPlayType(formats[item].type)) || (_s.preferFlash && (_s.flash[item] || _s.flash[formats[item].type]))) {
+ if ((formats[item].required && !sm2.html5.canPlayType(formats[item].type)) || (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type]))) {
// flash may be required, or preferred for this format
needsFlash = true;
}
}
}
}
// sanity check...
- if (_s.ignoreFlash) {
+ if (sm2.ignoreFlash) {
needsFlash = false;
}
- _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash);
+ sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !needsFlash);
- return (!_s.html5Only);
+ return (!sm2.html5Only);
};
- _parseURL = function(url) {
+ parseURL = function(url) {
/**
* Internal: Finds and returns the first playable URL (or failing that, the first URL.)
* @param {string or array} url A single URL string, OR, an array of URL strings or {url:'/path/to/resource', type:'audio/mp3'} objects.
*/
@@ -4570,16 +4627,16 @@
// find the first good one
for (i=0, j=url.length; i<j; i++) {
if (url[i] instanceof Object) {
// MIME check
- if (_s.canPlayMIME(url[i].type)) {
+ if (sm2.canPlayMIME(url[i].type)) {
urlResult = i;
break;
}
- } else if (_s.canPlayURL(url[i])) {
+ } else if (sm2.canPlayURL(url[i])) {
// URL string check
urlResult = i;
break;
}
@@ -4602,125 +4659,125 @@
return result;
};
- _startTimer = function(oSound) {
+ startTimer = function(oSound) {
/**
* attach a timer to this sound, and start an interval if needed
*/
if (!oSound._hasTimer) {
oSound._hasTimer = true;
- if (!_mobileHTML5 && _s.html5PollingInterval) {
+ if (!mobileHTML5 && sm2.html5PollingInterval) {
- if (_h5IntervalTimer === null && _h5TimerCount === 0) {
+ if (h5IntervalTimer === null && h5TimerCount === 0) {
- _h5IntervalTimer = _win.setInterval(_timerExecute, _s.html5PollingInterval);
+ h5IntervalTimer = window.setInterval(timerExecute, sm2.html5PollingInterval);
}
- _h5TimerCount++;
+ h5TimerCount++;
}
}
};
- _stopTimer = function(oSound) {
+ stopTimer = function(oSound) {
/**
* detach a timer
*/
if (oSound._hasTimer) {
oSound._hasTimer = false;
- if (!_mobileHTML5 && _s.html5PollingInterval) {
+ if (!mobileHTML5 && sm2.html5PollingInterval) {
// interval will stop itself at next execution.
- _h5TimerCount--;
+ h5TimerCount--;
}
}
};
- _timerExecute = function() {
+ timerExecute = function() {
/**
* manual polling for HTML5 progress events, ie., whileplaying() (can achieve greater precision than conservative default HTML5 interval)
*/
var i;
- if (_h5IntervalTimer !== null && !_h5TimerCount) {
+ if (h5IntervalTimer !== null && !h5TimerCount) {
// no active timers, stop polling interval.
- _win.clearInterval(_h5IntervalTimer);
+ window.clearInterval(h5IntervalTimer);
- _h5IntervalTimer = null;
+ h5IntervalTimer = null;
return false;
}
// check all HTML5 sounds with timers
- for (i = _s.soundIDs.length-1; i >= 0; i--) {
+ for (i = sm2.soundIDs.length-1; i >= 0; i--) {
- if (_s.sounds[_s.soundIDs[i]].isHTML5 && _s.sounds[_s.soundIDs[i]]._hasTimer) {
+ if (sm2.sounds[sm2.soundIDs[i]].isHTML5 && sm2.sounds[sm2.soundIDs[i]]._hasTimer) {
- _s.sounds[_s.soundIDs[i]]._onTimer();
+ sm2.sounds[sm2.soundIDs[i]]._onTimer();
}
}
};
- _catchError = function(options) {
+ catchError = function(options) {
- options = (typeof options !== 'undefined' ? options : {});
+ options = (options !== _undefined ? options : {});
- if (typeof _s.onerror === 'function') {
- _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]);
+ if (typeof sm2.onerror === 'function') {
+ sm2.onerror.apply(window, [{type:(options.type !== _undefined ? options.type : null)}]);
}
- if (typeof options.fatal !== 'undefined' && options.fatal) {
- _s.disable();
+ if (options.fatal !== _undefined && options.fatal) {
+ sm2.disable();
}
};
- _badSafariFix = function() {
+ badSafariFix = function() {
// special case: "bad" Safari (OS X 10.3 - 10.7) must fall back to flash for MP3/MP4
- if (!_isBadSafari || !_detectFlash()) {
+ if (!isBadSafari || !detectFlash()) {
// doesn't apply
return false;
}
- var aF = _s.audioFormats, i, item;
+ var aF = sm2.audioFormats, i, item;
for (item in aF) {
if (aF.hasOwnProperty(item)) {
if (item === 'mp3' || item === 'mp4') {
- _s._wD(_sm+': Using flash fallback for '+item+' format');
- _s.html5[item] = false;
+ sm2._wD(sm + ': Using flash fallback for ' + item + ' format');
+ sm2.html5[item] = false;
// assign result to related formats, too
if (aF[item] && aF[item].related) {
for (i = aF[item].related.length-1; i >= 0; i--) {
- _s.html5[aF[item].related[i]] = false;
+ sm2.html5[aF[item].related[i]] = false;
}
}
}
}
}
@@ -4733,17 +4790,15 @@
*/
this._setSandboxType = function(sandboxType) {
// <d>
- var sb = _s.sandbox;
+ var sb = sm2.sandbox;
sb.type = sandboxType;
- sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')];
+ sb.description = sb.types[(sb.types[sandboxType] !== _undefined?sandboxType:'unknown')];
- _s._wD('Flash security sandbox type: ' + sb.type);
-
if (sb.type === 'localWithFile') {
sb.noRemote = true;
sb.noLocal = false;
_wDS('secNote', 2);
@@ -4767,31 +4822,30 @@
// flash callback confirming flash loaded, EI working etc.
// flashDate = approx. timing/delay info for JS/flash bridge
// swfVersion: SWF build string
- if (_s.swfLoaded) {
+ if (sm2.swfLoaded) {
return false;
}
- var e, eiTime = new Date().getTime();
+ var e;
- _s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':''));
- _debugTS('swf', true);
- _debugTS('flashtojs', true);
- _s.swfLoaded = true;
- _tryInitOnFocus = false;
+ debugTS('swf', true);
+ debugTS('flashtojs', true);
+ sm2.swfLoaded = true;
+ tryInitOnFocus = false;
- if (_isBadSafari) {
- _badSafariFix();
+ if (isBadSafari) {
+ badSafariFix();
}
// complain if JS + SWF build/version strings don't match, excluding +DEV builds
// <d>
- if (!swfVersion || swfVersion.replace(/\+dev/i,'') !== _s.versionNumber.replace(/\+dev/i, '')) {
+ if (!swfVersion || swfVersion.replace(/\+dev/i,'') !== sm2.versionNumber.replace(/\+dev/i, '')) {
- e = _sm + ': Fatal: JavaScript file build "' + _s.versionNumber + '" does not match Flash SWF build "' + swfVersion + '" at ' + _s.url + '. Ensure both are up-to-date.';
+ e = sm + ': Fatal: JavaScript file build "' + sm2.versionNumber + '" does not match Flash SWF build "' + swfVersion + '" at ' + sm2.url + '. Ensure both are up-to-date.';
// escape flash -> JS stack so this error fires in window.
setTimeout(function versionMismatch() {
throw new Error(e);
}, 0);
@@ -4801,150 +4855,204 @@
}
// </d>
// slight delay before init
- setTimeout(_init, _isIE ? 100 : 1);
+ setTimeout(init, isIE ? 100 : 1);
};
/**
* Private initialization helpers
* ------------------------------
*/
- _createMovie = function(smID, smURL) {
+ createMovie = function(smID, smURL) {
- if (_didAppend && _appendSuccess) {
+ if (didAppend && appendSuccess) {
// ignore if already succeeded
return false;
}
- function _initMsg() {
- _s._wD('-- SoundManager 2 ' + _s.version + (!_s.html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_s.html5Only ? (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : 'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1);
+ function initMsg() {
+
+ // <d>
+
+ var options = [], title, str = [], delimiter = ' + ';
+
+ title = 'SoundManager ' + sm2.version + (!sm2.html5Only && sm2.useHTML5Audio ? (sm2.hasHTML5 ? ' + HTML5 audio' : ', no HTML5 audio support') : '');
+
+ if (!sm2.html5Only) {
+
+ if (sm2.preferFlash) {
+ options.push('preferFlash');
+ }
+
+ if (sm2.useHighPerformance) {
+ options.push('useHighPerformance');
+ }
+
+ if (sm2.flashPollingInterval) {
+ options.push('flashPollingInterval (' + sm2.flashPollingInterval + 'ms)');
+ }
+
+ if (sm2.html5PollingInterval) {
+ options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)');
+ }
+
+ if (sm2.wmode) {
+ options.push('wmode (' + sm2.wmode + ')');
+ }
+
+ if (sm2.debugFlash) {
+ options.push('debugFlash');
+ }
+
+ if (sm2.useFlashBlock) {
+ options.push('flashBlock');
+ }
+
+ } else {
+
+ if (sm2.html5PollingInterval) {
+ options.push('html5PollingInterval (' + sm2.html5PollingInterval + 'ms)');
+ }
+
+ }
+
+ if (options.length) {
+ str = str.concat([options.join(delimiter)]);
+ }
+
+ sm2._wD(title + (str.length ? delimiter + str.join(', ') : ''), 1);
+
+ showSupport();
+
+ // </d>
+
}
- if (_s.html5Only) {
+ if (sm2.html5Only) {
// 100% HTML5 mode
- _setVersionInfo();
+ setVersionInfo();
- _initMsg();
- _s.oMC = _id(_s.movieID);
- _init();
+ initMsg();
+ sm2.oMC = id(sm2.movieID);
+ init();
// prevent multiple init attempts
- _didAppend = true;
+ didAppend = true;
- _appendSuccess = true;
+ appendSuccess = true;
return false;
}
// flash path
- var remoteURL = (smURL || _s.url),
- localURL = (_s.altURL || remoteURL),
+ var remoteURL = (smURL || sm2.url),
+ localURL = (sm2.altURL || remoteURL),
swfTitle = 'JS/Flash audio component (SoundManager 2)',
- oTarget = _getDocument(),
- extraClass = _getSWFCSS(),
+ oTarget = getDocument(),
+ extraClass = getSWFCSS(),
isRTL = null,
- html = _doc.getElementsByTagName('html')[0],
+ html = doc.getElementsByTagName('html')[0],
oEmbed, oMovie, tmp, movieHTML, oEl, s, x, sClass;
isRTL = (html && html.dir && html.dir.match(/rtl/i));
- smID = (typeof smID === 'undefined'?_s.id:smID);
+ smID = (smID === _undefined?sm2.id:smID);
function param(name, value) {
return '<param name="'+name+'" value="'+value+'" />';
}
// safety check for legacy (change to Flash 9 URL)
- _setVersionInfo();
- _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL);
- smURL = _s.url;
+ setVersionInfo();
+ sm2.url = normalizeMovieURL(overHTTP?remoteURL:localURL);
+ smURL = sm2.url;
- _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode);
+ sm2.wmode = (!sm2.wmode && sm2.useHighPerformance ? 'transparent' : sm2.wmode);
- if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {
+ if (sm2.wmode !== null && (ua.match(/msie 8/i) || (!isIE && !sm2.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {
/**
* extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here
* does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout
* wmode breaks IE 8 on Vista + Win7 too in some cases, as of January 2011 (?)
*/
- _wDS('spcWmode');
- _s.wmode = null;
+ messages.push(strings.spcWmode);
+ sm2.wmode = null;
}
oEmbed = {
'name': smID,
'id': smID,
'src': smURL,
'quality': 'high',
- 'allowScriptAccess': _s.allowScriptAccess,
- 'bgcolor': _s.bgColor,
- 'pluginspage': _http+'www.macromedia.com/go/getflashplayer',
+ 'allowScriptAccess': sm2.allowScriptAccess,
+ 'bgcolor': sm2.bgColor,
+ 'pluginspage': http+'www.macromedia.com/go/getflashplayer',
'title': swfTitle,
'type': 'application/x-shockwave-flash',
- 'wmode': _s.wmode,
+ 'wmode': sm2.wmode,
// http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html
'hasPriority': 'true'
};
- if (_s.debugFlash) {
+ if (sm2.debugFlash) {
oEmbed.FlashVars = 'debug=1';
}
- if (!_s.wmode) {
+ if (!sm2.wmode) {
// don't write empty attribute
delete oEmbed.wmode;
}
- if (_isIE) {
+ if (isIE) {
// IE is "special".
- oMovie = _doc.createElement('div');
+ oMovie = doc.createElement('div');
movieHTML = [
- '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + _http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">',
+ '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">',
param('movie', smURL),
- param('AllowScriptAccess', _s.allowScriptAccess),
+ param('AllowScriptAccess', sm2.allowScriptAccess),
param('quality', oEmbed.quality),
- (_s.wmode? param('wmode', _s.wmode): ''),
- param('bgcolor', _s.bgColor),
+ (sm2.wmode? param('wmode', sm2.wmode): ''),
+ param('bgcolor', sm2.bgColor),
param('hasPriority', 'true'),
- (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),
+ (sm2.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),
'</object>'
].join('');
} else {
- oMovie = _doc.createElement('embed');
+ oMovie = doc.createElement('embed');
for (tmp in oEmbed) {
if (oEmbed.hasOwnProperty(tmp)) {
oMovie.setAttribute(tmp, oEmbed[tmp]);
}
}
}
- _initDebug();
- extraClass = _getSWFCSS();
- oTarget = _getDocument();
+ initDebug();
+ extraClass = getSWFCSS();
+ oTarget = getDocument();
if (oTarget) {
- _s.oMC = (_id(_s.movieID) || _doc.createElement('div'));
+ sm2.oMC = (id(sm2.movieID) || doc.createElement('div'));
- if (!_s.oMC.id) {
+ if (!sm2.oMC.id) {
- _s.oMC.id = _s.movieID;
- _s.oMC.className = _swfCSS.swfDefault + ' ' + extraClass;
+ sm2.oMC.id = sm2.movieID;
+ sm2.oMC.className = swfCSS.swfDefault + ' ' + extraClass;
s = null;
oEl = null;
- if (!_s.useFlashBlock) {
- if (_s.useHighPerformance) {
+ if (!sm2.useFlashBlock) {
+ if (sm2.useHighPerformance) {
// on-screen at all times
s = {
'position': 'fixed',
'width': '8px',
'height': '8px',
@@ -4966,76 +5074,76 @@
s.left = Math.abs(parseInt(s.left,10))+'px';
}
}
}
- if (_isWebkit) {
+ if (isWebkit) {
// soundcloud-reported render/crash fix, safari 5
- _s.oMC.style.zIndex = 10000;
+ sm2.oMC.style.zIndex = 10000;
}
- if (!_s.debugFlash) {
+ if (!sm2.debugFlash) {
for (x in s) {
if (s.hasOwnProperty(x)) {
- _s.oMC.style[x] = s[x];
+ sm2.oMC.style[x] = s[x];
}
}
}
try {
- if (!_isIE) {
- _s.oMC.appendChild(oMovie);
+ if (!isIE) {
+ sm2.oMC.appendChild(oMovie);
}
- oTarget.appendChild(_s.oMC);
- if (_isIE) {
- oEl = _s.oMC.appendChild(_doc.createElement('div'));
- oEl.className = _swfCSS.swfBox;
+ oTarget.appendChild(sm2.oMC);
+ if (isIE) {
+ oEl = sm2.oMC.appendChild(doc.createElement('div'));
+ oEl.className = swfCSS.swfBox;
oEl.innerHTML = movieHTML;
}
- _appendSuccess = true;
+ appendSuccess = true;
} catch(e) {
- throw new Error(_str('domError')+' \n'+e.toString());
+ throw new Error(str('domError')+' \n'+e.toString());
}
} else {
// SM2 container is already in the document (eg. flashblock use case)
- sClass = _s.oMC.className;
- _s.oMC.className = (sClass?sClass+' ':_swfCSS.swfDefault) + (extraClass?' '+extraClass:'');
- _s.oMC.appendChild(oMovie);
- if (_isIE) {
- oEl = _s.oMC.appendChild(_doc.createElement('div'));
- oEl.className = _swfCSS.swfBox;
+ sClass = sm2.oMC.className;
+ sm2.oMC.className = (sClass?sClass+' ':swfCSS.swfDefault) + (extraClass?' '+extraClass:'');
+ sm2.oMC.appendChild(oMovie);
+ if (isIE) {
+ oEl = sm2.oMC.appendChild(doc.createElement('div'));
+ oEl.className = swfCSS.swfBox;
oEl.innerHTML = movieHTML;
}
- _appendSuccess = true;
+ appendSuccess = true;
}
}
- _didAppend = true;
- _initMsg();
- _s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_overHTTP && _s.altURL?' (alternate URL)':''), 1);
+ didAppend = true;
+ initMsg();
+ // sm2._wD(sm + ': Trying to load ' + smURL + (!overHTTP && sm2.altURL ? ' (alternate URL)' : ''), 1);
return true;
};
- _initMovie = function() {
+ initMovie = function() {
- if (_s.html5Only) {
- _createMovie();
+ if (sm2.html5Only) {
+ createMovie();
return false;
}
// attempt to get, or create, movie (may already exist)
- if (_flash) {
+ if (flash) {
return false;
}
- if (!_s.url) {
+ if (!sm2.url) {
/**
* Something isn't right - we've reached init, but the soundManager url property has not been set.
* User has not called setup({url: ...}), or has not set soundManager.url (legacy use case) directly before init time.
* Notify and exit. If user calls setup() with a url: property, init will be restarted as in the deferred loading case.
@@ -5045,234 +5153,249 @@
return false;
}
// inline markup case
- _flash = _s.getMovie(_s.id);
+ flash = sm2.getMovie(sm2.id);
- if (!_flash) {
- if (!_oRemoved) {
+ if (!flash) {
+ if (!oRemoved) {
// try to create
- _createMovie(_s.id, _s.url);
+ createMovie(sm2.id, sm2.url);
} else {
// try to re-append removed movie after reboot()
- if (!_isIE) {
- _s.oMC.appendChild(_oRemoved);
+ if (!isIE) {
+ sm2.oMC.appendChild(oRemoved);
} else {
- _s.oMC.innerHTML = _oRemovedHTML;
+ sm2.oMC.innerHTML = oRemovedHTML;
}
- _oRemoved = null;
- _didAppend = true;
+ oRemoved = null;
+ didAppend = true;
}
- _flash = _s.getMovie(_s.id);
+ flash = sm2.getMovie(sm2.id);
}
- // <d>
- if (_flash) {
- _wDS('waitEI');
+ if (typeof sm2.oninitmovie === 'function') {
+ setTimeout(sm2.oninitmovie, 1);
}
+
+ // <d>
+ flushMessages();
// </d>
- if (typeof _s.oninitmovie === 'function') {
- setTimeout(_s.oninitmovie, 1);
- }
-
return true;
};
- _delayWaitForEI = function() {
+ delayWaitForEI = function() {
- setTimeout(_waitForEI, 1000);
+ setTimeout(waitForEI, 1000);
};
- _waitForEI = function() {
+ waitForEI = function() {
var p,
loadIncomplete = false;
- if (!_s.url) {
+ if (!sm2.url) {
// No SWF url to load (noURL case) - exit for now. Will be retried when url is set.
return false;
}
- if (_waitingForEI) {
+ if (waitingForEI) {
return false;
}
- _waitingForEI = true;
- _event.remove(_win, 'load', _delayWaitForEI);
+ waitingForEI = true;
+ event.remove(window, 'load', delayWaitForEI);
- if (_tryInitOnFocus && !_isFocused) {
+ if (tryInitOnFocus && !isFocused) {
// Safari won't load flash in background tabs, only when focused.
_wDS('waitFocus');
return false;
}
- if (!_didInit) {
- p = _s.getMoviePercent();
- _s._wD(_str('waitImpatient', (p > 0 ? ' (SWF ' + p + '% loaded)' : '')));
+ if (!didInit) {
+ p = sm2.getMoviePercent();
if (p > 0 && p < 100) {
loadIncomplete = true;
}
}
setTimeout(function() {
- p = _s.getMoviePercent();
+ p = sm2.getMoviePercent();
if (loadIncomplete) {
// special case: if movie *partially* loaded, retry until it's 100% before assuming failure.
- _waitingForEI = false;
- _s._wD(_str('waitSWF'));
- _win.setTimeout(_delayWaitForEI, 1);
+ waitingForEI = false;
+ sm2._wD(str('waitSWF'));
+ window.setTimeout(delayWaitForEI, 1);
return false;
}
// <d>
- if (!_didInit) {
- _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2);
- if (!_overHTTP && p) {
+ if (!didInit) {
+ sm2._wD(sm + ': No Flash response within expected time. Likely causes: ' + (p === 0 ? 'SWF load failed, ':'') + 'Flash blocked or JS-Flash security error.' + (sm2.debugFlash?' ' + str('checkSWF'):''), 2);
+ if (!overHTTP && p) {
_wDS('localFail', 2);
- if (!_s.debugFlash) {
+ if (!sm2.debugFlash) {
_wDS('tryDebug', 2);
}
}
if (p === 0) {
// if 0 (not null), probably a 404.
- _s._wD(_str('swf404', _s.url));
+ sm2._wD(str('swf404', sm2.url), 1);
}
- _debugTS('flashtojs', false, ': Timed out' + _overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');
+ debugTS('flashtojs', false, ': Timed out' + overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');
}
// </d>
// give up / time-out, depending
- if (!_didInit && _okToDisable) {
+ if (!didInit && okToDisable) {
if (p === null) {
// SWF failed. Maybe blocked.
- if (_s.useFlashBlock || _s.flashLoadTimeout === 0) {
- if (_s.useFlashBlock) {
- _flashBlockHandler();
+ if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) {
+ if (sm2.useFlashBlock) {
+ flashBlockHandler();
}
_wDS('waitForever');
} else {
- // old SM2 behaviour, simply fail
- _failSafely(true);
+ // no custom flash block handling, but SWF has timed out. Will recover if user unblocks / allows SWF load.
+ _wDS('waitForever');
+ // fire any regular registered ontimeout() listeners.
+ processOnEvents({type:'ontimeout', ignoreInit: true});
}
} else {
// flash loaded? Shouldn't be a blocking issue, then.
- if (_s.flashLoadTimeout === 0) {
+ if (sm2.flashLoadTimeout === 0) {
_wDS('waitForever');
} else {
- _failSafely(true);
+ failSafely(true);
}
}
}
- }, _s.flashLoadTimeout);
+ }, sm2.flashLoadTimeout);
};
- _handleFocus = function() {
+ handleFocus = function() {
function cleanup() {
- _event.remove(_win, 'focus', _handleFocus);
+ event.remove(window, 'focus', handleFocus);
}
- if (_isFocused || !_tryInitOnFocus) {
+ if (isFocused || !tryInitOnFocus) {
// already focused, or not special Safari background tab case
cleanup();
return true;
}
- _okToDisable = true;
- _isFocused = true;
+ okToDisable = true;
+ isFocused = true;
_wDS('gotFocus');
// allow init to restart
- _waitingForEI = false;
+ waitingForEI = false;
// kick off ExternalInterface timeout, now that the SWF has started
- _delayWaitForEI();
+ delayWaitForEI();
cleanup();
return true;
};
- _showSupport = function() {
+ flushMessages = function() {
// <d>
+ // SM2 pre-init debug messages
+ if (messages.length) {
+ sm2._wD('SoundManager 2: ' + messages.join(' '), 1);
+ messages = [];
+ }
+
+ // </d>
+
+ };
+
+ showSupport = function() {
+
+ // <d>
+
+ flushMessages();
+
var item, tests = [];
- if (_s.useHTML5Audio && _s.hasHTML5) {
- for (item in _s.audioFormats) {
- if (_s.audioFormats.hasOwnProperty(item)) {
- tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));
+ if (sm2.useHTML5Audio && sm2.hasHTML5) {
+ for (item in sm2.audioFormats) {
+ if (sm2.audioFormats.hasOwnProperty(item)) {
+ tests.push(item + ' = ' + sm2.html5[item] + (!sm2.html5[item] && hasFlash && sm2.flash[item] ? ' (using flash)' : (sm2.preferFlash && sm2.flash[item] && hasFlash ? ' (preferring flash)': (!sm2.html5[item] ? ' (' + (sm2.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));
}
}
- _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1);
+ sm2._wD('SoundManager 2 HTML5 support: ' + tests.join(', '), 1);
}
// </d>
};
- _initComplete = function(bNoDisable) {
+ initComplete = function(bNoDisable) {
- if (_didInit) {
+ if (didInit) {
return false;
}
- if (_s.html5Only) {
+ if (sm2.html5Only) {
// all good.
- _s._wD('-- SoundManager 2: loaded --');
- _didInit = true;
- _initUserOnload();
- _debugTS('onload', true);
+ _wDS('sm2Loaded');
+ didInit = true;
+ initUserOnload();
+ debugTS('onload', true);
return true;
}
- var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()),
+ var wasTimeout = (sm2.useFlashBlock && sm2.flashLoadTimeout && !sm2.getMoviePercent()),
result = true,
error;
if (!wasTimeout) {
- _didInit = true;
- if (_disabled) {
- error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
+ didInit = true;
+ if (disabled) {
+ error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
}
}
- _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'Flash security/load error':'OK') + ') --', 1);
+ sm2._wD('SoundManager 2 ' + (disabled ? 'failed to load' : 'loaded') + ' (' + (disabled ? 'Flash security/load error' : 'OK') + ')', disabled ? 2: 1);
- if (_disabled || bNoDisable) {
- if (_s.useFlashBlock && _s.oMC) {
- _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_swfCSS.swfTimedout:_swfCSS.swfError);
+ if (disabled || bNoDisable) {
+ if (sm2.useFlashBlock && sm2.oMC) {
+ sm2.oMC.className = getSWFCSS() + ' ' + (sm2.getMoviePercent() === null?swfCSS.swfTimedout:swfCSS.swfError);
}
- _processOnEvents({type:'ontimeout', error:error, ignoreInit: true});
- _debugTS('onload', false);
- _catchError(error);
+ processOnEvents({type:'ontimeout', error:error, ignoreInit: true});
+ debugTS('onload', false);
+ catchError(error);
result = false;
} else {
- _debugTS('onload', true);
+ debugTS('onload', true);
}
- if (!_disabled) {
- if (_s.waitForWindowLoad && !_windowLoaded) {
+ if (!disabled) {
+ if (sm2.waitForWindowLoad && !windowLoaded) {
_wDS('waitOnload');
- _event.add(_win, 'load', _initUserOnload);
+ event.add(window, 'load', initUserOnload);
} else {
// <d>
- if (_s.waitForWindowLoad && _windowLoaded) {
+ if (sm2.waitForWindowLoad && windowLoaded) {
_wDS('docLoaded');
}
// </d>
- _initUserOnload();
+ initUserOnload();
}
}
return result;
@@ -5281,126 +5404,122 @@
/**
* apply top-level setupOptions object as local properties, eg., this.setupOptions.flashVersion -> this.flashVersion (soundManager.flashVersion)
* this maintains backward compatibility, and allows properties to be defined separately for use by soundManager.setup().
*/
- _setProperties = function() {
+ setProperties = function() {
var i,
- o = _s.setupOptions;
+ o = sm2.setupOptions;
for (i in o) {
if (o.hasOwnProperty(i)) {
// assign local property if not already defined
- if (typeof _s[i] === 'undefined') {
+ if (sm2[i] === _undefined) {
- _s[i] = o[i];
+ sm2[i] = o[i];
- } else if (_s[i] !== o[i]) {
+ } else if (sm2[i] !== o[i]) {
// legacy support: write manually-assigned property (eg., soundManager.url) back to setupOptions to keep things in sync
- _s.setupOptions[i] = _s[i];
+ sm2.setupOptions[i] = sm2[i];
}
}
}
};
- _init = function() {
+ init = function() {
- _wDS('init');
-
// called after onload()
- if (_didInit) {
+ if (didInit) {
_wDS('didInit');
return false;
}
- function _cleanup() {
- _event.remove(_win, 'load', _s.beginDelayedInit);
+ function cleanup() {
+ event.remove(window, 'load', sm2.beginDelayedInit);
}
- if (_s.html5Only) {
- if (!_didInit) {
+ if (sm2.html5Only) {
+ if (!didInit) {
// we don't need no steenking flash!
- _cleanup();
- _s.enabled = true;
- _initComplete();
+ cleanup();
+ sm2.enabled = true;
+ initComplete();
}
return true;
}
// flash path
- _initMovie();
+ initMovie();
try {
- _wDS('flashJS');
-
// attempt to talk to Flash
- _flash._externalInterfaceTest(false);
+ flash._externalInterfaceTest(false);
// apply user-specified polling interval, OR, if "high performance" set, faster vs. default polling
// (determines frequency of whileloading/whileplaying callbacks, effectively driving UI framerates)
- _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50)));
+ setPolling(true, (sm2.flashPollingInterval || (sm2.useHighPerformance ? 10 : 50)));
- if (!_s.debugMode) {
+ if (!sm2.debugMode) {
// stop the SWF from making debug output calls to JS
- _flash._disableDebug();
+ flash._disableDebug();
}
- _s.enabled = true;
- _debugTS('jstoflash', true);
+ sm2.enabled = true;
+ debugTS('jstoflash', true);
- if (!_s.html5Only) {
+ if (!sm2.html5Only) {
// prevent browser from showing cached page state (or rather, restoring "suspended" page state) via back button, because flash may be dead
// http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
- _event.add(_win, 'unload', _doNothing);
+ event.add(window, 'unload', doNothing);
}
} catch(e) {
- _s._wD('js/flash exception: ' + e.toString());
- _debugTS('jstoflash', false);
- _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});
+ sm2._wD('js/flash exception: ' + e.toString());
+ debugTS('jstoflash', false);
+ catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});
// don't disable, for reboot()
- _failSafely(true);
- _initComplete();
+ failSafely(true);
+ initComplete();
return false;
}
- _initComplete();
+ initComplete();
// disconnect events
- _cleanup();
+ cleanup();
return true;
};
- _domContentLoaded = function() {
+ domContentLoaded = function() {
- if (_didDCLoaded) {
+ if (didDCLoaded) {
return false;
}
- _didDCLoaded = true;
+ didDCLoaded = true;
// assign top-level soundManager properties eg. soundManager.url
- _setProperties();
+ setProperties();
- _initDebug();
+ initDebug();
/**
* Temporary feature: allow force of HTML5 via URL params: sm2-usehtml5audio=0 or 1
* Ditto for sm2-preferFlash, too.
*/
@@ -5409,114 +5528,154 @@
var a = 'sm2-usehtml5audio=',
a2 = 'sm2-preferflash=',
b = null,
b2 = null,
- hasCon = (typeof console !== 'undefined' && typeof console.log === 'function'),
- l = _wl.toLowerCase();
+ hasCon = (window.console !== _undefined && typeof console.log === 'function'),
+ l = wl.toLowerCase();
if (l.indexOf(a) !== -1) {
b = (l.charAt(l.indexOf(a)+a.length) === '1');
if (hasCon) {
console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter');
}
- _s.setup({
+ sm2.setup({
'useHTML5Audio': b
});
}
if (l.indexOf(a2) !== -1) {
b2 = (l.charAt(l.indexOf(a2)+a2.length) === '1');
if (hasCon) {
console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter');
}
- _s.setup({
+ sm2.setup({
'preferFlash': b2
});
}
}());
// </d>
- if (!_hasFlash && _s.hasHTML5) {
- _s._wD('SoundManager: No Flash detected'+(!_s.useHTML5Audio?', enabling HTML5.':'. Trying HTML5-only mode.'));
- _s.setup({
+ if (!hasFlash && sm2.hasHTML5) {
+ sm2._wD('SoundManager: No Flash detected' + (!sm2.useHTML5Audio ? ', enabling HTML5.' : '. Trying HTML5-only mode.'), 1);
+ sm2.setup({
'useHTML5Audio': true,
// make sure we aren't preferring flash, either
// TODO: preferFlash should not matter if flash is not installed. Currently, stuff breaks without the below tweak.
'preferFlash': false
});
}
- _testHTML5();
- _s.html5.usingFlash = _featureCheck();
- _needsFlash = _s.html5.usingFlash;
- _showSupport();
+ testHTML5();
+ sm2.html5.usingFlash = featureCheck();
+ needsFlash = sm2.html5.usingFlash;
- if (!_hasFlash && _needsFlash) {
- _wDS('needFlash');
+ if (!hasFlash && needsFlash) {
+ messages.push(strings.needFlash);
// TODO: Fatal here vs. timeout approach, etc.
// hack: fail sooner.
- _s.setup({
+ sm2.setup({
'flashLoadTimeout': 1
});
}
- if (_doc.removeEventListener) {
- _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false);
+ if (doc.removeEventListener) {
+ doc.removeEventListener('DOMContentLoaded', domContentLoaded, false);
}
- _initMovie();
+ initMovie();
+
return true;
};
- _domContentLoadedIE = function() {
+ domContentLoadedIE = function() {
- if (_doc.readyState === 'complete') {
- _domContentLoaded();
- _doc.detachEvent('onreadystatechange', _domContentLoadedIE);
+ if (doc.readyState === 'complete') {
+ domContentLoaded();
+ doc.detachEvent('onreadystatechange', domContentLoadedIE);
}
return true;
};
- _winOnLoad = function() {
- // catch edge case of _initComplete() firing after window.load()
- _windowLoaded = true;
- _event.remove(_win, 'load', _winOnLoad);
+ winOnLoad = function() {
+
+ // catch edge case of initComplete() firing after window.load()
+ windowLoaded = true;
+ event.remove(window, 'load', winOnLoad);
+
};
+ /**
+ * miscellaneous run-time, pre-init stuff
+ */
+
+ preInit = function() {
+
+ if (mobileHTML5) {
+
+ // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point.
+
+ // <d>
+ if (!sm2.setupOptions.useHTML5Audio || sm2.setupOptions.preferFlash) {
+ // notify that defaults are being changed.
+ messages.push(strings.mobileUA);
+ }
+ // </d>
+
+ sm2.setupOptions.useHTML5Audio = true;
+ sm2.setupOptions.preferFlash = false;
+
+ if (is_iDevice || (isAndroid && !ua.match(/android\s2\.3/i))) {
+ // iOS and Android devices tend to work better with a single audio instance, specifically for chained playback of sounds in sequence.
+ // common use case: exiting sound onfinish() -> createSound() -> play()
+ // <d>
+ messages.push(strings.globalHTML5);
+ // </d>
+ if (is_iDevice) {
+ sm2.ignoreFlash = true;
+ }
+ useGlobalHTML5Audio = true;
+ }
+
+ }
+
+ };
+
+ preInit();
+
// sniff up-front
- _detectFlash();
+ detectFlash();
// focus and window load, init (primarily flash-driven)
- _event.add(_win, 'focus', _handleFocus);
- _event.add(_win, 'load', _delayWaitForEI);
- _event.add(_win, 'load', _winOnLoad);
+ event.add(window, 'focus', handleFocus);
+ event.add(window, 'load', delayWaitForEI);
+ event.add(window, 'load', winOnLoad);
- if (_doc.addEventListener) {
+ if (doc.addEventListener) {
- _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false);
+ doc.addEventListener('DOMContentLoaded', domContentLoaded, false);
- } else if (_doc.attachEvent) {
+ } else if (doc.attachEvent) {
- _doc.attachEvent('onreadystatechange', _domContentLoadedIE);
+ doc.attachEvent('onreadystatechange', domContentLoadedIE);
} else {
// no add/attachevent support - safe to assume no JS -> Flash either
- _debugTS('onload', false);
- _catchError({type:'NO_DOM2_EVENTS', fatal:true});
+ debugTS('onload', false);
+ catchError({type:'NO_DOM2_EVENTS', fatal:true});
}
} // SoundManager()
// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading
-if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) {
+if (window.SM2_DEFER === undefined || !SM2_DEFER) {
soundManager = new SoundManager();
}
/**
* SoundManager public interfaces
\ No newline at end of file