-
-
Save dandean/888831 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<script type="text/javascript" src="soundmanager/script/soundmanager2.js"></script> | |
<script type="text/javascript" src="index.js"></script> | |
<title>Grrrr!</title> | |
</head> | |
<body> | |
<p id="debug1">Nothing works! ♥</p> | |
<p id="debug2">i'm such a hipster these days i only use helvetica</p> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
soundManager.url = '/~dand/git/gist-888831/soundmanager/swf/'; | |
soundManager.flashVersion = 9; // optional: shiny features (default = 8) | |
soundManager.useFlashBlock = false; // optionally, enable when you're ready to dive in | |
soundManager.useHTML5Audio = true; | |
soundManager.onready(function() { | |
console.log("SoundManager is ready!"); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @license | |
SoundManager 2: JavaScript Sound for the Web | |
---------------------------------------------- | |
http://schillmania.com/projects/soundmanager2/ | |
Copyright (c) 2007, Scott Schiller. All rights reserved. | |
Code provided under the BSD License: | |
http://schillmania.com/projects/soundmanager2/license.txt | |
V2.97a.20110306 | |
*/ | |
(function(W){function ya(Pa,Qa){function r(c){return function(a){if(!this._t||!this._t._a){this._t&&this._t.sID?b._wD(o+"ignoring "+a.type+": "+this._t.sID):b._wD(o+"ignoring "+a.type);return null}else return c.call(this,a)}}function za(){if(b.debugURLParam.test(H))b.debugMode=true;if(v(b.debugID))return false;var c,a,f,h;if(b.debugMode&&!v(b.debugID)&&(!ha||!b.useConsole||b.useConsole&&ha&&!b.consoleOnly)){c=j.createElement("div");c.id=b.debugID+"-toggle";a={position:"fixed",bottom:"0px",right:"0px", | |
width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001};c.appendChild(j.createTextNode("-"));c.onclick=Aa;c.title="Toggle SM2 debug console";if(w.match(/msie 6/i)){c.style.position="absolute";c.style.cursor="hand"}for(h in a)if(a.hasOwnProperty(h))c.style[h]=a[h];a=j.createElement("div");a.id=b.debugID;a.style.display=b.debugMode?"block":"none";if(b.debugMode&&!v(c.id)){try{f=X();f.appendChild(c)}catch(e){throw Error(q("appXHTML")); | |
}f.appendChild(a)}}}this.flashVersion=8;this.debugMode=true;this.debugFlash=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.nullURL="about:blank";this.allowPolling=true;this.useFastPolling=false;this.useMovieStar=true;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useHTML5Audio=this.useFlashBlock=false;this.html5Test=/^probably$/i;this.useGlobalHTML5Audio= | |
true;this.requireFlash=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:true},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false, | |
loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,onbeforefinish:null,onbeforefinishtime:5E3,onbeforefinishcomplete:null,onjustbeforefinish:null,onjustbeforefinishtime:200,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions= | |
{bufferTime:3,serverURL:null,onconnect:null,duration:null};this.version=null;this.versionNumber="V2.97a.20110306";this.movieURL=null;this.url=Pa||null;this.altURL=null;this.enabled=this.swfLoaded=false;this.o=null;this.movieID="sm2-container";this.id=Qa||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"}; | |
this.oMC=null;this.sounds={};this.soundIDs=[];this.muted=false;this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.didFlashBlock=this.specialWmodeCase=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.baseMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamTypes=["aac","flv","mov","mp4","m4v","f4v","m4a","mp4v","3gp","3g2"];this.netStreamPattern= | |
RegExp("\\.("+this.netStreamTypes.join("|")+")(\\?.*)?$","i");this.mimePattern=this.baseMimeTypes;this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};this.hasHTML5= | |
null;this.html5={usingFlash:null};this.ignoreFlash=false;var ia,b=this,o="HTML5::",v,w=navigator.userAgent,n=W,H=n.location.href.toString(),p=this.flashVersion,j=document,ja,Y,C=[],ka=true,z,I=false,O=false,s=false,A=false,la=false,l,Ra=0,P,x,ma,E,J,na,Z,Ba,oa,F,Ca,$,Q,K,pa,X,aa,qa,Da,Sa=["log","info","warn","error"],Ea,ba,Fa,R=null,ra=null,q,sa,L,Aa,ca,da,ta,t,ea=false,ua=false,Ga,Ha,G=null,Ia,fa,y=false,S,D,va,Ja,u,Ka=Array.prototype.slice,T=false,ga,M,La,Ma=w.match(/pre\//i),Ta=w.match(/(ipad|iphone|ipod)/i); | |
w.match(/mobile/i);var B=w.match(/msie/i),Ua=w.match(/webkit/i),U=w.match(/safari/i)&&!w.match(/chrome/i),wa=!H.match(/usehtml5audio/i)&&!H.match(/sm2\-ignorebadua/i)&&U&&w.match(/OS X 10_6_(3|4|5|6)/i),ha=typeof console!=="undefined"&&typeof console.log!=="undefined",xa=typeof j.hasFocus!=="undefined"?j.hasFocus():null,N=typeof j.hasFocus==="undefined"&&U,Na=!N;this._use_maybe=H.match(/sm2\-useHTML5Maybe\=1/i);this._overHTTP=j.location?j.location.protocol.match(/http/i):null;this.useAltURL=!this._overHTTP; | |
this._global_a=null;if(Ta||Ma){b.useHTML5Audio=true;b.ignoreFlash=true;if(b.useGlobalHTML5Audio)T=true}if(Ma||this._use_maybe)b.html5Test=/^(probably|maybe)$/i;(function(){var c=H,a=null;if(c.indexOf("#sm2-usehtml5audio=")!==-1){a=c.charAt(c.indexOf("#sm2-usehtml5audio=")+19)==="1";if(typeof console!=="undefined"&&typeof console.log!=="undefined")console.log((a?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter");b.useHTML5Audio=a}})();this.supported=this.ok=function(){return G?s&&!A:b.useHTML5Audio&& | |
b.hasHTML5};this.getMovie=function(c){return B?n[c]:U?v(c)||j[c]:v(c)};this.createSound=function(c){function a(){f=ca(f);b.sounds[e.id]=new ia(e);b.soundIDs.push(e.id);return b.sounds[e.id]}var f=null,h=null,e=null;if(!s||!b.ok()){ta("soundManager.createSound(): "+q(!s?"notReady":"notOK"));return false}if(arguments.length===2)c={id:arguments[0],url:arguments[1]};e=f=x(c);e.id.toString().charAt(0).match(/^[0-9]$/)&&b._wD("soundManager.createSound(): "+q("badID",e.id),2);b._wD("soundManager.createSound(): "+ | |
e.id+" ("+e.url+")",1);if(t(e.id,true)){b._wD("soundManager.createSound(): "+e.id+" exists",1);return b.sounds[e.id]}if(fa(e)){h=a();b._wD("Loading sound "+e.id+" via HTML5");h._setup_html5(e)}else{if(p>8&&b.useMovieStar){if(e.isMovieStar===null)e.isMovieStar=e.serverURL||(e.type?e.type.match(b.netStreamPattern):false)||e.url.match(b.netStreamPattern)?true:false;e.isMovieStar&&b._wD("soundManager.createSound(): using MovieStar handling");if(e.isMovieStar){if(e.usePeakData){l("noPeak");e.usePeakData= | |
false}e.loops>1&&l("noNSLoop")}}e=da(e,"soundManager.createSound(): ");h=a();if(p===8)b.o._createSound(e.id,e.onjustbeforefinishtime,e.loops||1,e.usePolicyFile);else{b.o._createSound(e.id,e.url,e.onjustbeforefinishtime,e.usePeakData,e.useWaveformData,e.useEQData,e.isMovieStar,e.isMovieStar?e.bufferTime:false,e.loops||1,e.serverURL,e.duration||null,e.autoPlay,true,e.autoLoad,e.usePolicyFile);if(!e.serverURL){h.connected=true;e.onconnect&&e.onconnect.apply(h)}}if((e.autoLoad||e.autoPlay)&&!e.serverURL)h.load(e)}e.autoPlay&& | |
!e.serverURL&&h.play();return h};this.destroySound=function(c,a){if(!t(c))return false;var f=b.sounds[c],h;f._iO={};f.stop();f.unload();for(h=0;h<b.soundIDs.length;h++)if(b.soundIDs[h]===c){b.soundIDs.splice(h,1);break}a||f.destruct(true);delete b.sounds[c];return true};this.load=function(c,a){if(!t(c))return false;return b.sounds[c].load(a)};this.unload=function(c){if(!t(c))return false;return b.sounds[c].unload()};this.start=this.play=function(c,a){if(!s||!b.ok()){ta("soundManager.play(): "+q(!s? | |
"notReady":"notOK"));return false}if(!t(c)){a instanceof Object||(a={url:a});if(a&&a.url){b._wD('soundManager.play(): attempting to create "'+c+'"',1);a.id=c;return b.createSound(a).play()}else return false}return b.sounds[c].play(a)};this.setPosition=function(c,a){if(!t(c))return false;return b.sounds[c].setPosition(a)};this.stop=function(c){if(!t(c))return false;b._wD("soundManager.stop("+c+")",1);return b.sounds[c].stop()};this.stopAll=function(){b._wD("soundManager.stopAll()",1);for(var c in b.sounds)b.sounds[c]instanceof | |
ia&&b.sounds[c].stop()};this.pause=function(c){if(!t(c))return false;return b.sounds[c].pause()};this.pauseAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].pause()};this.resume=function(c){if(!t(c))return false;return b.sounds[c].resume()};this.resumeAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].resume()};this.togglePause=function(c){if(!t(c))return false;return b.sounds[c].togglePause()};this.setPan=function(c,a){if(!t(c))return false;return b.sounds[c].setPan(a)}; | |
this.setVolume=function(c,a){if(!t(c))return false;return b.sounds[c].setVolume(a)};this.mute=function(c){var a=0;if(typeof c!=="string")c=null;if(c){if(!t(c))return false;b._wD('soundManager.mute(): Muting "'+c+'"');return b.sounds[c].mute()}else{b._wD("soundManager.mute(): Muting all sounds");for(a=b.soundIDs.length;a--;)b.sounds[b.soundIDs[a]].mute();b.muted=true}return true};this.muteAll=function(){b.mute()};this.unmute=function(c){if(typeof c!=="string")c=null;if(c){if(!t(c))return false;b._wD('soundManager.unmute(): Unmuting "'+ | |
c+'"');return b.sounds[c].unmute()}else{b._wD("soundManager.unmute(): Unmuting all sounds");for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].unmute();b.muted=false}return true};this.unmuteAll=function(){b.unmute()};this.toggleMute=function(c){if(!t(c))return false;return b.sounds[c].toggleMute()};this.getMemoryUse=function(){if(p===8)return 0;if(b.o)return parseInt(b.o._getMemoryUse(),10)};this.disable=function(c){if(typeof c==="undefined")c=false;if(A)return false;A=true;l("shutdown",1);for(var a= | |
b.soundIDs.length;a--;)Ea(b.sounds[b.soundIDs[a]]);P(c);u.remove(n,"load",J);return true};this.canPlayMIME=function(c){var a;if(b.hasHTML5)a=S({type:c});return!G||a?a:c?c.match(b.mimePattern)?true:false:null};this.canPlayURL=function(c){var a;if(b.hasHTML5)a=S(c);return!G||a?a:c?c.match(b.filePattern)?true:false:null};this.canPlayLink=function(c){if(typeof c.type!=="undefined"&&c.type)if(b.canPlayMIME(c.type))return true;return b.canPlayURL(c.href)};this.getSoundById=function(c,a){if(!c)throw Error("soundManager.getSoundById(): sID is null/undefined"); | |
var f=b.sounds[c];!f&&!a&&b._wD('"'+c+'" is an invalid sound ID.',2);return f};this.onready=function(c,a){if(c&&c instanceof Function){s&&l("queue","onready");a||(a=n);ma("onready",c,a);E();return true}else throw q("needFunction","onready");};this.ontimeout=function(c,a){if(c&&c instanceof Function){s&&l("queue");a||(a=n);ma("ontimeout",c,a);E({type:"ontimeout"});return true}else throw q("needFunction","ontimeout");};this.getMoviePercent=function(){return b.o&&typeof b.o.PercentLoaded!=="undefined"? | |
b.o.PercentLoaded():null};this._wD=this._writeDebug=function(c,a,f){var h,e;if(!b.debugMode)return false;if(typeof f!=="undefined"&&f)c=c+" | "+(new Date).getTime();if(ha&&b.useConsole){f=Sa[a];typeof console[f]!=="undefined"?console[f](c):console.log(c);if(b.useConsoleOnly)return true}try{h=v("soundmanager-debug");if(!h)return false;e=j.createElement("div");if(++Ra%2===0)e.className="sm2-alt";a=typeof a==="undefined"?0:parseInt(a,10);e.appendChild(j.createTextNode(c));if(a){if(a>=2)e.style.fontWeight= | |
"bold";if(a===3)e.style.color="#ff3333"}h.insertBefore(e,h.firstChild)}catch(d){}return true};this._debug=function(){l("currentObj",1);for(var c=0,a=b.soundIDs.length;c<a;c++)b.sounds[b.soundIDs[c]]._debug()};this.reboot=function(){b._wD("soundManager.reboot()");b.soundIDs.length&&b._wD("Destroying "+b.soundIDs.length+" SMSound objects...");var c,a;for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].destruct();try{if(B)ra=b.o.innerHTML;R=b.o.parentNode.removeChild(b.o);b._wD("Flash movie removed.")}catch(f){l("badRemove", | |
2)}ra=R=null;b.enabled=s=ea=ua=I=O=A=b.swfLoaded=false;b.soundIDs=b.sounds=[];b.o=null;for(c in C)if(C.hasOwnProperty(c))for(a=C[c].length;a--;)C[c][a].fired=false;b._wD("soundManager: Rebooting...");n.setTimeout(function(){b.beginDelayedInit()},20)};this.destruct=function(){b._wD("soundManager.destruct()");b.disable(true)};this.beginDelayedInit=function(){la=true;K();setTimeout(Ca,20);Z()};this._html5_events={abort:r(function(){b._wD(o+"abort: "+this._t.sID)}),canplay:r(function(){b._wD(o+"canplay: "+ | |
this._t.sID+", "+this._t.url);this._t._onbufferchange(0);var c=!isNaN(this._t.position)?this._t.position/1E3:null;this._t._html5_canplay=true;if(this._t.position&&this.currentTime!==c){b._wD(o+"canplay: setting position to "+c+"");try{this.currentTime=c}catch(a){b._wD(o+"setting position failed: "+a.message,2)}}}),load:r(function(){if(!this._t.loaded){this._t._onbufferchange(0);this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration());this._t._onload(true)}}),emptied:r(function(){b._wD(o+ | |
"emptied: "+this._t.sID)}),ended:r(function(){b._wD(o+"ended: "+this._t.sID);this._t._onfinish()}),error:r(function(){b._wD(o+"error: "+this.error.code);this._t._onload(false)}),loadeddata:r(function(){b._wD(o+"loadeddata: "+this._t.sID)}),loadedmetadata:r(function(){b._wD(o+"loadedmetadata: "+this._t.sID)}),loadstart:r(function(){b._wD(o+"loadstart: "+this._t.sID);this._t._onbufferchange(1)}),play:r(function(){b._wD(o+"play: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0)}),playing:r(function(){b._wD(o+ | |
"playing: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0)}),progress:r(function(c){if(this._t.loaded)return false;var a,f,h;h=0;var e=c.type==="progress";f=c.target.buffered;var d=c.loaded||0,g=c.total||1;if(f&&f.length){for(a=f.length;a--;)h=f.end(a)-f.start(a);d=h/c.target.duration;if(e&&f.length>1){h=[];f=f.length;for(a=0;a<f;a++)h.push(c.target.buffered.start(a)+"-"+c.target.buffered.end(a));b._wD(o+"progress: timeRanges: "+h.join(", "))}e&&!isNaN(d)&&b._wD(o+"progress: "+this._t.sID+ | |
": "+Math.floor(d*100)+"% loaded")}if(!isNaN(d)){this._t._onbufferchange(0);this._t._whileloading(d,g,this._t._get_html5_duration());d&&g&&d===g&&b._html5_events.load.call(this,c)}}),ratechange:r(function(){b._wD(o+"ratechange: "+this._t.sID)}),suspend:r(function(c){b._wD(o+"suspend: "+this._t.sID);b._html5_events.progress.call(this,c)}),stalled:r(function(){b._wD(o+"stalled: "+this._t.sID)}),timeupdate:r(function(){this._t._onTimer()}),waiting:r(function(){b._wD(o+"waiting: "+this._t.sID);this._t._onbufferchange(1)})}; | |
ia=function(c){var a=this,f,h,e;this.sID=c.id;this.url=c.url;this._iO=this.instanceOptions=this.options=x(c);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){if(b.debugMode){var d=null,g=[],i,k;for(d in a.options)if(a.options[d]!==null)if(a.options[d]instanceof Function){i=a.options[d].toString();i=i.replace(/\s\s+/g," ");k=i.indexOf("{");g.push(" "+d+": {"+i.substr(k+1,Math.min(Math.max(i.indexOf("\n")- | |
1,64),64)).replace(/\n/g,"")+"... }")}else g.push(" "+d+": "+a.options[d]);b._wD("SMSound() merged options: {\n"+g.join(", \n")+"\n}")}};this._debug();this.load=function(d){var g=null;if(typeof d!=="undefined"){a._iO=x(d);a.instanceOptions=a._iO}else{d=a.options;a._iO=d;a.instanceOptions=a._iO;if(a._lastURL&&a._lastURL!==a.url){l("manURL");a._iO.url=a.url;a.url=null}}if(!a._iO.url)a._iO.url=a.url;b._wD("SMSound.load(): "+a._iO.url,1);if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2){l("onURL", | |
1);return a}a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(fa(a._iO)){g=a._setup_html5(a._iO);if(g._called_load)b._wD("HTML5 ignoring request to load again: "+a.sID);else{b._wD(o+"load: "+a.sID);g.load();g._called_load=true;a._iO.autoPlay&&a.play()}}else try{a.isHTML5=false;a._iO=da(ca(a._iO));p===8?b.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,a._iO.usePolicyFile):b.o._load(a.sID,a._iO.url,a._iO.stream?true:false,a._iO.autoPlay?true: | |
false,a._iO.loops||1,a._iO.autoLoad?true:false,a._iO.usePolicyFile)}catch(i){l("smError",2);z("onload",false);qa()}return a};this.unload=function(){if(a.readyState!==0){b._wD('SMSound.unload(): "'+a.sID+'"');if(a.isHTML5){h();if(a._a){a._a.pause();a._a.src=""}}else p===8?b.o._unload(a.sID,b.nullURL):b.o._unload(a.sID);f()}return a};this.destruct=function(d){b._wD('SMSound.destruct(): "'+a.sID+'"');if(a.isHTML5){h();if(a._a){a._a.pause();a._a.src="";T||a._remove_html5_events()}}else{a._iO.onfailure= | |
null;b.o._destroySound(a.sID)}d||b.destroySound(a.sID,true)};this.start=this.play=function(d,g){var i;g=g===undefined?true:g;d||(d={});a._iO=x(d,a._iO);a._iO=x(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL)if(!a.connected){if(!a.getAutoPlay()){b._wD("SMSound.play(): Netstream not connected yet - setting autoPlay");a.setAutoPlay(true)}return a}if(fa(a._iO)){a._setup_html5(a._iO);e()}if(a.playState===1&&!a.paused)if(i=a._iO.multiShot){b._wD('SMSound.play(): "'+a.sID+'" already playing (multi-shot)', | |
1);a.isHTML5&&a.setPosition(a._iO.position)}else{b._wD('SMSound.play(): "'+a.sID+'" already playing (one-shot)',1);return a}if(a.loaded)b._wD('SMSound.play(): "'+a.sID+'"');else if(a.readyState===0){b._wD('SMSound.play(): Attempting to load "'+a.sID+'"',1);if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2){b._wD('SMSound.play(): Could not load "'+a.sID+'" - exiting',2);return a}else b._wD('SMSound.play(): "'+a.sID+'" is loading - attempting to play..',1);if(a.paused&&a.position&& | |
a.position>0){b._wD('SMSound.play(): "'+a.sID+'" is resuming from paused state',1);a.resume()}else{b._wD('SMSound.play(): "'+a.sID+'" is starting to play');a.playState=1;a.paused=false;if(!a.instanceCount||a._iO.multiShotEvents||p>8&&!a.isHTML5&&!a.getAutoPlay())a.instanceCount++;a.position=typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=da(ca(a._iO));if(a._iO.onplay&&g){a._iO.onplay.apply(a);a._onplay_called=true}a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan, | |
true);if(a.isHTML5){e();a._setup_html5().play()}else b.o._start(a.sID,a._iO.loops||1,p===9?a.position:a.position/1E3)}return a};this.stop=function(d){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);if(!a.isHTML5)a.playState=0;a.paused=false;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(a._a){a.setPosition(0);a._a.pause();a.playState=0;a._onTimer();h();a.unload()}}else{b.o._stop(a.sID,d);a._iO.serverURL&&a.unload()}a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(d){b._wD("sound "+ | |
a.sID+" turned autoplay "+(d?"on":"off"));a._iO.autoPlay=d;if(a.isHTML5)a._a&&d&&a.play();else b.o._setAutoPlay(a.sID,d);if(d)if(!a.instanceCount&&a.readyState===1){a.instanceCount++;b._wD("sound "+a.sID+" incremented instance count to "+a.instanceCount)}};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(d){if(d===undefined)d=0;var g=a.isHTML5?Math.max(d,0):Math.min(a.duration||a._iO.duration,Math.max(d,0));a.position=g;d=a.position/1E3;a.resetOnPosition(a.position);a._iO.position= | |
g;if(a.isHTML5){if(a._a)if(a._html5_canplay){if(a._a.currentTime!==d){b._wD("setPosition("+d+"): setting position");try{a._a.currentTime=d}catch(i){b._wD("setPosition("+d+"): setting position failed: "+i.message,2)}}}else b._wD("setPosition("+d+"): delaying, sound not ready")}else{d=p===9?a.position:d;if(a.readyState&&a.readyState!==2)b.o._setPosition(a.sID,d,a.paused||!a.playState)}a.isHTML5&&a.paused&&a._onTimer(true);return a};this.pause=function(d){if(a.paused||a.playState===0&&a.readyState!== | |
1)return a;b._wD("SMSound.pause()");a.paused=true;if(a.isHTML5){a._setup_html5().pause();h()}else if(d||d===undefined)b.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;b._wD("SMSound.resume()");a.paused=false;a.playState=1;if(a.isHTML5){a._setup_html5().play();e()}else{a._iO.isMovieStar&&a.setPosition(a.position);b.o._pause(a.sID)}if(!a._onplay_called&&a._iO.onplay){a._iO.onplay.apply(a);a._onplay_called=true}else a._iO.onresume&&a._iO.onresume.apply(a); | |
return a};this.togglePause=function(){b._wD("SMSound.togglePause()");if(a.playState===0){a.play({position:p===9&&!a.isHTML5?a.position:a.position/1E3});return a}a.paused?a.resume():a.pause();return a};this.setPan=function(d,g){if(typeof d==="undefined")d=0;if(typeof g==="undefined")g=false;a.isHTML5||b.o._setPan(a.sID,d);a._iO.pan=d;if(!g)a.pan=d;return a};this.setVolume=function(d,g){if(typeof d==="undefined")d=100;if(typeof g==="undefined")g=false;if(a.isHTML5){if(a._a)a._a.volume=d/100}else b.o._setVolume(a.sID, | |
b.muted&&!a.muted||a.muted?0:d);a._iO.volume=d;if(!g)a.volume=d;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else b.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var d=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else b.o._setVolume(a.sID,d?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(d,g,i){a._onPositionItems.push({position:d, | |
method:g,scope:typeof i!=="undefined"?i:a,fired:false});return a};this.processOnPosition=function(){var d,g;d=a._onPositionItems.length;if(!d||!a.playState||a._onPositionFired>=d)return false;for(d=d;d--;){g=a._onPositionItems[d];if(!g.fired&&a.position>=g.position){g.method.apply(g.scope,[g.position]);g.fired=true;b._onPositionFired++}}return true};this.resetOnPosition=function(d){var g,i;g=a._onPositionItems.length;if(!g)return false;for(g=g;g--;){i=a._onPositionItems[g];if(i.fired&&d<=i.position){i.fired= | |
false;b._onPositionFired--}}return true};this._onTimer=function(d){var g={};if(a._hasTimer||d)if(a._a&&(d||(a.playState>0||a.readyState===1)&&!a.paused)){a.duration=a._get_html5_duration();a.durationEstimate=a.duration;d=a._a.currentTime?a._a.currentTime*1E3:0;a._whileplaying(d,g,g,g,g);return true}else{b._wD('_onTimer: Warn for "'+a.sID+'": '+(!a._a?"Could not find element. ":"")+(a.playState===0?"playState bad, 0?":"playState = "+a.playState+", OK"));return false}};this._get_html5_duration=function(){var d= | |
a._a?a._a.duration*1E3:a._iO?a._iO.duration:undefined;return d&&!isNaN(d)&&d!==Infinity?d:a._iO?a._iO.duration:null};e=function(){a.isHTML5&&Ga(a)};h=function(){a.isHTML5&&Ha(a)};f=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState= | |
0;a.muted=false;a.didBeforeFinish=false;a.didJustBeforeFinish=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=[];a.eqData.left=[];a.eqData.right=[]};f();this._setup_html5=function(d){d=x(a._iO,d);var g=decodeURI,i=T?b._global_a:a._a,k=g(d.url),m=i&&i._t?i._t.instanceOptions:null;if(i){if(i._t&&m.url===d.url)return i;b._wD("setting new URL on existing object: "+k+", old URL: "+g(m.url));T&&i._t.playState&&i._t&& | |
d.url!==m.url&&i._t.stop();f();i.src=d.url}else{b._wD("creating HTML5 Audio() element with URL: "+k);i=new Audio(d.url);if(T)b._global_a=i}i._called_load=false;a.isHTML5=true;a._a=i;i._t=a;a._add_html5_events();i.loop=d.loops>1?"loop":"";if(d.autoLoad||d.autoPlay){i.autobuffer="auto";i.preload="auto";a.load()}else{i.autobuffer=false;i.preload="none"}i.loop=d.loops>1?"loop":"";return i};this._add_html5_events=function(){if(a._a._added_events)return false;var d;b._wD(o+"adding event listeners: "+a.sID); | |
a._a._added_events=true;for(d in b._html5_events)b._html5_events.hasOwnProperty(d)&&a._a&&a._a.addEventListener(d,b._html5_events[d],false);return true};this._remove_html5_events=function(){b._wD(o+"removing event listeners: "+a.sID);a._a._added_events=false;for(var d in b._html5_events)b._html5_events.hasOwnProperty(d)&&a._a&&a._a.removeEventListener(d,b._html5_events[d],false)};this._whileloading=function(d,g,i,k){a.bytesLoaded=d;a.bytesTotal=g;a.duration=Math.floor(i);a.bufferLength=k;if(a._iO.isMovieStar)a.durationEstimate= | |
a.duration;else{a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10);if(a.durationEstimate===undefined)a.durationEstimate=a.duration}a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._onid3=function(d,g){b._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.');var i=[],k,m;k=0;for(m=d.length;k<m;k++)i[d[k]]=g[k];a.id3=x(a.id3,i);a._iO.onid3&&a._iO.onid3.apply(a)};this._whileplaying=function(d, | |
g,i,k,m){if(isNaN(d)||d===null)return false;if(a.playState===0&&d>0)d=0;a.position=d;a.processOnPosition();if(p>8&&!a.isHTML5){if(a._iO.usePeakData&&typeof g!=="undefined"&&g)a.peakData={left:g.leftPeak,right:g.rightPeak};if(a._iO.useWaveformData&&typeof i!=="undefined"&&i)a.waveformData={left:i.split(","),right:k.split(",")};if(a._iO.useEQData)if(typeof m!=="undefined"&&m&&m.leftEQ){d=m.leftEQ.split(",");a.eqData=d;a.eqData.left=d;if(typeof m.rightEQ!=="undefined"&&m.rightEQ)a.eqData.right=m.rightEQ.split(",")}}if(a.playState=== | |
1){!a.isHTML5&&b.flashVersion===8&&!a.position&&a.isBuffering&&a._onbufferchange(0);a._iO.whileplaying&&a._iO.whileplaying.apply(a);if((a.loaded||!a.loaded&&a._iO.isMovieStar)&&a._iO.onbeforefinish&&a._iO.onbeforefinishtime&&!a.didBeforeFinish&&a.duration-a.position<=a._iO.onbeforefinishtime)a._onbeforefinish()}return true};this._onconnect=function(d){d=d===1;b._wD('SMSound._onconnect(): "'+a.sID+'"'+(d?" connected.":" failed to connect? - "+a.url),d?1:2);if(a.connected=d){a.failures=0;if(t(a.sID))if(a.getAutoPlay())a.play(undefined, | |
a.getAutoPlay());else a._iO.autoLoad&&a.load();a._iO.onconnect&&a._iO.onconnect.apply(a,[d])}};this._onload=function(d){d=d?true:false;b._wD('SMSound._onload(): "'+a.sID+'"'+(d?" loaded.":" failed to load? - "+a.url),d?1:2);if(!d&&!a.isHTML5){b.sandbox.noRemote===true&&b._wD("SMSound._onload(): "+q("noNet"),1);b.sandbox.noLocal===true&&b._wD("SMSound._onload(): "+q("noLocal"),1)}a.loaded=d;a.readyState=d?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[d]);return true};this._onfailure= | |
function(d,g,i){a.failures++;b._wD('SMSound._onfailure(): "'+a.sID+'" count '+a.failures);a._iO.onfailure&&a.failures===1?a._iO.onfailure(a,d,g,i):b._wD("SMSound._onfailure(): ignoring")};this._onbeforefinish=function(){if(!a.didBeforeFinish){a.didBeforeFinish=true;if(a._iO.onbeforefinish){b._wD('SMSound._onbeforefinish(): "'+a.sID+'"');a._iO.onbeforefinish.apply(a)}}};this._onjustbeforefinish=function(){if(!a.didJustBeforeFinish){a.didJustBeforeFinish=true;if(a._iO.onjustbeforefinish){b._wD('SMSound._onjustbeforefinish(): "'+ | |
a.sID+'"');a._iO.onjustbeforefinish.apply(a)}}};this._onfinish=function(){var d=a._iO.onfinish;a._onbufferchange(0);a.resetOnPosition(0);a._iO.onbeforefinishcomplete&&a._iO.onbeforefinishcomplete.apply(a);a.didBeforeFinish=false;a.didJustBeforeFinish=false;if(a.instanceCount){a.instanceCount--;if(!a.instanceCount){a.playState=0;a.paused=false;a.instanceCount=0;a.instanceOptions={};a._iO={};h()}if(!a.instanceCount||a._iO.multiShotEvents)if(d){b._wD('SMSound._onfinish(): "'+a.sID+'"');d.apply(a)}}}; | |
this._onbufferchange=function(d){if(a.playState===0)return false;if(d&&a.isBuffering||!d&&!a.isBuffering)return false;a.isBuffering=d===1;if(a._iO.onbufferchange){b._wD("SMSound._onbufferchange(): "+d);a._iO.onbufferchange.apply(a)}return true};this._ondataerror=function(d){if(a.playState>0){b._wD("SMSound._ondataerror(): "+d);a._iO.ondataerror&&a._iO.ondataerror.apply(a)}}};X=function(){return j.body?j.body:j._docElement?j.documentElement:j.getElementsByTagName("div")[0]};v=function(c){return j.getElementById(c)}; | |
x=function(c,a){var f={},h,e;for(h in c)if(c.hasOwnProperty(h))f[h]=c[h];h=typeof a==="undefined"?b.defaultOptions:a;for(e in h)if(h.hasOwnProperty(e)&&typeof f[e]==="undefined")f[e]=h[e];return f};u=function(){function c(e){e=Ka.call(e);var d=e.length;if(f){e[1]="on"+e[1];d>3&&e.pop()}else d===3&&e.push(false);return e}function a(e,d){var g=e.shift(),i=[h[d]];f?g[i](e[0],e[1]):g[i].apply(g,e)}var f=n.attachEvent,h={add:f?"attachEvent":"addEventListener",remove:f?"detachEvent":"removeEventListener"}; | |
return{add:function(){a(c(arguments),"add")},remove:function(){a(c(arguments),"remove")}}}();fa=function(c){return!c.serverURL&&(c.type?S({type:c.type}):S(c.url)||y)};S=function(c){if(!b.useHTML5Audio||!b.hasHTML5)return false;var a,f=b.audioFormats;if(!D){D=[];for(a in f)if(f.hasOwnProperty(a)){D.push(a);if(f[a].related)D=D.concat(f[a].related)}D=RegExp("\\.("+D.join("|")+")","i")}a=typeof c.type!=="undefined"?c.type:null;c=typeof c==="string"?c.toLowerCase().match(D):null;if(!c||!c.length)if(a){c= | |
a.indexOf(";");c=(c!==-1?a.substr(0,c):a).substr(6)}else return false;else c=c[0].substr(1);if(c&&typeof b.html5[c]!=="undefined")return b.html5[c];else{if(!a)if(c&&b.html5[c])return b.html5[c];else a="audio/"+c;a=b.html5.canPlayType(a);return b.html5[c]=a}};Ja=function(){function c(g){var i,k,m=false;if(!a||typeof a.canPlayType!=="function")return false;if(g instanceof Array){i=0;for(k=g.length;i<k&&!m;i++)if(b.html5[g[i]]||a.canPlayType(g[i]).match(b.html5Test)){m=true;b.html5[g[i]]=true}return m}else return(g= | |
a&&typeof a.canPlayType==="function"?a.canPlayType(g):false)&&(g.match(b.html5Test)?true:false)}if(!b.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?new Audio(null):null,f,h={},e,d;M();e=b.audioFormats;for(f in e)if(e.hasOwnProperty(f)){h[f]=c(e[f].type);if(e[f]&&e[f].related)for(d=e[f].related.length;d--;)b.html5[e[f].related[d]]=h[f]}h.canPlayType=a?c:null;b.html5=x(b.html5,h);return true};$={notReady:"Not loaded yet - wait for soundManager.onload()/onready()", | |
notOK:"Audio support is not available.",appXHTML:"soundManager::createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.",spcWmode:"soundManager::createMovie(): Removing wmode, preventing known SWF loading issue(s)",swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+j.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:"soundManager: Special case: Waiting for focus-related event..",waitImpatient:"soundManager: Getting impatient, still waiting for Flash%s...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",needFunction:"soundManager: Function object expected for %s",badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',noMS:"MovieStar mode not enabled. Exiting.",currentObj:"--- soundManager._debug(): Current sound objects ---", | |
waitEI:"soundManager::initMovie(): Waiting for ExternalInterface call from Flash..",waitOnload:"soundManager: Waiting for window.onload()",docLoaded:"soundManager: Document already loaded",onload:"soundManager::initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",init:"-- soundManager::init() --",didInit:"soundManager::init(): Already called?",flashJS:"soundManager: Attempting to call Flash from JS..",noPolling:"soundManager: Polling (whileloading()/whileplaying() support) is disabled.", | |
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.",noPeak:"Warning: peakData features unsupported for movieStar formats",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smFail:"soundManager: Failed to initialise.", | |
smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+b.swfCSS.swfTimedout+" CSS..",fbLoaded:"Flash loaded",fbHandler:"soundManager::flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:"soundManager.load(): current URL already assigned.",badFV:'soundManager.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",mfOn:"mobileFlash::enabling on-screen flash repositioning",policy:"Enabling usePolicyFile for data access"};q=function(){var c=Ka.call(arguments),a=c.shift();a=$&&$[a]?$[a]:"";var f,h;if(a&&c&&c.length){f=0;for(h=c.length;f<h;f++)a=a.replace("%s",c[f])}return a};ca=function(c){if(p===8&&c.loops>1&&c.stream){l("as2loop");c.stream=false}return c};da=function(c, | |
a){if(c&&!c.usePolicyFile&&(c.onid3||c.usePeakData||c.useWaveformData||c.useEQData)){b._wD((a?a+":":"")+q("policy"));c.usePolicyFile=true}return c};ta=function(c){typeof console!=="undefined"&&typeof console.warn!=="undefined"?console.warn(c):b._wD(c)};ja=function(){return false};Ea=function(c){for(var a in c)if(c.hasOwnProperty(a)&&typeof c[a]==="function")c[a]=ja};ba=function(c){if(typeof c==="undefined")c=false;if(A||c){l("smFail",2);b.disable(c)}};Fa=function(c){var a=null;if(c)if(c.match(/\.swf(\?.*)?$/i)){if(a= | |
c.substr(c.toLowerCase().lastIndexOf(".swf?")+4))return c}else if(c.lastIndexOf("/")!==c.length-1)c+="/";return(c&&c.lastIndexOf("/")!==-1?c.substr(0,c.lastIndexOf("/")+1):"./")+b.movieURL};oa=function(){if(p!==8&&p!==9){b._wD(q("badFV",p,8));b.flashVersion=8}var c=b.debugMode||b.debugFlash?"_debug.swf":".swf";if(b.useHTML5Audio&&!y&&b.audioFormats.mp4.required&&b.flashVersion<9){b._wD(q("needfl9"));b.flashVersion=9}p=b.flashVersion;b.version=b.versionNumber+(y?" (HTML5-only mode)":p===9?" (AS3/Flash 9)": | |
" (AS2/Flash 8)");if(p>8){b.defaultOptions=x(b.defaultOptions,b.flash9Options);b.features.buffering=true}if(p>8&&b.useMovieStar){b.defaultOptions=x(b.defaultOptions,b.movieStarOptions);b.filePatterns.flash9=RegExp("\\.(mp3|"+b.netStreamTypes.join("|")+")(\\?.*)?$","i");b.mimePattern=b.netStreamMimeTypes;b.features.movieStar=true}else{b.useMovieStar=false;b.features.movieStar=false}b.filePattern=b.filePatterns[p!==8?"flash9":"flash8"];b.movieURL=(p===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf", | |
c);b.features.peakData=b.features.waveformData=b.features.eqData=p>8};Da=function(c,a){if(!b.o||!b.allowPolling)return false;b.o._setPolling(c,a)};aa=function(c,a){function f(){b._wD("-- SoundManager 2 "+b.version+(!y&&b.useHTML5Audio?b.hasHTML5?" + HTML5 audio":", no HTML5 audio support":"")+(!y?(b.useMovieStar?", MovieStar mode":"")+(b.useHighPerformance?", high performance mode, ":", ")+((b.flashPollingInterval?"custom ("+b.flashPollingInterval+"ms)":b.useFastPolling?"fast":"normal")+" polling")+ | |
(b.wmode?", wmode: "+b.wmode:"")+(b.debugFlash?", flash debug mode":"")+(b.useFlashBlock?", flashBlock mode":""):"")+" --",1)}var h=a?a:b.url,e=b.altURL?b.altURL:h,d;d=X();var g,i,k=L(),m,V=null;V=(V=j.getElementsByTagName("html")[0])&&V.dir&&V.dir.match(/rtl/i);c=typeof c==="undefined"?b.id:c;if(I&&O)return false;if(y){oa();f();b.oMC=v(b.movieID);Y();O=I=true;return false}I=true;oa();b.url=Fa(b._overHTTP?h:e);a=b.url;b.wmode=!b.wmode&&b.useHighPerformance&&!b.useMovieStar?"transparent":b.wmode;if(b.wmode!== | |
null&&(w.match(/msie 8/i)||!B&&!b.useHighPerformance)&&navigator.platform.match(/win32|win64/i)){b.specialWmodeCase=true;l("spcWmode");b.wmode=null}d={name:c,id:c,src:a,width:"100%",height:"100%",quality:"high",allowScriptAccess:b.allowScriptAccess,bgcolor:b.bgColor,pluginspage:"http://www.macromedia.com/go/getflashplayer",type:"application/x-shockwave-flash",wmode:b.wmode,hasPriority:"true"};if(b.debugFlash)d.FlashVars="debug=1";b.wmode||delete d.wmode;if(B){h=j.createElement("div");i='<object id="'+ | |
c+'" data="'+a+'" type="'+d.type+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+d.width+'" height="'+d.height+'"><param name="movie" value="'+a+'" /><param name="AllowScriptAccess" value="'+b.allowScriptAccess+'" /><param name="quality" value="'+d.quality+'" />'+(b.wmode?'<param name="wmode" value="'+b.wmode+'" /> ':"")+'<param name="bgcolor" value="'+b.bgColor+'" />'+(b.debugFlash?'<param name="FlashVars" value="'+ | |
d.FlashVars+'" />':"")+"</object>"}else{h=j.createElement("embed");for(g in d)d.hasOwnProperty(g)&&h.setAttribute(g,d[g])}za();k=L();if(d=X()){b.oMC=v(b.movieID)?v(b.movieID):j.createElement("div");if(b.oMC.id){m=b.oMC.className;b.oMC.className=(m?m+" ":b.swfCSS.swfDefault)+(k?" "+k:"");b.oMC.appendChild(h);if(B){g=b.oMC.appendChild(j.createElement("div"));g.className=b.swfCSS.swfBox;g.innerHTML=i}O=true}else{b.oMC.id=b.movieID;b.oMC.className=b.swfCSS.swfDefault+" "+k;g=k=null;if(!b.useFlashBlock)if(b.useHighPerformance)k= | |
{position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else{k={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"};if(V)k.left=Math.abs(parseInt(k.left,10))+"px"}if(Ua)b.oMC.style.zIndex=1E4;if(!b.debugFlash)for(m in k)if(k.hasOwnProperty(m))b.oMC.style[m]=k[m];try{B||b.oMC.appendChild(h);d.appendChild(b.oMC);if(B){g=b.oMC.appendChild(j.createElement("div"));g.className=b.swfCSS.swfBox;g.innerHTML=i}O=true}catch(Va){throw Error(q("appXHTML")); | |
}}}f();b._wD("soundManager::createMovie(): Trying to load "+a+(!b._overHTTP&&b.altURL?" (alternate URL)":""),1);return true};t=this.getSoundById;Q=function(){if(y){aa();return false}if(b.o)return false;b.o=b.getMovie(b.id);if(!b.o){if(R){if(B)b.oMC.innerHTML=ra;else b.oMC.appendChild(R);R=null;I=true}else aa(b.id,b.url);b.o=b.getMovie(b.id)}if(b.o){b._wD("soundManager::initMovie(): Got "+b.o.nodeName+" element ("+(I?"created via JS":"static HTML")+")");l("waitEI")}b.oninitmovie instanceof Function&& | |
setTimeout(b.oninitmovie,1);return true};na=function(c){if(c)b.url=c;Q()};Z=function(){setTimeout(Ba,500)};Ba=function(){if(ea)return false;ea=true;u.remove(n,"load",Z);if(N&&!xa){l("waitFocus");return false}var c;if(!s){c=b.getMoviePercent();b._wD(q("waitImpatient",c===100?" (SWF loaded)":c>0?" (SWF "+c+"% loaded)":""))}setTimeout(function(){c=b.getMoviePercent();if(!s){b._wD("soundManager: No Flash response within expected time.\nLikely causes: "+(c===0?"Loading "+b.movieURL+" may have failed (and/or Flash "+ | |
p+"+ not present?), ":"")+"Flash blocked or JS-Flash security error."+(b.debugFlash?" "+q("checkSWF"):""),2);if(!b._overHTTP&&c){l("localFail",2);b.debugFlash||l("tryDebug",2)}c===0&&b._wD(q("swf404",b.url));z("flashtojs",false,": Timed out"+b._overHTTP?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)")}if(!s&&Na)if(c===null)if(b.useFlashBlock||b.flashLoadTimeout===0){b.useFlashBlock&&sa();l("waitForever")}else ba(true);else b.flashLoadTimeout===0?l("waitForever"):ba(true)}, | |
b.flashLoadTimeout)};na=function(c){if(c)b.url=c;Q()};l=function(c,a){return c?b._wD(q(c),a):""};if(H.indexOf("debug=alert")+1&&b.debugMode)b._wD=function(c){W.alert(c)};Aa=function(){var c=v(b.debugID),a=v(b.debugID+"-toggle");if(!c)return false;if(ka){a.innerHTML="+";c.style.display="none"}else{a.innerHTML="-";c.style.display="block"}ka=!ka};z=function(c,a,f){if(typeof sm2Debugger!=="undefined")try{sm2Debugger.handleEvent(c,a,f)}catch(h){}return true};L=function(){var c=[];b.debugMode&&c.push(b.swfCSS.sm2Debug); | |
b.debugFlash&&c.push(b.swfCSS.flashDebug);b.useHighPerformance&&c.push(b.swfCSS.highPerf);return c.join(" ")};sa=function(){var c=q("fbHandler"),a=b.getMoviePercent(),f=b.swfCSS;if(b.ok()){b.didFlashBlock&&b._wD(c+": Unblocked");if(b.oMC)b.oMC.className=[L(),f.swfDefault,f.swfLoaded+(b.didFlashBlock?" "+f.swfUnblocked:"")].join(" ")}else{if(G){b.oMC.className=L()+" "+f.swfDefault+" "+(a===null?f.swfTimedout:f.swfError);b._wD(c+": "+q("fbTimeout")+(a?" ("+q("fbLoaded")+")":""))}b.didFlashBlock=true; | |
E({type:"ontimeout",ignoreInit:true});b.onerror instanceof Function&&b.onerror.apply(n)}};F=function(){function c(){u.remove(n,"focus",F);u.remove(n,"load",F)}if(xa||!N){c();return true}xa=Na=true;b._wD("soundManager::handleFocus()");U&&N&&u.remove(n,"mousemove",F);ea=false;c();return true};P=function(c){if(s)return false;if(y){b._wD("-- SoundManager 2: loaded --");s=true;E();J();return true}b.useFlashBlock&&b.flashLoadTimeout&&!b.getMoviePercent()||(s=true);b._wD("-- SoundManager 2 "+(A?"failed to load": | |
"loaded")+" ("+(A?"security/load error":"OK")+") --",1);if(A||c){if(b.useFlashBlock)b.oMC.className=L()+" "+(b.getMoviePercent()===null?b.swfCSS.swfTimedout:b.swfCSS.swfError);E({type:"ontimeout"});z("onload",false);b.onerror instanceof Function&&b.onerror.apply(n);return false}else z("onload",true);u.add(n,"unload",ja);if(b.waitForWindowLoad&&!la){l("waitOnload");u.add(n,"load",J);return false}else{b.waitForWindowLoad&&la&&l("docLoaded");J()}return true};ma=function(c,a,f){if(typeof C[c]==="undefined")C[c]= | |
[];C[c].push({method:a,scope:f||null,fired:false})};E=function(c){c||(c={type:"onready"});if(!s&&c&&!c.ignoreInit)return false;var a={success:c&&c.ignoreInit?b.ok():!A},f=c&&c.type?C[c.type]||[]:[],h=[],e,d=G&&b.useFlashBlock&&!b.ok();for(e=0;e<f.length;e++)f[e].fired!==true&&h.push(f[e]);if(h.length){b._wD("soundManager: Firing "+h.length+" "+c.type+"() item"+(h.length===1?"":"s"));e=0;for(c=h.length;e<c;e++){h[e].scope?h[e].method.apply(h[e].scope,[a]):h[e].method(a);if(!d)h[e].fired=true}}return true}; | |
J=function(){n.setTimeout(function(){b.useFlashBlock&&sa();E();if(b.onload instanceof Function){l("onload",1);b.onload.apply(n);l("onloadOK",1)}b.waitForWindowLoad&&u.add(n,"load",J)},1)};M=function(){if(ga!==undefined)return ga;var c=false,a=navigator,f=a.plugins,h,e=n.ActiveXObject;if(f&&f.length){if((a=a.mimeTypes)&&a["application/x-shockwave-flash"]&&a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description)c=true}else if(typeof e!=="undefined"){try{h= | |
new e("ShockwaveFlash.ShockwaveFlash")}catch(d){}c=!!h}return ga=c};Ia=function(){var c,a;if(w.match(/iphone os (1|2|3_0|3_1)/i)?true:false){b.hasHTML5=false;y=true;if(b.oMC)b.oMC.style.display="none";return false}if(b.useHTML5Audio){if(!b.html5||!b.html5.canPlayType){b._wD("SoundManager: No HTML5 Audio() support detected.");b.hasHTML5=false;return true}else b.hasHTML5=true;if(wa){b._wD("soundManager::Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - "+ | |
(!ga?" would use flash fallback for MP3/MP4, but none detected.":"will use flash fallback for MP3/MP4, if available"),1);if(M())return true}}else return true;for(a in b.audioFormats)if(b.audioFormats.hasOwnProperty(a)&&b.audioFormats[a].required&&!b.html5.canPlayType(b.audioFormats[a].type))c=true;if(b.ignoreFlash)c=false;y=b.useHTML5Audio&&b.hasHTML5&&!c&&!b.requireFlash;return M()&&c};Y=function(){var c,a=[];l("init");if(s){l("didInit");return false}if(b.hasHTML5){for(c in b.audioFormats)b.audioFormats.hasOwnProperty(c)&& | |
a.push(c+": "+b.html5[c]);b._wD("-- SoundManager 2: HTML5 support tests ("+b.html5Test+"): "+a.join(", ")+" --",1)}if(y){if(!s){u.remove(n,"load",b.beginDelayedInit);b.enabled=true;P()}return true}Q();try{l("flashJS");b.o._externalInterfaceTest(false);b.allowPolling?Da(true,b.flashPollingInterval?b.flashPollingInterval:b.useFastPolling?10:50):l("noPolling",1);b.debugMode||b.o._disableDebug();b.enabled=true;z("jstoflash",true)}catch(f){b._wD("js/flash exception: "+f.toString());z("jstoflash",false); | |
ba(true);P();return false}P();u.remove(n,"load",b.beginDelayedInit);return true};Ca=function(){if(ua)return false;aa();Q();return ua=true};K=function(){if(pa)return false;pa=true;za();if(!b.useHTML5Audio)if(!M()){b._wD("SoundManager: No Flash detected, trying HTML5");b.useHTML5Audio=true}Ja();b.html5.usingFlash=Ia();G=b.html5.usingFlash;pa=true;j.removeEventListener&&j.removeEventListener("DOMContentLoaded",K,false);na();return true};Ga=function(c){if(!c._hasTimer)c._hasTimer=true};Ha=function(c){if(c._hasTimer)c._hasTimer= | |
false};qa=function(){b.onerror instanceof Function&&b.onerror();b.disable()};La=function(){if(!wa||!M())return false;var c=b.audioFormats,a,f;for(f in c)if(c.hasOwnProperty(f))if(f==="mp3"||f==="mp4"){b._wD("soundManager: Using flash fallback for "+f+" format");b.html5[f]=false;if(c[f]&&c[f].related)for(;a--;)b.html5[c[f].related[a]]=false}};this._setSandboxType=function(c){var a=b.sandbox;a.type=c;a.description=a.types[typeof a.types[c]!=="undefined"?c:"unknown"];b._wD("Flash security sandbox type: "+ | |
a.type);if(a.type==="localWithFile"){a.noRemote=true;a.noLocal=false;l("secNote",2)}else if(a.type==="localWithNetwork"){a.noRemote=false;a.noLocal=true}else if(a.type==="localTrusted"){a.noRemote=false;a.noLocal=false}};this._externalInterfaceOK=function(c){if(b.swfLoaded)return false;var a=(new Date).getTime();b._wD("soundManager::externalInterfaceOK()"+(c?" (~"+(a-c)+" ms)":""));z("swf",true);z("flashtojs",true);b.swfLoaded=true;N=false;wa&&La();B?setTimeout(Y,100):Y()};va=function(){if(j.readyState=== | |
"complete"){K();j.detachEvent("onreadystatechange",va)}return true};if(!b.hasHTML5||G){u.add(n,"focus",F);u.add(n,"load",F);u.add(n,"load",Z);U&&N&&u.add(n,"mousemove",F)}if(j.addEventListener)j.addEventListener("DOMContentLoaded",K,false);else if(j.attachEvent)j.attachEvent("onreadystatechange",va);else{z("onload",false);qa()}j.readyState==="complete"&&setTimeout(K,100)}var Oa=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)Oa=new ya;W.SoundManager=ya;W.soundManager=Oa})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @license | |
SoundManager 2: JavaScript Sound for the Web | |
---------------------------------------------- | |
http://schillmania.com/projects/soundmanager2/ | |
Copyright (c) 2007, Scott Schiller. All rights reserved. | |
Code provided under the BSD License: | |
http://schillmania.com/projects/soundmanager2/license.txt | |
V2.97a.20110306 | |
*/ | |
(function($){function qa(Ga,Ha){function o(c){return function(a){return!this._t||!this._t._a?null:c.call(this,a)}}function ra(){if(b.debugURLParam.test(R))b.debugMode=true}this.flashVersion=8;this.debugFlash=this.debugMode=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.nullURL="about:blank";this.allowPolling=true;this.useFastPolling=false;this.useMovieStar=true;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout= | |
1E3;this.wmode=null;this.allowScriptAccess="always";this.useHTML5Audio=this.useFlashBlock=false;this.html5Test=/^probably$/i;this.useGlobalHTML5Audio=true;this.requireFlash=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:true},ogg:{type:["audio/ogg; codecs=vorbis"],required:false}, | |
wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,onbeforefinish:null,onbeforefinishtime:5E3,onbeforefinishcomplete:null,onjustbeforefinish:null,onjustbeforefinishtime:200,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false, | |
volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.version=null;this.versionNumber="V2.97a.20110306";this.movieURL=null;this.url=Ga||null;this.altURL=null;this.enabled=this.swfLoaded=false;this.o=null;this.movieID="sm2-container";this.id=Ha||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error", | |
swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.oMC=null;this.sounds={};this.soundIDs=[];this.muted=false;this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.didFlashBlock=this.specialWmodeCase=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.baseMimeTypes=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamMimeTypes= | |
/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.netStreamTypes=["aac","flv","mov","mp4","m4v","f4v","m4a","mp4v","3gp","3g2"];this.netStreamPattern=RegExp("\\.("+this.netStreamTypes.join("|")+")(\\?.*)?$","i");this.mimePattern=this.baseMimeTypes;this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={};this.hasHTML5=null;this.html5={usingFlash:null};this.ignoreFlash=false;var aa,b=this,D,t=navigator.userAgent,k=$,R=k.location.href.toString(), | |
l=this.flashVersion,j=document,ba,S,w=[],J=false,K=false,r=false,y=false,sa=false,L,s,ca,z,E,da,T,ta,ea,A,ua,M,F,fa,ga,U,ha,va,wa,V,xa,N=null,ia=null,B,ja,G,W,X,ka,p,Y=false,la=false,ya,za,C=null,Aa,Z,u=false,O,x,ma,Ba,q,Ia=Array.prototype.slice,P=false,na,H,Ca,Da=t.match(/pre\//i),Ja=t.match(/(ipad|iphone|ipod)/i);t.match(/mobile/i);var v=t.match(/msie/i),Ka=t.match(/webkit/i),Q=t.match(/safari/i)&&!t.match(/chrome/i),oa=!R.match(/usehtml5audio/i)&&!R.match(/sm2\-ignorebadua/i)&&Q&&t.match(/OS X 10_6_(3|4|5|6)/i), | |
pa=typeof j.hasFocus!=="undefined"?j.hasFocus():null,I=typeof j.hasFocus==="undefined"&&Q,Ea=!I;this._use_maybe=R.match(/sm2\-useHTML5Maybe\=1/i);this._overHTTP=j.location?j.location.protocol.match(/http/i):null;this.useAltURL=!this._overHTTP;this._global_a=null;if(Ja||Da){b.useHTML5Audio=true;b.ignoreFlash=true;if(b.useGlobalHTML5Audio)P=true}if(Da||this._use_maybe)b.html5Test=/^(probably|maybe)$/i;this.supported=this.ok=function(){return C?r&&!y:b.useHTML5Audio&&b.hasHTML5};this.getMovie=function(c){return v? | |
k[c]:Q?D(c)||j[c]:D(c)};this.createSound=function(c){function a(){g=W(g);b.sounds[e.id]=new aa(e);b.soundIDs.push(e.id);return b.sounds[e.id]}var g=null,h=null,e=null;if(!r||!b.ok()){ka("soundManager.createSound(): "+B(!r?"notReady":"notOK"));return false}if(arguments.length===2)c={id:arguments[0],url:arguments[1]};e=g=s(c);if(p(e.id,true))return b.sounds[e.id];if(Z(e)){h=a();h._setup_html5(e)}else{if(l>8&&b.useMovieStar){if(e.isMovieStar===null)e.isMovieStar=e.serverURL||(e.type?e.type.match(b.netStreamPattern): | |
false)||e.url.match(b.netStreamPattern)?true:false;if(e.isMovieStar)if(e.usePeakData)e.usePeakData=false}e=X(e,"soundManager.createSound(): ");h=a();if(l===8)b.o._createSound(e.id,e.onjustbeforefinishtime,e.loops||1,e.usePolicyFile);else{b.o._createSound(e.id,e.url,e.onjustbeforefinishtime,e.usePeakData,e.useWaveformData,e.useEQData,e.isMovieStar,e.isMovieStar?e.bufferTime:false,e.loops||1,e.serverURL,e.duration||null,e.autoPlay,true,e.autoLoad,e.usePolicyFile);if(!e.serverURL){h.connected=true;e.onconnect&& | |
e.onconnect.apply(h)}}if((e.autoLoad||e.autoPlay)&&!e.serverURL)h.load(e)}e.autoPlay&&!e.serverURL&&h.play();return h};this.destroySound=function(c,a){if(!p(c))return false;var g=b.sounds[c],h;g._iO={};g.stop();g.unload();for(h=0;h<b.soundIDs.length;h++)if(b.soundIDs[h]===c){b.soundIDs.splice(h,1);break}a||g.destruct(true);delete b.sounds[c];return true};this.load=function(c,a){if(!p(c))return false;return b.sounds[c].load(a)};this.unload=function(c){if(!p(c))return false;return b.sounds[c].unload()}; | |
this.start=this.play=function(c,a){if(!r||!b.ok()){ka("soundManager.play(): "+B(!r?"notReady":"notOK"));return false}if(!p(c)){a instanceof Object||(a={url:a});if(a&&a.url){a.id=c;return b.createSound(a).play()}else return false}return b.sounds[c].play(a)};this.setPosition=function(c,a){if(!p(c))return false;return b.sounds[c].setPosition(a)};this.stop=function(c){if(!p(c))return false;return b.sounds[c].stop()};this.stopAll=function(){for(var c in b.sounds)b.sounds[c]instanceof aa&&b.sounds[c].stop()}; | |
this.pause=function(c){if(!p(c))return false;return b.sounds[c].pause()};this.pauseAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].pause()};this.resume=function(c){if(!p(c))return false;return b.sounds[c].resume()};this.resumeAll=function(){for(var c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].resume()};this.togglePause=function(c){if(!p(c))return false;return b.sounds[c].togglePause()};this.setPan=function(c,a){if(!p(c))return false;return b.sounds[c].setPan(a)};this.setVolume= | |
function(c,a){if(!p(c))return false;return b.sounds[c].setVolume(a)};this.mute=function(c){var a=0;if(typeof c!=="string")c=null;if(c){if(!p(c))return false;return b.sounds[c].mute()}else{for(a=b.soundIDs.length;a--;)b.sounds[b.soundIDs[a]].mute();b.muted=true}return true};this.muteAll=function(){b.mute()};this.unmute=function(c){if(typeof c!=="string")c=null;if(c){if(!p(c))return false;return b.sounds[c].unmute()}else{for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].unmute();b.muted=false}return true}; | |
this.unmuteAll=function(){b.unmute()};this.toggleMute=function(c){if(!p(c))return false;return b.sounds[c].toggleMute()};this.getMemoryUse=function(){if(l===8)return 0;if(b.o)return parseInt(b.o._getMemoryUse(),10)};this.disable=function(c){if(typeof c==="undefined")c=false;if(y)return false;y=true;for(var a=b.soundIDs.length;a--;)wa(b.sounds[b.soundIDs[a]]);L(c);q.remove(k,"load",E);return true};this.canPlayMIME=function(c){var a;if(b.hasHTML5)a=O({type:c});return!C||a?a:c?c.match(b.mimePattern)? | |
true:false:null};this.canPlayURL=function(c){var a;if(b.hasHTML5)a=O(c);return!C||a?a:c?c.match(b.filePattern)?true:false:null};this.canPlayLink=function(c){if(typeof c.type!=="undefined"&&c.type)if(b.canPlayMIME(c.type))return true;return b.canPlayURL(c.href)};this.getSoundById=function(c){if(!c)throw Error("soundManager.getSoundById(): sID is null/undefined");return b.sounds[c]};this.onready=function(c,a){if(c&&c instanceof Function){a||(a=k);ca("onready",c,a);z();return true}else throw B("needFunction", | |
"onready");};this.ontimeout=function(c,a){if(c&&c instanceof Function){a||(a=k);ca("ontimeout",c,a);z({type:"ontimeout"});return true}else throw B("needFunction","ontimeout");};this.getMoviePercent=function(){return b.o&&typeof b.o.PercentLoaded!=="undefined"?b.o.PercentLoaded():null};this._wD=this._writeDebug=function(){return true};this._debug=function(){};this.reboot=function(){var c,a;for(c=b.soundIDs.length;c--;)b.sounds[b.soundIDs[c]].destruct();try{if(v)ia=b.o.innerHTML;N=b.o.parentNode.removeChild(b.o)}catch(g){}ia= | |
N=null;b.enabled=r=Y=la=J=K=y=b.swfLoaded=false;b.soundIDs=b.sounds=[];b.o=null;for(c in w)if(w.hasOwnProperty(c))for(a=w[c].length;a--;)w[c][a].fired=false;k.setTimeout(function(){b.beginDelayedInit()},20)};this.destruct=function(){b.disable(true)};this.beginDelayedInit=function(){sa=true;F();setTimeout(ua,20);T()};this._html5_events={abort:o(function(){}),canplay:o(function(){this._t._onbufferchange(0);var c=!isNaN(this._t.position)?this._t.position/1E3:null;this._t._html5_canplay=true;if(this._t.position&& | |
this.currentTime!==c)try{this.currentTime=c}catch(a){}}),load:o(function(){if(!this._t.loaded){this._t._onbufferchange(0);this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration());this._t._onload(true)}}),emptied:o(function(){}),ended:o(function(){this._t._onfinish()}),error:o(function(){this._t._onload(false)}),loadeddata:o(function(){}),loadedmetadata:o(function(){}),loadstart:o(function(){this._t._onbufferchange(1)}),play:o(function(){this._t._onbufferchange(0)}), | |
playing:o(function(){this._t._onbufferchange(0)}),progress:o(function(c){if(this._t.loaded)return false;var a,g=0,h=c.type==="progress",e=c.target.buffered;a=c.loaded||0;var d=c.total||1;if(e&&e.length){for(a=e.length;a--;)g=e.end(a)-e.start(a);a=g/c.target.duration;h&&isNaN(a)}if(!isNaN(a)){this._t._onbufferchange(0);this._t._whileloading(a,d,this._t._get_html5_duration());a&&d&&a===d&&b._html5_events.load.call(this,c)}}),ratechange:o(function(){}),suspend:o(function(c){b._html5_events.progress.call(this, | |
c)}),stalled:o(function(){}),timeupdate:o(function(){this._t._onTimer()}),waiting:o(function(){this._t._onbufferchange(1)})};aa=function(c){var a=this,g,h,e;this.sID=c.id;this.url=c.url;this._iO=this.instanceOptions=this.options=s(c);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){};this._debug();this.load=function(d){var f=null;if(typeof d!=="undefined"){a._iO=s(d);a.instanceOptions=a._iO}else{d=a.options; | |
a._iO=d;a.instanceOptions=a._iO;if(a._lastURL&&a._lastURL!==a.url){a._iO.url=a.url;a.url=null}}if(!a._iO.url)a._iO.url=a.url;if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2)return a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(Z(a._iO)){f=a._setup_html5(a._iO);if(!f._called_load){f.load();f._called_load=true;a._iO.autoPlay&&a.play()}}else try{a.isHTML5=false;a._iO=X(W(a._iO));l===8?b.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops|| | |
1,a._iO.usePolicyFile):b.o._load(a.sID,a._iO.url,a._iO.stream?true:false,a._iO.autoPlay?true:false,a._iO.loops||1,a._iO.autoLoad?true:false,a._iO.usePolicyFile)}catch(i){ha()}return a};this.unload=function(){if(a.readyState!==0){if(a.isHTML5){h();if(a._a){a._a.pause();a._a.src=""}}else l===8?b.o._unload(a.sID,b.nullURL):b.o._unload(a.sID);g()}return a};this.destruct=function(d){if(a.isHTML5){h();if(a._a){a._a.pause();a._a.src="";P||a._remove_html5_events()}}else{a._iO.onfailure=null;b.o._destroySound(a.sID)}d|| | |
b.destroySound(a.sID,true)};this.start=this.play=function(d,f){var i;f=f===undefined?true:f;d||(d={});a._iO=s(d,a._iO);a._iO=s(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL)if(!a.connected){a.getAutoPlay()||a.setAutoPlay(true);return a}if(Z(a._iO)){a._setup_html5(a._iO);e()}if(a.playState===1&&!a.paused)if(i=a._iO.multiShot)a.isHTML5&&a.setPosition(a._iO.position);else return a;if(!a.loaded)if(a.readyState===0){if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2)return a; | |
if(a.paused&&a.position&&a.position>0)a.resume();else{a.playState=1;a.paused=false;if(!a.instanceCount||a._iO.multiShotEvents||l>8&&!a.isHTML5&&!a.getAutoPlay())a.instanceCount++;a.position=typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=X(W(a._iO));if(a._iO.onplay&&f){a._iO.onplay.apply(a);a._onplay_called=true}a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);if(a.isHTML5){e();a._setup_html5().play()}else b.o._start(a.sID,a._iO.loops||1,l=== | |
9?a.position:a.position/1E3)}return a};this.stop=function(d){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);if(!a.isHTML5)a.playState=0;a.paused=false;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(a._a){a.setPosition(0);a._a.pause();a.playState=0;a._onTimer();h();a.unload()}}else{b.o._stop(a.sID,d);a._iO.serverURL&&a.unload()}a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(d){a._iO.autoPlay=d;if(a.isHTML5)a._a&&d&&a.play();else b.o._setAutoPlay(a.sID,d);d&&!a.instanceCount&& | |
a.readyState===1&&a.instanceCount++};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(d){if(d===undefined)d=0;var f=a.isHTML5?Math.max(d,0):Math.min(a.duration||a._iO.duration,Math.max(d,0));a.position=f;d=a.position/1E3;a.resetOnPosition(a.position);a._iO.position=f;if(a.isHTML5){if(a._a)if(a._html5_canplay)if(a._a.currentTime!==d)try{a._a.currentTime=d}catch(i){}}else{d=l===9?a.position:d;if(a.readyState&&a.readyState!==2)b.o._setPosition(a.sID,d,a.paused||!a.playState)}a.isHTML5&& | |
a.paused&&a._onTimer(true);return a};this.pause=function(d){if(a.paused||a.playState===0&&a.readyState!==1)return a;a.paused=true;if(a.isHTML5){a._setup_html5().pause();h()}else if(d||d===undefined)b.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;a.paused=false;a.playState=1;if(a.isHTML5){a._setup_html5().play();e()}else{a._iO.isMovieStar&&a.setPosition(a.position);b.o._pause(a.sID)}if(!a._onplay_called&&a._iO.onplay){a._iO.onplay.apply(a); | |
a._onplay_called=true}else a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){if(a.playState===0){a.play({position:l===9&&!a.isHTML5?a.position:a.position/1E3});return a}a.paused?a.resume():a.pause();return a};this.setPan=function(d,f){if(typeof d==="undefined")d=0;if(typeof f==="undefined")f=false;a.isHTML5||b.o._setPan(a.sID,d);a._iO.pan=d;if(!f)a.pan=d;return a};this.setVolume=function(d,f){if(typeof d==="undefined")d=100;if(typeof f==="undefined")f=false;if(a.isHTML5){if(a._a)a._a.volume= | |
d/100}else b.o._setVolume(a.sID,b.muted&&!a.muted||a.muted?0:d);a._iO.volume=d;if(!f)a.volume=d;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else b.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var d=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else b.o._setVolume(a.sID,d?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(d,f,i){a._onPositionItems.push({position:d, | |
method:f,scope:typeof i!=="undefined"?i:a,fired:false});return a};this.processOnPosition=function(){var d,f;d=a._onPositionItems.length;if(!d||!a.playState||a._onPositionFired>=d)return false;for(d=d;d--;){f=a._onPositionItems[d];if(!f.fired&&a.position>=f.position){f.method.apply(f.scope,[f.position]);f.fired=true;b._onPositionFired++}}return true};this.resetOnPosition=function(d){var f,i;f=a._onPositionItems.length;if(!f)return false;for(f=f;f--;){i=a._onPositionItems[f];if(i.fired&&d<=i.position){i.fired= | |
false;b._onPositionFired--}}return true};this._onTimer=function(d){var f={};if(a._hasTimer||d)if(a._a&&(d||(a.playState>0||a.readyState===1)&&!a.paused)){a.duration=a._get_html5_duration();a.durationEstimate=a.duration;d=a._a.currentTime?a._a.currentTime*1E3:0;a._whileplaying(d,f,f,f,f);return true}else return false};this._get_html5_duration=function(){var d=a._a?a._a.duration*1E3:a._iO?a._iO.duration:undefined;return d&&!isNaN(d)&&d!==Infinity?d:a._iO?a._iO.duration:null};e=function(){a.isHTML5&& | |
ya(a)};h=function(){a.isHTML5&&za(a)};g=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.didBeforeFinish=false;a.didJustBeforeFinish=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData= | |
{left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=[];a.eqData.left=[];a.eqData.right=[]};g();this._setup_html5=function(d){d=s(a._iO,d);var f=P?b._global_a:a._a;decodeURI(d.url);var i=f&&f._t?f._t.instanceOptions:null;if(f){if(f._t&&i.url===d.url)return f;P&&f._t.playState&&f._t&&d.url!==i.url&&f._t.stop();g();f.src=d.url}else{f=new Audio(d.url);if(P)b._global_a=f}f._called_load=false;a.isHTML5=true;a._a=f;f._t=a;a._add_html5_events();f.loop=d.loops>1?"loop":"";if(d.autoLoad||d.autoPlay){f.autobuffer= | |
"auto";f.preload="auto";a.load()}else{f.autobuffer=false;f.preload="none"}f.loop=d.loops>1?"loop":"";return f};this._add_html5_events=function(){if(a._a._added_events)return false;var d;a._a._added_events=true;for(d in b._html5_events)b._html5_events.hasOwnProperty(d)&&a._a&&a._a.addEventListener(d,b._html5_events[d],false);return true};this._remove_html5_events=function(){a._a._added_events=false;for(var d in b._html5_events)b._html5_events.hasOwnProperty(d)&&a._a&&a._a.removeEventListener(d,b._html5_events[d], | |
false)};this._whileloading=function(d,f,i,m){a.bytesLoaded=d;a.bytesTotal=f;a.duration=Math.floor(i);a.bufferLength=m;if(a._iO.isMovieStar)a.durationEstimate=a.duration;else{a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10);if(a.durationEstimate===undefined)a.durationEstimate=a.duration}a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._onid3=function(d,f){var i=[],m,n;m=0;for(n=d.length;m< | |
n;m++)i[d[m]]=f[m];a.id3=s(a.id3,i);a._iO.onid3&&a._iO.onid3.apply(a)};this._whileplaying=function(d,f,i,m,n){if(isNaN(d)||d===null)return false;if(a.playState===0&&d>0)d=0;a.position=d;a.processOnPosition();if(l>8&&!a.isHTML5){if(a._iO.usePeakData&&typeof f!=="undefined"&&f)a.peakData={left:f.leftPeak,right:f.rightPeak};if(a._iO.useWaveformData&&typeof i!=="undefined"&&i)a.waveformData={left:i.split(","),right:m.split(",")};if(a._iO.useEQData)if(typeof n!=="undefined"&&n&&n.leftEQ){d=n.leftEQ.split(","); | |
a.eqData=d;a.eqData.left=d;if(typeof n.rightEQ!=="undefined"&&n.rightEQ)a.eqData.right=n.rightEQ.split(",")}}if(a.playState===1){!a.isHTML5&&b.flashVersion===8&&!a.position&&a.isBuffering&&a._onbufferchange(0);a._iO.whileplaying&&a._iO.whileplaying.apply(a);if((a.loaded||!a.loaded&&a._iO.isMovieStar)&&a._iO.onbeforefinish&&a._iO.onbeforefinishtime&&!a.didBeforeFinish&&a.duration-a.position<=a._iO.onbeforefinishtime)a._onbeforefinish()}return true};this._onconnect=function(d){d=d===1;if(a.connected= | |
d){a.failures=0;if(p(a.sID))if(a.getAutoPlay())a.play(undefined,a.getAutoPlay());else a._iO.autoLoad&&a.load();a._iO.onconnect&&a._iO.onconnect.apply(a,[d])}};this._onload=function(d){d=d?true:false;a.loaded=d;a.readyState=d?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[d]);return true};this._onfailure=function(d,f,i){a.failures++;a._iO.onfailure&&a.failures===1&&a._iO.onfailure(a,d,f,i)};this._onbeforefinish=function(){if(!a.didBeforeFinish){a.didBeforeFinish=true;a._iO.onbeforefinish&& | |
a._iO.onbeforefinish.apply(a)}};this._onjustbeforefinish=function(){if(!a.didJustBeforeFinish){a.didJustBeforeFinish=true;a._iO.onjustbeforefinish&&a._iO.onjustbeforefinish.apply(a)}};this._onfinish=function(){var d=a._iO.onfinish;a._onbufferchange(0);a.resetOnPosition(0);a._iO.onbeforefinishcomplete&&a._iO.onbeforefinishcomplete.apply(a);a.didBeforeFinish=false;a.didJustBeforeFinish=false;if(a.instanceCount){a.instanceCount--;if(!a.instanceCount){a.playState=0;a.paused=false;a.instanceCount=0;a.instanceOptions= | |
{};a._iO={};h()}if(!a.instanceCount||a._iO.multiShotEvents)d&&d.apply(a)}};this._onbufferchange=function(d){if(a.playState===0)return false;if(d&&a.isBuffering||!d&&!a.isBuffering)return false;a.isBuffering=d===1;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return true};this._ondataerror=function(){a.playState>0&&a._iO.ondataerror&&a._iO.ondataerror.apply(a)}};ga=function(){return j.body?j.body:j._docElement?j.documentElement:j.getElementsByTagName("div")[0]};D=function(c){return j.getElementById(c)}; | |
s=function(c,a){var g={},h,e;for(h in c)if(c.hasOwnProperty(h))g[h]=c[h];h=typeof a==="undefined"?b.defaultOptions:a;for(e in h)if(h.hasOwnProperty(e)&&typeof g[e]==="undefined")g[e]=h[e];return g};q=function(){function c(e){e=Ia.call(e);var d=e.length;if(g){e[1]="on"+e[1];d>3&&e.pop()}else d===3&&e.push(false);return e}function a(e,d){var f=e.shift(),i=[h[d]];g?f[i](e[0],e[1]):f[i].apply(f,e)}var g=k.attachEvent,h={add:g?"attachEvent":"addEventListener",remove:g?"detachEvent":"removeEventListener"}; | |
return{add:function(){a(c(arguments),"add")},remove:function(){a(c(arguments),"remove")}}}();Z=function(c){return!c.serverURL&&(c.type?O({type:c.type}):O(c.url)||u)};O=function(c){if(!b.useHTML5Audio||!b.hasHTML5)return false;var a,g=b.audioFormats;if(!x){x=[];for(a in g)if(g.hasOwnProperty(a)){x.push(a);if(g[a].related)x=x.concat(g[a].related)}x=RegExp("\\.("+x.join("|")+")","i")}a=typeof c.type!=="undefined"?c.type:null;c=typeof c==="string"?c.toLowerCase().match(x):null;if(!c||!c.length)if(a){c= | |
a.indexOf(";");c=(c!==-1?a.substr(0,c):a).substr(6)}else return false;else c=c[0].substr(1);if(c&&typeof b.html5[c]!=="undefined")return b.html5[c];else{if(!a)if(c&&b.html5[c])return b.html5[c];else a="audio/"+c;a=b.html5.canPlayType(a);return b.html5[c]=a}};Ba=function(){function c(f){var i,m,n=false;if(!a||typeof a.canPlayType!=="function")return false;if(f instanceof Array){i=0;for(m=f.length;i<m&&!n;i++)if(b.html5[f[i]]||a.canPlayType(f[i]).match(b.html5Test)){n=true;b.html5[f[i]]=true}return n}else return(f= | |
a&&typeof a.canPlayType==="function"?a.canPlayType(f):false)&&(f.match(b.html5Test)?true:false)}if(!b.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?new Audio(null):null,g,h={},e,d;H();e=b.audioFormats;for(g in e)if(e.hasOwnProperty(g)){h[g]=c(e[g].type);if(e[g]&&e[g].related)for(d=e[g].related.length;d--;)b.html5[e[g].related[d]]=h[g]}h.canPlayType=a?c:null;b.html5=s(b.html5,h);return true};B=function(){};W=function(c){if(l===8&&c.loops>1&&c.stream)c.stream= | |
false;return c};X=function(c){if(c&&!c.usePolicyFile&&(c.onid3||c.usePeakData||c.useWaveformData||c.useEQData))c.usePolicyFile=true;return c};ka=function(c){typeof console!=="undefined"&&typeof console.warn!=="undefined"&&console.warn(c)};ba=function(){return false};wa=function(c){for(var a in c)if(c.hasOwnProperty(a)&&typeof c[a]==="function")c[a]=ba};V=function(c){if(typeof c==="undefined")c=false;if(y||c)b.disable(c)};xa=function(c){var a=null;if(c)if(c.match(/\.swf(\?.*)?$/i)){if(a=c.substr(c.toLowerCase().lastIndexOf(".swf?")+ | |
4))return c}else if(c.lastIndexOf("/")!==c.length-1)c+="/";return(c&&c.lastIndexOf("/")!==-1?c.substr(0,c.lastIndexOf("/")+1):"./")+b.movieURL};ea=function(){if(l!==8&&l!==9)b.flashVersion=8;var c=b.debugMode||b.debugFlash?"_debug.swf":".swf";if(b.useHTML5Audio&&!u&&b.audioFormats.mp4.required&&b.flashVersion<9)b.flashVersion=9;l=b.flashVersion;b.version=b.versionNumber+(u?" (HTML5-only mode)":l===9?" (AS3/Flash 9)":" (AS2/Flash 8)");if(l>8){b.defaultOptions=s(b.defaultOptions,b.flash9Options);b.features.buffering= | |
true}if(l>8&&b.useMovieStar){b.defaultOptions=s(b.defaultOptions,b.movieStarOptions);b.filePatterns.flash9=RegExp("\\.(mp3|"+b.netStreamTypes.join("|")+")(\\?.*)?$","i");b.mimePattern=b.netStreamMimeTypes;b.features.movieStar=true}else{b.useMovieStar=false;b.features.movieStar=false}b.filePattern=b.filePatterns[l!==8?"flash9":"flash8"];b.movieURL=(l===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",c);b.features.peakData=b.features.waveformData=b.features.eqData=l>8};va=function(c, | |
a){if(!b.o||!b.allowPolling)return false;b.o._setPolling(c,a)};U=function(c,a){var g=a?a:b.url,h=b.altURL?b.altURL:g,e;e=ga();var d,f,i=G(),m,n=null;n=(n=j.getElementsByTagName("html")[0])&&n.dir&&n.dir.match(/rtl/i);c=typeof c==="undefined"?b.id:c;if(J&&K)return false;if(u){ea();b.oMC=D(b.movieID);S();K=J=true;return false}J=true;ea();b.url=xa(b._overHTTP?g:h);a=b.url;b.wmode=!b.wmode&&b.useHighPerformance&&!b.useMovieStar?"transparent":b.wmode;if(b.wmode!==null&&(t.match(/msie 8/i)||!v&&!b.useHighPerformance)&& | |
navigator.platform.match(/win32|win64/i)){b.specialWmodeCase=true;b.wmode=null}e={name:c,id:c,src:a,width:"100%",height:"100%",quality:"high",allowScriptAccess:b.allowScriptAccess,bgcolor:b.bgColor,pluginspage:"http://www.macromedia.com/go/getflashplayer",type:"application/x-shockwave-flash",wmode:b.wmode,hasPriority:"true"};if(b.debugFlash)e.FlashVars="debug=1";b.wmode||delete e.wmode;if(v){g=j.createElement("div");f='<object id="'+c+'" data="'+a+'" type="'+e.type+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+ | |
e.width+'" height="'+e.height+'"><param name="movie" value="'+a+'" /><param name="AllowScriptAccess" value="'+b.allowScriptAccess+'" /><param name="quality" value="'+e.quality+'" />'+(b.wmode?'<param name="wmode" value="'+b.wmode+'" /> ':"")+'<param name="bgcolor" value="'+b.bgColor+'" />'+(b.debugFlash?'<param name="FlashVars" value="'+e.FlashVars+'" />':"")+"</object>"}else{g=j.createElement("embed");for(d in e)e.hasOwnProperty(d)&&g.setAttribute(d,e[d])}ra();i=G();if(e=ga()){b.oMC=D(b.movieID)? | |
D(b.movieID):j.createElement("div");if(b.oMC.id){m=b.oMC.className;b.oMC.className=(m?m+" ":b.swfCSS.swfDefault)+(i?" "+i:"");b.oMC.appendChild(g);if(v){d=b.oMC.appendChild(j.createElement("div"));d.className=b.swfCSS.swfBox;d.innerHTML=f}K=true}else{b.oMC.id=b.movieID;b.oMC.className=b.swfCSS.swfDefault+" "+i;d=i=null;if(!b.useFlashBlock)if(b.useHighPerformance)i={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else{i={position:"absolute",width:"6px",height:"6px", | |
top:"-9999px",left:"-9999px"};if(n)i.left=Math.abs(parseInt(i.left,10))+"px"}if(Ka)b.oMC.style.zIndex=1E4;if(!b.debugFlash)for(m in i)if(i.hasOwnProperty(m))b.oMC.style[m]=i[m];try{v||b.oMC.appendChild(g);e.appendChild(b.oMC);if(v){d=b.oMC.appendChild(j.createElement("div"));d.className=b.swfCSS.swfBox;d.innerHTML=f}K=true}catch(La){throw Error(B("appXHTML"));}}}return true};p=this.getSoundById;M=function(){if(u){U();return false}if(b.o)return false;b.o=b.getMovie(b.id);if(!b.o){if(N){if(v)b.oMC.innerHTML= | |
ia;else b.oMC.appendChild(N);N=null;J=true}else U(b.id,b.url);b.o=b.getMovie(b.id)}b.oninitmovie instanceof Function&&setTimeout(b.oninitmovie,1);return true};da=function(c){if(c)b.url=c;M()};T=function(){setTimeout(ta,500)};ta=function(){if(Y)return false;Y=true;q.remove(k,"load",T);if(I&&!pa)return false;var c;r||(c=b.getMoviePercent());setTimeout(function(){c=b.getMoviePercent();if(!r&&Ea)if(c===null)if(b.useFlashBlock||b.flashLoadTimeout===0)b.useFlashBlock&&ja();else V(true);else b.flashLoadTimeout!== | |
0&&V(true)},b.flashLoadTimeout)};da=function(c){if(c)b.url=c;M()};G=function(){var c=[];b.debugMode&&c.push(b.swfCSS.sm2Debug);b.debugFlash&&c.push(b.swfCSS.flashDebug);b.useHighPerformance&&c.push(b.swfCSS.highPerf);return c.join(" ")};ja=function(){B("fbHandler");var c=b.getMoviePercent(),a=b.swfCSS;if(b.ok()){if(b.oMC)b.oMC.className=[G(),a.swfDefault,a.swfLoaded+(b.didFlashBlock?" "+a.swfUnblocked:"")].join(" ")}else{if(C)b.oMC.className=G()+" "+a.swfDefault+" "+(c===null?a.swfTimedout:a.swfError); | |
b.didFlashBlock=true;z({type:"ontimeout",ignoreInit:true});b.onerror instanceof Function&&b.onerror.apply(k)}};A=function(){function c(){q.remove(k,"focus",A);q.remove(k,"load",A)}if(pa||!I){c();return true}pa=Ea=true;Q&&I&&q.remove(k,"mousemove",A);Y=false;c();return true};L=function(c){if(r)return false;if(u){r=true;z();E();return true}b.useFlashBlock&&b.flashLoadTimeout&&!b.getMoviePercent()||(r=true);if(y||c){if(b.useFlashBlock)b.oMC.className=G()+" "+(b.getMoviePercent()===null?b.swfCSS.swfTimedout: | |
b.swfCSS.swfError);z({type:"ontimeout"});b.onerror instanceof Function&&b.onerror.apply(k);return false}q.add(k,"unload",ba);if(b.waitForWindowLoad&&!sa){q.add(k,"load",E);return false}else E();return true};ca=function(c,a,g){if(typeof w[c]==="undefined")w[c]=[];w[c].push({method:a,scope:g||null,fired:false})};z=function(c){c||(c={type:"onready"});if(!r&&c&&!c.ignoreInit)return false;var a={success:c&&c.ignoreInit?b.ok():!y},g=c&&c.type?w[c.type]||[]:[];c=[];var h,e=C&&b.useFlashBlock&&!b.ok();for(h= | |
0;h<g.length;h++)g[h].fired!==true&&c.push(g[h]);if(c.length){h=0;for(g=c.length;h<g;h++){c[h].scope?c[h].method.apply(c[h].scope,[a]):c[h].method(a);if(!e)c[h].fired=true}}return true};E=function(){k.setTimeout(function(){b.useFlashBlock&&ja();z();b.onload instanceof Function&&b.onload.apply(k);b.waitForWindowLoad&&q.add(k,"load",E)},1)};H=function(){if(na!==undefined)return na;var c=false,a=navigator,g=a.plugins,h,e=k.ActiveXObject;if(g&&g.length){if((a=a.mimeTypes)&&a["application/x-shockwave-flash"]&& | |
a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description)c=true}else if(typeof e!=="undefined"){try{h=new e("ShockwaveFlash.ShockwaveFlash")}catch(d){}c=!!h}return na=c};Aa=function(){var c,a;if(t.match(/iphone os (1|2|3_0|3_1)/i)?true:false){b.hasHTML5=false;u=true;if(b.oMC)b.oMC.style.display="none";return false}if(b.useHTML5Audio){if(!b.html5||!b.html5.canPlayType){b.hasHTML5=false;return true}else b.hasHTML5=true;if(oa)if(H())return true}else return true; | |
for(a in b.audioFormats)if(b.audioFormats.hasOwnProperty(a)&&b.audioFormats[a].required&&!b.html5.canPlayType(b.audioFormats[a].type))c=true;if(b.ignoreFlash)c=false;u=b.useHTML5Audio&&b.hasHTML5&&!c&&!b.requireFlash;return H()&&c};S=function(){var c,a=[];if(r)return false;if(b.hasHTML5)for(c in b.audioFormats)b.audioFormats.hasOwnProperty(c)&&a.push(c+": "+b.html5[c]);if(u){if(!r){q.remove(k,"load",b.beginDelayedInit);b.enabled=true;L()}return true}M();try{b.o._externalInterfaceTest(false);if(b.allowPolling)va(true, | |
b.flashPollingInterval?b.flashPollingInterval:b.useFastPolling?10:50);b.debugMode||b.o._disableDebug();b.enabled=true}catch(g){V(true);L();return false}L();q.remove(k,"load",b.beginDelayedInit);return true};ua=function(){if(la)return false;U();M();return la=true};F=function(){if(fa)return false;fa=true;ra();if(!b.useHTML5Audio)if(!H())b.useHTML5Audio=true;Ba();b.html5.usingFlash=Aa();C=b.html5.usingFlash;fa=true;j.removeEventListener&&j.removeEventListener("DOMContentLoaded",F,false);da();return true}; | |
ya=function(c){if(!c._hasTimer)c._hasTimer=true};za=function(c){if(c._hasTimer)c._hasTimer=false};ha=function(){b.onerror instanceof Function&&b.onerror();b.disable()};Ca=function(){if(!oa||!H())return false;var c=b.audioFormats,a,g;for(g in c)if(c.hasOwnProperty(g))if(g==="mp3"||g==="mp4"){b.html5[g]=false;if(c[g]&&c[g].related)for(;a--;)b.html5[c[g].related[a]]=false}};this._setSandboxType=function(){};this._externalInterfaceOK=function(){if(b.swfLoaded)return false;(new Date).getTime();b.swfLoaded= | |
true;I=false;oa&&Ca();v?setTimeout(S,100):S()};ma=function(){if(j.readyState==="complete"){F();j.detachEvent("onreadystatechange",ma)}return true};if(!b.hasHTML5||C){q.add(k,"focus",A);q.add(k,"load",A);q.add(k,"load",T);Q&&I&&q.add(k,"mousemove",A)}if(j.addEventListener)j.addEventListener("DOMContentLoaded",F,false);else j.attachEvent?j.attachEvent("onreadystatechange",ma):ha();j.readyState==="complete"&&setTimeout(F,100)}var Fa=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)Fa=new qa;$.SoundManager= | |
qa;$.soundManager=Fa})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @license | |
* SoundManager 2: JavaScript Sound for the Web | |
* ---------------------------------------------- | |
* http://schillmania.com/projects/soundmanager2/ | |
* | |
* Copyright (c) 2007, Scott Schiller. All rights reserved. | |
* Code provided under the BSD License: | |
* http://schillmania.com/projects/soundmanager2/license.txt | |
* | |
* V2.97a.20110306 | |
*/ | |
/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: false, newcap: true, immed: true */ | |
/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ | |
(function(window) { | |
var soundManager = null; | |
function SoundManager(smURL, smID) { | |
this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. | |
this.debugMode = false; // enable debugging output (div#soundmanager-debug, OR console if available+configured) | |
this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues | |
this.useConsole = true; // use firebug/safari console.log()-type debug console if available | |
this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug | |
this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() | |
this.nullURL = 'about:blank'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) | |
this.allowPolling = true; // allow flash to poll for status update (required for whileplaying() events, peak, sound spectrum functions to work.) | |
this.useFastPolling = false; // uses lower flash timer interval for higher callback frequency, best combined with useHighPerformance | |
this.useMovieStar = true; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio formats (AAC, M4V, FLV, MOV etc.) | |
this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000' | |
this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag | |
this.flashPollingInterval = null; // msec for polling interval. Defaults to 50 unless useFastPolling = true. | |
this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity) | |
this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top) | |
this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain' | |
this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable. | |
this.useHTML5Audio = false; // Beta feature: Use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible. | |
this.html5Test = /^probably$/i; // HTML5 Audio().canPlayType() test. /^(probably|maybe)$/i if you want to be more liberal/risky. | |
this.useGlobalHTML5Audio = true; // (experimental) if true, re-use single HTML5 audio object across all sounds. Enabled by default on mobile devices/iOS. | |
this.requireFlash = false; // (experimental) if true, prevents "HTML5-only" mode when flash present. Allows flash to handle RTMP/serverURL, but HTML5 for other cases | |
this.audioFormats = { | |
// determines HTML5 support, flash requirements | |
// eg. if MP3 or MP4 required, Flash fallback is used if HTML5 can't play it | |
// shotgun approach to MIME testing due to browser variance | |
'mp3': { | |
'type': ['audio/mpeg; codecs="mp3"','audio/mpeg','audio/mp3','audio/MPA','audio/mpa-robust'], | |
'required': true | |
}, | |
'mp4': { | |
'related': ['aac','m4a'], // additional formats under the MP4 container | |
'type': ['audio/mp4; codecs="mp4a.40.2"','audio/aac','audio/x-m4a','audio/MP4A-LATM','audio/mpeg4-generic'], | |
'required': true | |
}, | |
'ogg': { | |
'type': ['audio/ogg; codecs=vorbis'], | |
'required': false | |
}, | |
'wav': { | |
'type': ['audio/wav; codecs="1"','audio/wav','audio/wave','audio/x-wav'], | |
'required': false | |
} | |
}; | |
this.defaultOptions = { | |
'autoLoad': false, // enable automatic loading (otherwise .load() will be called on demand with .play(), the latter being nicer on bandwidth - if you want to .load yourself, you also can) | |
'stream': true, // allows playing before entire file has loaded (recommended) | |
'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) | |
'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0) | |
'onid3': null, // callback function for "ID3 data is added/available" | |
'onload': null, // callback function for "load finished" | |
'whileloading': null, // callback function for "download progress update" (X of Y bytes received) | |
'onplay': null, // callback for "play" start | |
'onpause': null, // callback for "pause" | |
'onresume': null, // callback for "resume" (pause toggle) | |
'whileplaying': null, // callback during play (position update) | |
'onstop': null, // callback for "user stop" | |
'onfailure': null, // callback function for when playing fails | |
'onfinish': null, // callback function for "sound finished playing" | |
'onbeforefinish': null, // callback for "before sound finished playing (at [time])" | |
'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) | |
'onbeforefinishcomplete': null,// function to call when said sound finishes playing | |
'onjustbeforefinish': null, // callback for [n] msec before end of current sound | |
'onjustbeforefinishtime': 200, // [n] - if not using, set to 0 (or null handler) and event will not fire. | |
'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time | |
'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled | |
'position': null, // offset (milliseconds) to seek to within loaded sound data. | |
'pan': 0, // "pan" settings, left-to-right, -100 to 100 | |
'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3 | |
'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access) | |
'volume': 100 // self-explanatory. 0-100, the latter being the max. | |
}; | |
this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used | |
'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL | |
'usePeakData': false, // enable left/right channel peak (level) data | |
'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. | |
'useEQData': false, // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. | |
'onbufferchange': null, // callback for "isBuffering" property change | |
'ondataerror': null // callback for waveform/eq data access error (flash playing audio in other tabs/domains) | |
}; | |
this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio options, merged into defaultOptions if flash 9+movieStar mode is enabled | |
'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.) | |
'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants | |
'onconnect': null, // rtmp: callback for connection to flash media server | |
'duration': null // rtmp: song duration (msec) | |
}; | |
this.version = null; | |
this.versionNumber = 'V2.97a.20110306'; | |
this.movieURL = null; | |
this.url = (smURL || null); | |
this.altURL = null; | |
this.swfLoaded = false; | |
this.enabled = false; | |
this.o = null; | |
this.movieID = 'sm2-container'; | |
this.id = (smID || 'sm2movie'); | |
this.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', | |
'swfUnblocked': 'swf_unblocked', // or loaded OK | |
'sm2Debug': 'sm2_debug', | |
'highPerf': 'high_performance', | |
'flashDebug': 'flash_debug' | |
}; | |
this.oMC = null; | |
this.sounds = {}; | |
this.soundIDs = []; | |
this.muted = false; | |
this.debugID = 'soundmanager-debug'; | |
this.debugURLParam = /([#?&])debug=1/i; | |
this.specialWmodeCase = false; | |
this.didFlashBlock = false; | |
this.filePattern = null; | |
this.filePatterns = { | |
'flash8': /\.mp3(\?.*)?$/i, | |
'flash9': /\.mp3(\?.*)?$/i | |
}; | |
this.baseMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3 | |
this.netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3, mp4, aac etc. | |
this.netStreamTypes = ['aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2']; // Flash v9.0r115+ "moviestar" formats | |
this.netStreamPattern = new RegExp('\\.(' + this.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); | |
this.mimePattern = this.baseMimeTypes; | |
this.features = { | |
'buffering': false, | |
'peakData': false, | |
'waveformData': false, | |
'eqData': false, | |
'movieStar': false | |
}; | |
this.sandbox = { | |
/* | |
'type': null, | |
'types': { | |
'remote': 'remote (domain-based) rules', | |
'localWithFile': 'local with file access (no internet access)', | |
'localWithNetwork': 'local with network (internet access only, no local access)', | |
'localTrusted': 'local, trusted (local+internet access)' | |
}, | |
'description': null, | |
'noRemote': null, | |
'noLocal': null | |
*/ | |
}; | |
this.hasHTML5 = null; // switch for handling logic | |
this.html5 = { // stores canPlayType() results, etc. treat as read-only. | |
// mp3: boolean | |
// mp4: boolean | |
'usingFlash': null // set if/when flash fallback is needed | |
}; | |
this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?) | |
// --- private SM2 internals --- | |
var SMSound, | |
_s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _fV = this.flashVersion, _doc = document, _doNothing, _init, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _go, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _beginInit, _strings, _initMovie, _dcLoaded, _didDCLoaded, _getDocument, _createMovie, _die, _setPolling, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5Only = false, _html5CanPlay, _html5Ext, _dcIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, | |
_is_pre = _ua.match(/pre\//i), _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _isMobile = (_ua.match(/mobile/i) || _is_pre || _is_iDevice), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), | |
_isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_(3|4|5|6)/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" 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 = (typeof _doc.hasFocus === 'undefined' && _isSafari), _okToDisable = !_tryInitOnFocus; | |
this._use_maybe = (_wl.match(/sm2\-useHTML5Maybe\=1/i)); // temporary feature: #sm2-useHTML5Maybe=1 forces loose canPlay() check | |
this._overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null); | |
this.useAltURL = !this._overHTTP; // use altURL if not "online" | |
this._global_a = null; | |
if (_is_iDevice || _is_pre) { | |
// during HTML5 beta period (off by default), may as well force it on Apple + Palm, flash support unlikely | |
_s.useHTML5Audio = true; | |
_s.ignoreFlash = true; | |
if (_s.useGlobalHTML5Audio) { | |
_useGlobalHTML5Audio = true; | |
} | |
} | |
if (_is_pre || this._use_maybe) { | |
// less-strict canPlayType() checking option | |
_s.html5Test = /^(probably|maybe)$/i; | |
} | |
// Temporary feature: allow force of HTML5 via URL: #sm2-usehtml5audio=0 or 1 | |
/* | |
(function(){ | |
var a = '#sm2-usehtml5audio=', l = _wl, b = null; | |
if (l.indexOf(a) !== -1) { | |
b = (l.charAt(l.indexOf(a)+a.length) === '1'); | |
if (typeof console !== 'undefined' && typeof console.log !== 'undefined') { | |
console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); | |
} | |
_s.useHTML5Audio = b; | |
} | |
}()); | |
*/ | |
// --- public API methods --- | |
this.ok = function() { | |
return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); | |
}; | |
this.supported = this.ok; // legacy | |
this.getMovie = function(smID) { | |
return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); | |
}; | |
this.createSound = function(oOptions) { | |
var _cs = _sm+'.createSound(): ', | |
thisOptions = null, oSound = null, _tO = null; | |
if (!_didInit || !_s.ok()) { | |
_complain(_cs + _str(!_didInit?'notReady':'notOK')); | |
return false; | |
} | |
if (arguments.length === 2) { | |
// function overloading in JS! :) ..assume simple createSound(id,url) use case | |
oOptions = { | |
'id': arguments[0], | |
'url': arguments[1] | |
}; | |
} | |
thisOptions = _mixin(oOptions); // inherit from defaultOptions | |
_tO = thisOptions; // alias | |
/* | |
if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { | |
//_s._wD(_cs + _str('badID', _tO.id), 2); | |
} | |
//_s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); | |
*/ | |
if (_idCheck(_tO.id, true)) { | |
//_s._wD(_cs + _tO.id + ' exists', 1); | |
return _s.sounds[_tO.id]; | |
} | |
function make() { | |
thisOptions = _loopFix(thisOptions); | |
_s.sounds[_tO.id] = new SMSound(_tO); | |
_s.soundIDs.push(_tO.id); | |
return _s.sounds[_tO.id]; | |
} | |
if (_html5OK(_tO)) { | |
oSound = make(); | |
//_s._wD('Loading sound '+_tO.id+' via HTML5'); | |
oSound._setup_html5(_tO); | |
} else { | |
if (_fV > 8 && _s.useMovieStar) { | |
if (_tO.isMovieStar === null) { | |
_tO.isMovieStar = ((_tO.serverURL || (_tO.type?_tO.type.match(_s.netStreamPattern):false)||_tO.url.match(_s.netStreamPattern))?true:false); | |
} | |
if (_tO.isMovieStar) { | |
//_s._wD(_cs + 'using MovieStar handling'); | |
} | |
if (_tO.isMovieStar) { | |
if (_tO.usePeakData) { | |
//_wDS('noPeak'); | |
_tO.usePeakData = false; | |
} | |
if (_tO.loops > 1) { | |
//_wDS('noNSLoop'); | |
} | |
} | |
} | |
_tO = _policyFix(_tO, _cs); | |
oSound = make(); | |
if (_fV === 8) { | |
_s.o._createSound(_tO.id, _tO.onjustbeforefinishtime, _tO.loops||1, _tO.usePolicyFile); | |
} else { | |
_s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _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) { | |
// We are connected immediately | |
oSound.connected = true; | |
if (_tO.onconnect) { | |
_tO.onconnect.apply(oSound); | |
} | |
} | |
} | |
if ((_tO.autoLoad || _tO.autoPlay) && !_tO.serverURL) { | |
oSound.load(_tO); // call load for non-rtmp streams | |
} | |
} | |
if (_tO.autoPlay && !_tO.serverURL) { // rtmp will play in onconnect | |
oSound.play(); | |
} | |
return oSound; | |
}; | |
this.destroySound = function(sID, _bFromSound) { | |
// explicitly destroy a sound before normal page unload, etc. | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
var oS = _s.sounds[sID], i; | |
oS._iO = {}; // Disable all callbacks while the sound is being destroyed | |
oS.stop(); | |
oS.unload(); | |
for (i = 0; i < _s.soundIDs.length; i++) { | |
if (_s.soundIDs[i] === sID) { | |
_s.soundIDs.splice(i, 1); | |
break; | |
} | |
} | |
if (!_bFromSound) { | |
// ignore if being called from SMSound instance | |
oS.destruct(true); | |
} | |
oS = null; | |
delete _s.sounds[sID]; | |
return true; | |
}; | |
this.load = function(sID, oOptions) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].load(oOptions); | |
}; | |
this.unload = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].unload(); | |
}; | |
this.play = function(sID, oOptions) { | |
var fN = _sm+'.play(): '; | |
if (!_didInit || !_s.ok()) { | |
_complain(fN + _str(!_didInit?'notReady':'notOK')); | |
return false; | |
} | |
if (!_idCheck(sID)) { | |
if (!(oOptions instanceof Object)) { | |
oOptions = { | |
url: oOptions | |
}; // overloading use case: play('mySound','/path/to/some.mp3'); | |
} | |
if (oOptions && oOptions.url) { | |
// overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); | |
//_s._wD(fN + 'attempting to create "' + sID + '"', 1); | |
oOptions.id = sID; | |
return _s.createSound(oOptions).play(); | |
} else { | |
return false; | |
} | |
} | |
return _s.sounds[sID].play(oOptions); | |
}; | |
this.start = this.play; // just for convenience | |
this.setPosition = function(sID, nMsecOffset) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setPosition(nMsecOffset); | |
}; | |
this.stop = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
//_s._wD(_sm+'.stop(' + sID + ')', 1); | |
return _s.sounds[sID].stop(); | |
}; | |
this.stopAll = function() { | |
//_s._wD(_sm+'.stopAll()', 1); | |
for (var oSound in _s.sounds) { | |
if (_s.sounds[oSound] instanceof SMSound) { | |
_s.sounds[oSound].stop(); // apply only to sound objects | |
} | |
} | |
}; | |
this.pause = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].pause(); | |
}; | |
this.pauseAll = function() { | |
for (var i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].pause(); | |
} | |
}; | |
this.resume = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].resume(); | |
}; | |
this.resumeAll = function() { | |
for (var i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].resume(); | |
} | |
}; | |
this.togglePause = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].togglePause(); | |
}; | |
this.setPan = function(sID, nPan) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setPan(nPan); | |
}; | |
this.setVolume = function(sID, nVol) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setVolume(nVol); | |
}; | |
this.mute = function(sID) { | |
var fN = _sm+'.mute(): ', | |
i = 0; | |
if (typeof sID !== 'string') { | |
sID = null; | |
} | |
if (!sID) { | |
//_s._wD(fN + 'Muting all sounds'); | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].mute(); | |
} | |
_s.muted = true; | |
} else { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
//_s._wD(fN + 'Muting "' + sID + '"'); | |
return _s.sounds[sID].mute(); | |
} | |
return true; | |
}; | |
this.muteAll = function() { | |
_s.mute(); | |
}; | |
this.unmute = function(sID) { | |
var fN = _sm+'.unmute(): ', i; | |
if (typeof sID !== 'string') { | |
sID = null; | |
} | |
if (!sID) { | |
//_s._wD(fN + 'Unmuting all sounds'); | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].unmute(); | |
} | |
_s.muted = false; | |
} else { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
//_s._wD(fN + 'Unmuting "' + sID + '"'); | |
return _s.sounds[sID].unmute(); | |
} | |
return true; | |
}; | |
this.unmuteAll = function() { | |
_s.unmute(); | |
}; | |
this.toggleMute = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].toggleMute(); | |
}; | |
this.getMemoryUse = function() { | |
if (_fV === 8) { | |
return 0; | |
} | |
if (_s.o) { | |
return parseInt(_s.o._getMemoryUse(), 10); | |
} | |
}; | |
this.disable = function(bNoDisable) { | |
// destroy all functions | |
if (typeof bNoDisable === 'undefined') { | |
bNoDisable = false; | |
} | |
if (_disabled) { | |
return false; | |
} | |
_disabled = true; | |
//_wDS('shutdown', 1); | |
for (var i = _s.soundIDs.length; i--;) { | |
_disableObject(_s.sounds[_s.soundIDs[i]]); | |
} | |
_initComplete(bNoDisable); // fire "complete", despite fail | |
_event.remove(_win, 'load', _initUserOnload); | |
return true; | |
}; | |
this.canPlayMIME = function(sMIME) { | |
var result; | |
if (_s.hasHTML5) { | |
result = _html5CanPlay({type:sMIME}); | |
} | |
if (!_needsFlash || result) { | |
// no flash, or OK | |
return result; | |
} else { | |
return (sMIME?(sMIME.match(_s.mimePattern)?true:false):null); | |
} | |
}; | |
this.canPlayURL = function(sURL) { | |
var result; | |
if (_s.hasHTML5) { | |
result = _html5CanPlay(sURL); | |
} | |
if (!_needsFlash || result) { | |
// no flash, or OK | |
return result; | |
} else { | |
return (sURL?(sURL.match(_s.filePattern)?true:false):null); | |
} | |
}; | |
this.canPlayLink = function(oLink) { | |
if (typeof oLink.type !== 'undefined' && oLink.type) { | |
if (_s.canPlayMIME(oLink.type)) { | |
return true; | |
} | |
} | |
return _s.canPlayURL(oLink.href); | |
}; | |
this.getSoundById = function(sID, suppressDebug) { | |
if (!sID) { | |
throw new Error(_sm+'.getSoundById(): sID is null/undefined'); | |
} | |
var result = _s.sounds[sID]; | |
if (!result && !suppressDebug) { | |
//_s._wD('"' + sID + '" is an invalid sound ID.', 2); | |
} | |
return result; | |
}; | |
this.onready = function(oMethod, oScope) { | |
var sType = 'onready'; | |
if (oMethod && oMethod instanceof Function) { | |
if (_didInit) { | |
//_wDS('queue', sType); | |
} | |
if (!oScope) { | |
oScope = _win; | |
} | |
_addOnEvent(sType, oMethod, oScope); | |
_processOnEvents(); | |
return true; | |
} else { | |
throw _str('needFunction', sType); | |
} | |
}; | |
this.ontimeout = function(oMethod, oScope) { | |
var sType = 'ontimeout'; | |
if (oMethod && oMethod instanceof Function) { | |
if (_didInit) { | |
//_wDS('queue'); | |
} | |
if (!oScope) { | |
oScope = _win; | |
} | |
_addOnEvent(sType, oMethod, oScope); | |
_processOnEvents({type:sType}); | |
return true; | |
} else { | |
throw _str('needFunction', sType); | |
} | |
}; | |
this.getMoviePercent = function() { | |
return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); | |
}; | |
this._writeDebug = function(sText, sType, bTimestamp) { | |
// pseudo-private console.log()-style output | |
/* | |
var sDID = 'soundmanager-debug', o, oItem, sMethod; | |
if (!_s.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); | |
} else { | |
console.log(sText); | |
} | |
if (_s.useConsoleOnly) { | |
return true; | |
} | |
} | |
try { | |
o = _id(sDID); | |
if (!o) { | |
return false; | |
} | |
oItem = _doc.createElement('div'); | |
if (++_wdCount % 2 === 0) { | |
oItem.className = 'sm2-alt'; | |
} | |
if (typeof sType === 'undefined') { | |
sType = 0; | |
} else { | |
sType = parseInt(sType, 10); | |
} | |
oItem.appendChild(_doc.createTextNode(sText)); | |
if (sType) { | |
if (sType >= 2) { | |
oItem.style.fontWeight = 'bold'; | |
} | |
if (sType === 3) { | |
oItem.style.color = '#ff3333'; | |
} | |
} | |
// o.appendChild(oItem); // top-to-bottom | |
o.insertBefore(oItem, o.firstChild); // bottom-to-top | |
} catch(e) { | |
// oh well | |
} | |
o = null; | |
*/ | |
return true; | |
}; | |
this._wD = this._writeDebug; // alias | |
this._debug = function() { | |
/* | |
//_wDS('currentObj', 1); | |
for (var i = 0, j = _s.soundIDs.length; i < j; i++) { | |
_s.sounds[_s.soundIDs[i]]._debug(); | |
} | |
*/ | |
}; | |
this.reboot = function() { | |
// attempt to reset and init SM2 | |
//_s._wD(_sm+'.reboot()'); | |
if (_s.soundIDs.length) { | |
//_s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); | |
} | |
var i, j; | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].destruct(); | |
} | |
// trash ze flash | |
try { | |
if (_isIE) { | |
_oRemovedHTML = _s.o.innerHTML; | |
} | |
_oRemoved = _s.o.parentNode.removeChild(_s.o); | |
//_s._wD('Flash movie removed.'); | |
} catch(e) { | |
// uh-oh. | |
//_wDS('badRemove', 2); | |
} | |
// actually, force recreate of movie. | |
_oRemovedHTML = _oRemoved = null; | |
_s.enabled = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; | |
_s.soundIDs = _s.sounds = []; | |
_s.o = null; | |
for (i in _on_queue) { | |
if (_on_queue.hasOwnProperty(i)) { | |
for (j = _on_queue[i].length; j--;) { | |
_on_queue[i][j].fired = false; | |
} | |
} | |
} | |
//_s._wD(_sm + ': Rebooting...'); | |
_win.setTimeout(function() { | |
_s.beginDelayedInit(); | |
}, 20); | |
}; | |
this.destruct = function() { | |
//_s._wD(_sm+'.destruct()'); | |
_s.disable(true); | |
}; | |
this.beginDelayedInit = function() { | |
// //_s._wD(_sm+'.beginDelayedInit()'); | |
_windowLoaded = true; | |
_dcLoaded(); | |
setTimeout(_beginInit, 20); | |
_delayWaitForEI(); | |
}; | |
// Wrap html5 event handlers so we don't call them on destroyed sounds | |
function _html5_event(oFn) { | |
return function(e) { | |
if (!this._t || !this._t._a) { | |
if (this._t && this._t.sID) { | |
//_s._wD(_h5+'ignoring '+e.type+': '+this._t.sID); | |
} else { | |
//_s._wD(_h5+'ignoring '+e.type); | |
} | |
return null; | |
} else { | |
return oFn.call(this, e); | |
} | |
}; | |
} | |
this._html5_events = { | |
// HTML5 event-name-to-handler map | |
abort: _html5_event(function(e) { | |
//_s._wD(_h5+'abort: '+this._t.sID); | |
}), | |
// enough has loaded to play | |
canplay: _html5_event(function(e) { | |
//_s._wD(_h5+'canplay: '+this._t.sID+', '+this._t.url); | |
this._t._onbufferchange(0); | |
var position1K = (!isNaN(this._t.position)?this._t.position/1000:null); | |
// set the position if position was set before the sound loaded | |
this._t._html5_canplay = true; | |
if (this._t.position && this.currentTime !== position1K) { | |
//_s._wD(_h5+'canplay: setting position to '+position1K+''); | |
try { | |
this.currentTime = position1K; | |
} catch(ee) { | |
//_s._wD(_h5+'setting position failed: '+ee.message, 2); | |
} | |
} | |
}), | |
load: _html5_event(function(e) { | |
if (!this._t.loaded) { | |
this._t._onbufferchange(0); | |
// should be 1, and the same | |
this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration()); | |
this._t._onload(true); | |
} | |
}), | |
emptied: _html5_event(function(e) { | |
//_s._wD(_h5+'emptied: '+this._t.sID); | |
}), | |
ended: _html5_event(function(e) { | |
//_s._wD(_h5+'ended: '+this._t.sID); | |
this._t._onfinish(); | |
}), | |
error: _html5_event(function(e) { | |
//_s._wD(_h5+'error: '+this.error.code); | |
// call load with error state? | |
this._t._onload(false); | |
}), | |
loadeddata: _html5_event(function(e) { | |
//_s._wD(_h5+'loadeddata: '+this._t.sID); | |
}), | |
loadedmetadata: _html5_event(function(e) { | |
//_s._wD(_h5+'loadedmetadata: '+this._t.sID); | |
}), | |
loadstart: _html5_event(function(e) { | |
//_s._wD(_h5+'loadstart: '+this._t.sID); | |
// assume buffering at first | |
this._t._onbufferchange(1); | |
}), | |
play: _html5_event(function(e) { | |
//_s._wD(_h5+'play: '+this._t.sID+', '+this._t.url); | |
// once play starts, no buffering | |
this._t._onbufferchange(0); | |
}), | |
// TODO: verify if this is actually implemented anywhere yet. | |
playing: _html5_event(function(e) { | |
//_s._wD(_h5+'playing: '+this._t.sID+', '+this._t.url); | |
// once play starts, no buffering | |
this._t._onbufferchange(0); | |
}), | |
progress: _html5_event(function(e) { | |
if (this._t.loaded) { | |
return false; | |
} | |
var i, j, str, loadSum = 0, buffered = 0, | |
isProgress = (e.type === 'progress'), | |
ranges = e.target.buffered, | |
loaded = (e.loaded||0), // firefox 3.6 implements e.loaded/total (bytes) | |
total = (e.total||1); | |
if (ranges && ranges.length) { | |
// if loaded is 0, try TimeRanges implementation as % of load | |
// https://developer.mozilla.org/en/DOM/TimeRanges | |
for (i=ranges.length; i--;) { | |
buffered = (ranges.end(i) - ranges.start(i)); | |
} | |
// linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges | |
loaded = buffered/e.target.duration; | |
/* | |
if (isProgress && ranges.length > 1) { | |
str = []; | |
j = ranges.length; | |
for (i=0; i<j; i++) { | |
str.push(e.target.buffered.start(i) +'-'+ e.target.buffered.end(i)); | |
} | |
//_s._wD(_h5+'progress: timeRanges: '+str.join(', ')); | |
} | |
*/ | |
if (isProgress && !isNaN(loaded)) { | |
//_s._wD(_h5+'progress: '+this._t.sID+': ' + Math.floor(loaded*100)+'% loaded'); | |
} | |
} | |
if (!isNaN(loaded)) { | |
this._t._onbufferchange(0); // if progress, likely not buffering | |
this._t._whileloading(loaded, total, this._t._get_html5_duration()); | |
if (loaded && total && loaded === total) { | |
// in case "onload" doesn't fire (eg. gecko 1.9.2) | |
_s._html5_events.load.call(this, e); | |
} | |
} | |
}), | |
ratechange: _html5_event(function(e) { | |
//_s._wD(_h5+'ratechange: '+this._t.sID); | |
}), | |
suspend: _html5_event(function(e) { | |
// download paused/stopped, may have finished (eg. onload) | |
//_s._wD(_h5+'suspend: '+this._t.sID); | |
_s._html5_events.progress.call(this, e); | |
}), | |
stalled: _html5_event(function(e) { | |
//_s._wD(_h5+'stalled: '+this._t.sID); | |
}), | |
timeupdate: _html5_event(function(e) { | |
this._t._onTimer(); | |
}), | |
waiting: _html5_event(function(e) { // see also: seeking | |
//_s._wD(_h5+'waiting: '+this._t.sID); | |
// playback faster than download rate, etc. | |
this._t._onbufferchange(1); | |
}) | |
}; | |
// --- SMSound (sound object) instance --- | |
SMSound = function(oOptions) { | |
var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer; | |
this.sID = oOptions.id; | |
this.url = oOptions.url; | |
this.options = _mixin(oOptions); | |
this.instanceOptions = this.options; // per-play-instance-specific options | |
this._iO = this.instanceOptions; // short alias | |
// assign property defaults | |
this.pan = this.options.pan; | |
this.volume = this.options.volume; | |
this._lastURL = null; | |
this.isHTML5 = false; | |
this._a = null; | |
// --- public methods --- | |
this.id3 = {}; | |
this._debug = function() { | |
/* | |
// 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 (_t.options[stuff] instanceof Function) { | |
// handle functions specially | |
sF = _t.options[stuff].toString(); | |
sF = sF.replace(/\s\s+/g, ' '); // normalize spaces | |
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}'); | |
} | |
*/ | |
}; | |
this._debug(); | |
this.load = function(oOptions) { | |
var oS = null; | |
if (typeof oOptions !== 'undefined') { | |
_t._iO = _mixin(oOptions); | |
_t.instanceOptions = _t._iO; | |
} else { | |
oOptions = _t.options; | |
_t._iO = oOptions; | |
_t.instanceOptions = _t._iO; | |
if (_t._lastURL && _t._lastURL !== _t.url) { | |
//_wDS('manURL'); | |
_t._iO.url = _t.url; | |
_t.url = null; | |
} | |
} | |
if (!_t._iO.url) { | |
_t._iO.url = _t.url; | |
} | |
//_s._wD('SMSound.load(): ' + _t._iO.url, 1); | |
if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { | |
//_wDS('onURL', 1); | |
return _t; | |
} | |
_t._lastURL = _t.url; | |
_t.loaded = false; | |
_t.readyState = 1; | |
_t.playState = 0; | |
if (_html5OK(_t._iO)) { | |
oS = _t._setup_html5(_t._iO); | |
if (!oS._called_load) { | |
//_s._wD(_h5+'load: '+_t.sID); | |
oS.load(); | |
oS._called_load = true; | |
if (_t._iO.autoPlay) { | |
_t.play(); | |
} | |
} else { | |
//_s._wD('HTML5 ignoring request to load again: '+_t.sID); | |
} | |
} else { | |
try { | |
_t.isHTML5 = false; | |
_t._iO = _policyFix(_loopFix(_t._iO)); | |
if (_fV === 8) { | |
_s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile); | |
} else { | |
_s.o._load(_t.sID, _t._iO.url, _t._iO.stream?true:false, _t._iO.autoPlay?true:false, _t._iO.loops||1, _t._iO.autoLoad?true:false, _t._iO.usePolicyFile); | |
} | |
} catch(e) { | |
//_wDS('smError', 2); | |
//_debugTS('onload', false); | |
_die(); | |
} | |
} | |
return _t; | |
}; | |
this.unload = function() { | |
// Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 | |
// Flash 9/AS3: Close stream, preventing further load | |
if (_t.readyState !== 0) { | |
//_s._wD('SMSound.unload(): "' + _t.sID + '"'); | |
if (!_t.isHTML5) { | |
if (_fV === 8) { | |
_s.o._unload(_t.sID, _s.nullURL); | |
} else { | |
_s.o._unload(_t.sID); | |
} | |
} else { | |
_stop_html5_timer(); | |
if (_t._a) { | |
// abort()-style method here, stop loading? (doesn't exist?) | |
_t._a.pause(); | |
// if (!_useGlobalHTML5Audio || (_useGlobalHTML5Audio && _t.playState)) { // if global audio, only unload if actively playing | |
_t._a.src = ''; // https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media | |
// } | |
} | |
} | |
// reset load/status flags | |
_resetProperties(); | |
} | |
return _t; | |
}; | |
this.destruct = function(_bFromSM) { | |
//_s._wD('SMSound.destruct(): "' + _t.sID + '"'); | |
if (!_t.isHTML5) { | |
// kill sound within Flash | |
// Disable the onfailure handler | |
_t._iO.onfailure = null; | |
_s.o._destroySound(_t.sID); | |
} else { | |
_stop_html5_timer(); | |
if (_t._a) { | |
// abort()-style method here, stop loading? (doesn't exist?) | |
_t._a.pause(); | |
_t._a.src = ''; // https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media | |
if (!_useGlobalHTML5Audio) { | |
_t._remove_html5_events(); | |
} | |
} | |
} | |
if (!_bFromSM) { | |
_s.destroySound(_t.sID, true); // ensure deletion from controller | |
} | |
}; | |
this.play = function(oOptions, _updatePlayState) { | |
var fN = 'SMSound.play(): ', allowMulti; | |
_updatePlayState = _updatePlayState === undefined ? true : _updatePlayState; // default true | |
if (!oOptions) { | |
oOptions = {}; | |
} | |
_t._iO = _mixin(oOptions, _t._iO); | |
_t._iO = _mixin(_t._iO, _t.options); | |
_t.instanceOptions = _t._iO; | |
if (_t._iO.serverURL) { | |
if (!_t.connected) { | |
if (!_t.getAutoPlay()) { | |
//_s._wD(fN+' Netstream not connected yet - setting autoPlay'); | |
_t.setAutoPlay(true); | |
} | |
return _t; // play will be called in _onconnect() | |
} | |
} | |
if (_html5OK(_t._iO)) { | |
_t._setup_html5(_t._iO); | |
_start_html5_timer(); | |
} | |
if (_t.playState === 1 && !_t.paused) { | |
allowMulti = _t._iO.multiShot; | |
if (!allowMulti) { | |
//_s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1); | |
return _t; | |
} else { | |
//_s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1); | |
if (_t.isHTML5) { | |
// TODO: BUG? | |
_t.setPosition(_t._iO.position); | |
} | |
} | |
} | |
if (!_t.loaded) { | |
if (_t.readyState === 0) { | |
//_s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1); | |
// try to get this sound playing ASAP | |
if (!_t.isHTML5) { | |
_t._iO.autoPlay = true; // assign directly because setAutoPlay() increments the instanceCount | |
_t.load(_t._iO); | |
} else { | |
_t.load(_t._iO); | |
// _t.readyState = 1; // redundant | |
} | |
} else if (_t.readyState === 2) { | |
//_s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2); | |
return _t; | |
} else { | |
//_s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1); | |
} | |
} else { | |
//_s._wD(fN + '"' + _t.sID + '"'); | |
} | |
// Streams will pause when their buffer is full if they are being loaded. | |
// In this case paused is true, but the song hasn't started playing yet. If | |
// we just call resume() the onplay() callback will never be called. So | |
// only call resume() if the position is > 0. | |
// Another reason is because options like volume won't have been applied yet. | |
if (_t.paused && _t.position && _t.position > 0) { // https://gist.github.com/37b17df75cc4d7a90bf6 | |
//_s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1); | |
_t.resume(); | |
} else { | |
//_s._wD(fN+'"'+ _t.sID+'" is starting to play'); | |
_t.playState = 1; | |
_t.paused = false; | |
if (!_t.instanceCount || _t._iO.multiShotEvents || (_fV > 8 && !_t.isHTML5 && !_t.getAutoPlay())) { | |
_t.instanceCount++; | |
} | |
_t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); | |
if (!_t.isHTML5) { | |
_t._iO = _policyFix(_loopFix(_t._iO)); | |
} | |
if (_t._iO.onplay && _updatePlayState) { | |
_t._iO.onplay.apply(_t); | |
_t._onplay_called = true; | |
} | |
_t.setVolume(_t._iO.volume, true); | |
_t.setPan(_t._iO.pan, true); | |
if (!_t.isHTML5) { | |
_s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t.position:_t.position / 1000)); | |
} else { | |
_start_html5_timer(); | |
_t._setup_html5().play(); | |
} | |
} | |
return _t; | |
}; | |
this.start = this.play; // just for convenience | |
this.stop = function(bAll) { | |
if (_t.playState === 1) { | |
_t._onbufferchange(0); | |
_t.resetOnPosition(0); | |
if (!_t.isHTML5) { | |
_t.playState = 0; | |
} | |
_t.paused = false; | |
if (_t._iO.onstop) { | |
_t._iO.onstop.apply(_t); | |
} | |
if (!_t.isHTML5) { | |
_s.o._stop(_t.sID, bAll); | |
// hack for netStream: just unload | |
if (_t._iO.serverURL) { | |
_t.unload(); | |
} | |
} else { | |
if (_t._a) { | |
_t.setPosition(0); // act like Flash, though | |
_t._a.pause(); // html5 has no stop() | |
_t.playState = 0; | |
_t._onTimer(); // and update UI | |
_stop_html5_timer(); | |
_t.unload(); | |
} | |
} | |
_t.instanceCount = 0; | |
_t._iO = {}; | |
} | |
return _t; | |
}; | |
this.setAutoPlay = function(autoPlay) { | |
//_s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off')); | |
_t._iO.autoPlay = autoPlay; | |
if (_t.isHTML5) { | |
if (_t._a && autoPlay) { | |
_t.play(); // HTML5 onload isn't reliable | |
} | |
} else { | |
_s.o._setAutoPlay(_t.sID, 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.sID+' incremented instance count to '+_t.instanceCount); | |
} | |
} | |
}; | |
this.getAutoPlay = function() { | |
return _t._iO.autoPlay; | |
}; | |
this.setPosition = function(nMsecOffset, bNoDebug) { | |
if (nMsecOffset === undefined) { | |
nMsecOffset = 0; | |
} | |
// Use the duration from the instance options, if we don't have a track duration yet. | |
var original_pos, position, position1K, offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); // position >= 0 and <= current available (loaded) duration | |
original_pos = _t.position; | |
_t.position = offset; | |
position1K = _t.position/1000; | |
_t.resetOnPosition(_t.position); | |
_t._iO.position = offset; | |
if (!_t.isHTML5) { | |
position = _fV === 9 ? _t.position : position1K; | |
if (_t.readyState && _t.readyState !== 2) { | |
_s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) | |
} | |
} else if (_t._a) { | |
// Set the position in the canplay handler if the sound is not ready yet | |
if (_t._html5_canplay) { | |
if (_t._a.currentTime !== position1K) { | |
// Only set the position if we need to. | |
// 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'); | |
try { | |
_t._a.currentTime = position1K; | |
} catch(e) { | |
//_s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2); | |
} | |
} | |
} else { | |
//_s._wD('setPosition('+position1K+'): delaying, sound not ready'); | |
} | |
} | |
if (_t.isHTML5) { | |
if (_t.paused) { // if paused, refresh UI right away | |
_t._onTimer(true); // force update | |
} | |
} | |
return _t; | |
}; | |
this.pause = function(bCallFlash) { | |
if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { | |
return _t; | |
} | |
//_s._wD('SMSound.pause()'); | |
_t.paused = true; | |
if (!_t.isHTML5) { | |
if (bCallFlash || bCallFlash === undefined) { | |
_s.o._pause(_t.sID); | |
} | |
} else { | |
_t._setup_html5().pause(); | |
_stop_html5_timer(); | |
} | |
if (_t._iO.onpause) { | |
_t._iO.onpause.apply(_t); | |
} | |
return _t; | |
}; | |
// When auto-loaded streams pause on buffer full they have a playState of 0. | |
// We need to make sure that the playState is set to 1 when these streams "resume". | |
// | |
// When a paused stream is resumed, we need to trigger the onplay() callback if it | |
// hasn't been called already. In this case since the sound is being played for the | |
// first time, I think it's more appropriate to call onplay() rather than onresume(). | |
this.resume = function() { | |
if (!_t.paused) { | |
return _t; | |
} | |
//_s._wD('SMSound.resume()'); | |
_t.paused = false; | |
_t.playState = 1; | |
if (!_t.isHTML5) { | |
if (_t._iO.isMovieStar) { | |
// 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.o._pause(_t.sID); // flash method is toggle-based (pause/resume) | |
} else { | |
_t._setup_html5().play(); | |
_start_html5_timer(); | |
} | |
if (!_t._onplay_called && _t._iO.onplay) { | |
_t._iO.onplay.apply(_t); | |
_t._onplay_called = true; | |
} else if (_t._iO.onresume) { | |
_t._iO.onresume.apply(_t); | |
} | |
return _t; | |
}; | |
this.togglePause = function() { | |
//_s._wD('SMSound.togglePause()'); | |
if (_t.playState === 0) { | |
_t.play({ | |
position: (_fV === 9 && !_t.isHTML5 ? _t.position:_t.position / 1000) | |
}); | |
return _t; | |
} | |
if (_t.paused) { | |
_t.resume(); | |
} else { | |
_t.pause(); | |
} | |
return _t; | |
}; | |
this.setPan = function(nPan, bInstanceOnly) { | |
if (typeof nPan === 'undefined') { | |
nPan = 0; | |
} | |
if (typeof bInstanceOnly === 'undefined') { | |
bInstanceOnly = false; | |
} | |
if (!_t.isHTML5) { | |
_s.o._setPan(_t.sID, nPan); | |
} // else { no HTML5 pan? } | |
_t._iO.pan = nPan; | |
if (!bInstanceOnly) { | |
_t.pan = nPan; | |
} | |
return _t; | |
}; | |
this.setVolume = function(nVol, bInstanceOnly) { | |
if (typeof nVol === 'undefined') { | |
nVol = 100; | |
} | |
if (typeof bInstanceOnly === 'undefined') { | |
bInstanceOnly = false; | |
} | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); | |
} else if (_t._a) { | |
_t._a.volume = nVol/100; | |
} | |
_t._iO.volume = nVol; | |
if (!bInstanceOnly) { | |
_t.volume = nVol; | |
} | |
return _t; | |
}; | |
this.mute = function() { | |
_t.muted = true; | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, 0); | |
} else if (_t._a) { | |
_t._a.muted = true; | |
} | |
return _t; | |
}; | |
this.unmute = function() { | |
_t.muted = false; | |
var hasIO = typeof _t._iO.volume !== 'undefined'; | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); | |
} else if (_t._a) { | |
_t._a.muted = false; | |
} | |
return _t; | |
}; | |
this.toggleMute = function() { | |
return (_t.muted?_t.unmute():_t.mute()); | |
}; | |
this.onposition = function(nPosition, oMethod, oScope) { | |
// TODO: allow for ranges, too? eg. (nPosition instanceof Array) | |
_t._onPositionItems.push({ | |
position: nPosition, | |
method: oMethod, | |
scope: (typeof oScope !== 'undefined'?oScope:_t), | |
fired: false | |
}); | |
return _t; | |
}; | |
this.processOnPosition = function() { | |
var i, item, j = _t._onPositionItems.length; | |
if (!j || !_t.playState || _t._onPositionFired >= j) { | |
return false; | |
} | |
for (i=j; i--;) { | |
item = _t._onPositionItems[i]; | |
if (!item.fired && _t.position >= item.position) { | |
item.method.apply(item.scope,[item.position]); | |
item.fired = true; | |
_s._onPositionFired++; | |
} | |
} | |
return true; | |
}; | |
this.resetOnPosition = function(nPosition) { | |
// reset "fired" for items interested in this position | |
var i, item, j = _t._onPositionItems.length; | |
if (!j) { | |
return false; | |
} | |
for (i=j; i--;) { | |
item = _t._onPositionItems[i]; | |
if (item.fired && nPosition <= item.position) { | |
item.fired = false; | |
_s._onPositionFired--; | |
} | |
} | |
return true; | |
}; | |
// pseudo-private soundManager reference | |
this._onTimer = function(bForce) { | |
// HTML5-only _whileplaying() etc. | |
var time, x = {}; | |
if (_t._hasTimer || bForce) { | |
if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { // TODO: May not need to track readyState (1 = loading) | |
_t.duration = _t._get_html5_duration(); | |
_t.durationEstimate = _t.duration; | |
time = _t._a.currentTime?_t._a.currentTime*1000:0; | |
_t._whileplaying(time,x,x,x,x); | |
return true; | |
} else { | |
//_s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); | |
return false; | |
} | |
} | |
}; | |
// --- private internals --- | |
this._get_html5_duration = function() { | |
var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)); | |
return (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null)); | |
}; | |
_start_html5_timer = function() { | |
if (_t.isHTML5) { | |
_startTimer(_t); | |
} | |
}; | |
_stop_html5_timer = function() { | |
if (_t.isHTML5) { | |
_stopTimer(_t); | |
} | |
}; | |
_resetProperties = function(bLoaded) { | |
_t._onPositionItems = []; | |
_t._onPositionFired = 0; | |
_t._hasTimer = null; | |
_t._onplay_called = false; | |
_t._a = null; | |
_t._html5_canplay = false; | |
_t.bytesLoaded = null; | |
_t.bytesTotal = null; | |
_t.position = null; | |
_t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null); | |
_t.durationEstimate = null; | |
_t.failures = 0; | |
_t.loaded = false; | |
_t.playState = 0; | |
_t.paused = false; | |
_t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success | |
_t.muted = false; | |
_t.didBeforeFinish = false; | |
_t.didJustBeforeFinish = false; | |
_t.isBuffering = false; | |
_t.instanceOptions = {}; | |
_t.instanceCount = 0; | |
_t.peakData = { | |
left: 0, | |
right: 0 | |
}; | |
_t.waveformData = { | |
left: [], | |
right: [] | |
}; | |
_t.eqData = []; // legacy: 1D array | |
_t.eqData.left = []; | |
_t.eqData.right = []; | |
}; | |
_resetProperties(); | |
// pseudo-private methods used by soundManager | |
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); | |
if (_a) { | |
if (_a._t && _oldIO.url === _iO.url) { | |
return _a; // same url, ignore request | |
} | |
//_s._wD('setting new URL on existing object: '+_dURL+', old URL: '+d(_oldIO.url)); | |
/* | |
* "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 (_useGlobalHTML5Audio && _a._t.playState && _a._t && _iO.url !== _oldIO.url) { | |
_a._t.stop(); | |
} | |
_resetProperties(); // new URL, so reset load/playstate and so on | |
_a.src = _iO.url; | |
} else { | |
//_s._wD('creating HTML5 Audio() element with URL: '+_dURL); | |
_a = new Audio(_iO.url); | |
if (_useGlobalHTML5Audio) { | |
_s._global_a = _a; | |
} | |
} | |
_a._called_load = false; | |
_t.isHTML5 = true; | |
_t._a = _a; // store a ref on the track | |
_a._t = _t; // store a ref on the audio | |
_t._add_html5_events(); | |
_a.loop = (_iO.loops>1?'loop':''); | |
if (_iO.autoLoad || _iO.autoPlay) { | |
_a.autobuffer = 'auto'; // early HTML5 implementation (non-standard) | |
_a.preload = 'auto'; // standard | |
_t.load(); | |
} else { | |
_a.autobuffer = false; // early HTML5 implementation (non-standard) | |
_a.preload = 'none'; // standard | |
} | |
_a.loop = (_iO.loops>1?'loop':''); // boolean instead of "loop", for webkit? - spec says string. http://www.w3.org/TR/html-markup/audio.html#audio.attrs.loop | |
return _a; | |
}; | |
// related private methods | |
this._add_html5_events = function() { | |
if (_t._a._added_events) { | |
return false; | |
} | |
var f; | |
function add(oEvt, oFn, bCapture) { | |
return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null; | |
} | |
//_s._wD(_h5+'adding event listeners: '+_t.sID); | |
_t._a._added_events = true; | |
for (f in _s._html5_events) { | |
if (_s._html5_events.hasOwnProperty(f)) { | |
add(f, _s._html5_events[f]); | |
} | |
} | |
return true; | |
}; | |
// Keep this externally accessible | |
this._remove_html5_events = function() { | |
// Remove event listeners | |
function remove(oEvt, oFn, bCapture) { | |
return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null); | |
} | |
//_s._wD(_h5+'removing event listeners: '+_t.sID); | |
_t._a._added_events = false; | |
for (var f in _s._html5_events) { | |
if (_s._html5_events.hasOwnProperty(f)) { | |
remove(f, _s._html5_events[f]); | |
} | |
} | |
}; | |
// --- "private" methods called by Flash --- | |
this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { | |
_t.bytesLoaded = nBytesLoaded; | |
_t.bytesTotal = nBytesTotal; | |
_t.duration = Math.floor(nDuration); | |
_t.bufferLength = nBufferLength; | |
if (!_t._iO.isMovieStar) { | |
if (_t._iO.duration) { | |
// use options, if specified and larger | |
_t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration; | |
} else { | |
_t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); | |
} | |
if (_t.durationEstimate === undefined) { | |
_t.durationEstimate = _t.duration; | |
} | |
if (_t.readyState !== 3 && _t._iO.whileloading) { | |
_t._iO.whileloading.apply(_t); | |
} | |
} else { | |
_t.durationEstimate = _t.duration; | |
if (_t.readyState !== 3 && _t._iO.whileloading) { | |
_t._iO.whileloading.apply(_t); | |
} | |
} | |
}; | |
this._onid3 = function(oID3PropNames, oID3Data) { | |
// oID3PropNames: string array (names) | |
// ID3Data: string array (data) | |
//_s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.'); | |
var oData = [], i, j; | |
for (i = 0, j = oID3PropNames.length; i < j; i++) { | |
oData[oID3PropNames[i]] = oID3Data[i]; | |
} | |
_t.id3 = _mixin(_t.id3, oData); | |
if (_t._iO.onid3) { | |
_t._iO.onid3.apply(_t); | |
} | |
}; | |
this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { | |
if (isNaN(nPosition) || nPosition === null) { | |
return false; // flash safety net | |
} | |
if (_t.playState === 0 && nPosition > 0) { | |
// invalid position edge case for end/stop | |
nPosition = 0; | |
} | |
_t.position = nPosition; | |
_t.processOnPosition(); | |
if (_fV > 8 && !_t.isHTML5) { | |
if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { | |
_t.peakData = { | |
left: oPeakData.leftPeak, | |
right: oPeakData.rightPeak | |
}; | |
} | |
if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { | |
_t.waveformData = { | |
left: oWaveformDataLeft.split(','), | |
right: oWaveformDataRight.split(',') | |
}; | |
} | |
if (_t._iO.useEQData) { | |
if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { | |
var eqLeft = oEQData.leftEQ.split(','); | |
_t.eqData = eqLeft; | |
_t.eqData.left = eqLeft; | |
if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { | |
_t.eqData.right = oEQData.rightEQ.split(','); | |
} | |
} | |
} | |
} | |
if (_t.playState === 1) { | |
// special case/hack: ensure buffering is false if loading from cache (and not yet started) | |
if (!_t.isHTML5 && _s.flashVersion === 8 && !_t.position && _t.isBuffering) { | |
_t._onbufferchange(0); | |
} | |
if (_t._iO.whileplaying) { | |
_t._iO.whileplaying.apply(_t); // flash may call after actual finish | |
} | |
if ((_t.loaded || (!_t.loaded && _t._iO.isMovieStar)) && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { | |
_t._onbeforefinish(); | |
} | |
} | |
return true; | |
}; | |
// Only applies to RTMP | |
this._onconnect = function(bSuccess) { | |
var fN = 'SMSound._onconnect(): '; | |
bSuccess = (bSuccess === 1); | |
//_s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); | |
_t.connected = bSuccess; | |
if (bSuccess) { | |
_t.failures = 0; | |
if (_idCheck(_t.sID)) { | |
if (_t.getAutoPlay()) { | |
_t.play(undefined, _t.getAutoPlay()); // only update the play state if auto playing | |
} else if (_t._iO.autoLoad) { | |
_t.load(); | |
} | |
} | |
if (_t._iO.onconnect) { | |
_t._iO.onconnect.apply(_t,[bSuccess]); | |
} | |
} | |
}; | |
this._onload = function(nSuccess) { | |
var fN = 'SMSound._onload(): ', loadOK = (nSuccess?true:false); | |
//_s._wD(fN + '"' + _t.sID + '"' + (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); | |
} | |
if (_s.sandbox.noLocal === true) { | |
//_s._wD(fN + _str('noLocal'), 1); | |
} | |
} | |
*/ | |
_t.loaded = loadOK; | |
_t.readyState = loadOK?3:2; | |
_t._onbufferchange(0); | |
if (_t._iO.onload) { | |
_t._iO.onload.apply(_t, [loadOK]); | |
} | |
return true; | |
}; | |
// fire onfailure() only once at most | |
// 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.sID+'" count '+_t.failures); | |
if (_t._iO.onfailure && _t.failures === 1) { | |
_t._iO.onfailure(_t, msg, level, code); | |
} else { | |
//_s._wD('SMSound._onfailure(): ignoring'); | |
} | |
}; | |
this._onbeforefinish = function() { | |
if (!_t.didBeforeFinish) { | |
_t.didBeforeFinish = true; | |
if (_t._iO.onbeforefinish) { | |
//_s._wD('SMSound._onbeforefinish(): "' + _t.sID + '"'); | |
_t._iO.onbeforefinish.apply(_t); | |
} | |
} | |
}; | |
this._onjustbeforefinish = function(msOffset) { | |
if (!_t.didJustBeforeFinish) { | |
_t.didJustBeforeFinish = true; | |
if (_t._iO.onjustbeforefinish) { | |
//_s._wD('SMSound._onjustbeforefinish(): "' + _t.sID + '"'); | |
_t._iO.onjustbeforefinish.apply(_t); | |
} | |
} | |
}; | |
this._onfinish = function() { | |
// //_s._wD('SMSound._onfinish(): "' + _t.sID + '" got instanceCount '+_t.instanceCount); | |
var _io_onfinish = _t._iO.onfinish; // store local copy before it gets trashed.. | |
_t._onbufferchange(0); | |
_t.resetOnPosition(0); | |
if (_t._iO.onbeforefinishcomplete) { | |
_t._iO.onbeforefinishcomplete.apply(_t); | |
} | |
// reset some state items | |
_t.didBeforeFinish = false; | |
_t.didJustBeforeFinish = false; | |
if (_t.instanceCount) { | |
_t.instanceCount--; | |
if (!_t.instanceCount) { | |
// reset instance options | |
_t.playState = 0; | |
_t.paused = false; | |
_t.instanceCount = 0; | |
_t.instanceOptions = {}; | |
_t._iO = {}; | |
_stop_html5_timer(); | |
} | |
if (!_t.instanceCount || _t._iO.multiShotEvents) { | |
// fire onfinish for last, or every instance | |
if (_io_onfinish) { | |
//_s._wD('SMSound._onfinish(): "' + _t.sID + '"'); | |
_io_onfinish.apply(_t); | |
} | |
} | |
} | |
}; | |
this._onbufferchange = function(nIsBuffering) { | |
var fN = 'SMSound._onbufferchange()'; | |
if (_t.playState === 0) { | |
// ignore if not playing | |
return false; | |
} | |
if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { | |
return false; | |
} | |
_t.isBuffering = (nIsBuffering === 1); | |
if (_t._iO.onbufferchange) { | |
//_s._wD(fN + ': ' + nIsBuffering); | |
_t._iO.onbufferchange.apply(_t); | |
} | |
return true; | |
}; | |
this._ondataerror = function(sError) { | |
// flash 9 wave/eq data handler | |
if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish() | |
//_s._wD('SMSound._ondataerror(): ' + sError); | |
if (_t._iO.ondataerror) { | |
_t._iO.ondataerror.apply(_t); | |
} | |
} | |
}; | |
}; // SMSound() | |
// --- private SM2 internals --- | |
_getDocument = function() { | |
return (_doc.body?_doc.body:(_doc._docElement?_doc.documentElement:_doc.getElementsByTagName('div')[0])); | |
}; | |
_id = function(sID) { | |
return _doc.getElementById(sID); | |
}; | |
_mixin = function(oMain, oAdd) { | |
// non-destructive merge | |
var o1 = {}, i, o2, o; | |
for (i in oMain) { // clone c1 | |
if (oMain.hasOwnProperty(i)) { | |
o1[i] = oMain[i]; | |
} | |
} | |
o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd); | |
for (o in o2) { | |
if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { | |
o1[o] = o2[o]; | |
} | |
} | |
return o1; | |
}; | |
_event = (function() { | |
var old = (_win.attachEvent), | |
evt = { | |
add: (old?'attachEvent':'addEventListener'), | |
remove: (old?'detachEvent':'removeEventListener') | |
}; | |
function getArgs(oArgs) { | |
var args = _slice.call(oArgs), len = args.length; | |
if (old) { | |
args[1] = 'on' + args[1]; // prefix | |
if (len > 3) { | |
args.pop(); // no capture | |
} | |
} else if (len === 3) { | |
args.push(false); | |
} | |
return args; | |
} | |
function apply(args, sType) { | |
var element = args.shift(), | |
method = [evt[sType]]; | |
if (old) { | |
element[method](args[0], args[1]); | |
} else { | |
element[method].apply(element, args); | |
} | |
} | |
function add() { | |
apply(getArgs(arguments), 'add'); | |
} | |
function remove() { | |
apply(getArgs(arguments), 'remove'); | |
} | |
return { | |
'add': add, | |
'remove': remove | |
}; | |
}()); | |
_html5OK = function(iO) { | |
return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay(iO.url)||_html5Only)); // Use type, if specified. If HTML5-only mode, no other options, so just give 'er | |
}; | |
_html5CanPlay = function(sURL) { | |
// try to find MIME, test and return truthiness | |
if (!_s.useHTML5Audio || !_s.hasHTML5) { | |
return false; | |
} | |
var result, mime, offset, fileExt, item, aF = _s.audioFormats; | |
if (!_html5Ext) { | |
_html5Ext = []; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
_html5Ext.push(item); | |
if (aF[item].related) { | |
_html5Ext = _html5Ext.concat(aF[item].related); | |
} | |
} | |
} | |
_html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')','i'); | |
} | |
mime = (typeof sURL.type !== 'undefined'?sURL.type:null); | |
fileExt = (typeof sURL === 'string'?sURL.toLowerCase().match(_html5Ext):null); // TODO: Strip URL queries, etc. | |
if (!fileExt || !fileExt.length) { | |
if (!mime) { | |
return false; | |
} else { | |
// audio/mp3 -> mp3, result should be known | |
offset = mime.indexOf(';'); | |
fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6); // strip "audio/X; codecs.." | |
} | |
} else { | |
fileExt = fileExt[0].substr(1); // "mp3", for example | |
} | |
if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { | |
// result known | |
return _s.html5[fileExt]; | |
} else { | |
if (!mime) { | |
if (fileExt && _s.html5[fileExt]) { | |
return _s.html5[fileExt]; | |
} else { | |
// best-case guess, audio/whatever-dot-filename-format-you're-playing | |
mime = 'audio/'+fileExt; | |
} | |
} | |
result = _s.html5.canPlayType(mime); | |
_s.html5[fileExt] = result; | |
// //_s._wD('canPlayType, found result: '+result); | |
return result; | |
} | |
}; | |
_testHTML5 = function() { | |
if (!_s.useHTML5Audio || typeof Audio === 'undefined') { | |
return false; | |
} | |
var a = (typeof Audio !== 'undefined' ? new Audio(null):null), item, support = {}, aF, i, _hasFlash = _detectFlash(); | |
function _cp(m) { | |
var canPlay, i, j, isOK = false; | |
if (!a || typeof a.canPlayType !== 'function') { | |
return false; | |
} | |
if (m instanceof Array) { | |
// iterate through all mime types, return any successes | |
for (i=0, j=m.length; i<j && !isOK; i++) { | |
if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) { | |
isOK = true; | |
_s.html5[m[i]] = true; | |
} | |
} | |
return isOK; | |
} else { | |
canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false); | |
return (canPlay && (canPlay.match(_s.html5Test)?true:false)); | |
} | |
} | |
// test all registered formats + codecs | |
aF = _s.audioFormats; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
support[item] = _cp(aF[item].type); | |
// assign result to related formats, too | |
if (aF[item] && aF[item].related) { | |
for (i=aF[item].related.length; i--;) { | |
_s.html5[aF[item].related[i]] = support[item]; | |
} | |
} | |
} | |
} | |
support.canPlayType = (a?_cp:null); | |
_s.html5 = _mixin(_s.html5, support); | |
return true; | |
}; | |
_strings = { | |
/* | |
notReady: 'Not loaded yet - wait for soundManager.onload()/onready()', | |
notOK: 'Audio support is not available.', | |
appXHTML: _smc + 'createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', | |
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.)', | |
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 focus-related event..', | |
waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', | |
waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', | |
needFunction: _sm + ': Function object expected for %s', | |
badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', | |
noMS: 'MovieStar mode not enabled. Exiting.', | |
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 to call Flash from JS..', | |
noPolling: _sm + ': Polling (whileloading()/whileplaying() support) is disabled.', | |
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.', | |
noPeak: 'Warning: peakData features unsupported for movieStar formats', | |
shutdown: _sm + '.disable(): Shutting down', | |
queue: _sm + ': Queueing %s handler', | |
smFail: _sm + ': Failed to initialise.', | |
smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', | |
fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..', | |
fbLoaded: 'Flash loaded', | |
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.', | |
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', | |
mfOn: 'mobileFlash::enabling on-screen flash repositioning', | |
policy: 'Enabling usePolicyFile for data access' | |
*/ | |
}; | |
_str = function() { // o [,items to replace] | |
/* | |
var args = _slice.call(arguments), // real array, please | |
o = args.shift(), // first arg | |
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]); | |
} | |
} | |
return str; | |
*/ | |
}; | |
_loopFix = function(sOpt) { | |
// flash 8 requires stream = false for looping to work | |
if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { | |
//_wDS('as2loop'); | |
sOpt.stream = false; | |
} | |
return sOpt; | |
}; | |
_policyFix = function(sOpt, sPre) { | |
if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { | |
//_s._wD((sPre?sPre+':':'') + _str('policy')); | |
sOpt.usePolicyFile = true; | |
} | |
return sOpt; | |
}; | |
_complain = function(sMsg) { | |
if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { | |
console.warn(sMsg); | |
} else { | |
//_s._wD(sMsg); | |
} | |
}; | |
_doNothing = function() { | |
return false; | |
}; | |
_disableObject = function(o) { | |
for (var oProp in o) { | |
if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { | |
o[oProp] = _doNothing; | |
} | |
} | |
oProp = null; | |
}; | |
_failSafely = function(bNoDisable) { | |
// general failure exception handler | |
if (typeof bNoDisable === 'undefined') { | |
bNoDisable = false; | |
} | |
if (_disabled || bNoDisable) { | |
//_wDS('smFail', 2); | |
_s.disable(bNoDisable); | |
} | |
}; | |
_normalizeMovieURL = function(smURL) { | |
var urlParams = null; | |
if (smURL) { | |
if (smURL.match(/\.swf(\?.*)?$/i)) { | |
urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4); | |
if (urlParams) { | |
return smURL; // assume user knows what they're doing | |
} | |
} else if (smURL.lastIndexOf('/') !== smURL.length - 1) { | |
smURL = smURL + '/'; | |
} | |
} | |
return (smURL && smURL.lastIndexOf('/') !== - 1?smURL.substr(0, smURL.lastIndexOf('/') + 1):'./') + _s.movieURL; | |
}; | |
_setVersionInfo = function() { | |
if (_fV !== 8 && _fV !== 9) { | |
//_s._wD(_str('badFV', _fV, _defaultFlashVersion)); | |
_s.flashVersion = _defaultFlashVersion; | |
} | |
var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); // debug flash movie, if applicable | |
if (_s.useHTML5Audio && !_html5Only && _s.audioFormats.mp4.required && _s.flashVersion < 9) { | |
//_s._wD(_str('needfl9')); | |
_s.flashVersion = 9; | |
} | |
_fV = _s.flashVersion; // short-hand for internal use | |
_s.version = _s.versionNumber + (_html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); | |
// set up default options | |
if (_fV > 8) { | |
_s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); | |
_s.features.buffering = true; | |
} | |
if (_fV > 8 && _s.useMovieStar) { | |
// flash 9+ support for movieStar formats as well as MP3 | |
_s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); | |
_s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _s.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); | |
_s.mimePattern = _s.netStreamMimeTypes; | |
_s.features.movieStar = true; | |
} else { | |
_s.useMovieStar = false; | |
_s.features.movieStar = false; | |
} | |
_s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; | |
_s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf',isDebug); | |
_s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); | |
}; | |
_setPolling = function(bPolling, bHighPerformance) { | |
if (!_s.o || !_s.allowPolling) { | |
return false; | |
} | |
_s.o._setPolling(bPolling, bHighPerformance); | |
}; | |
function _initDebug() { | |
if (_s.debugURLParam.test(_wl)) { | |
_s.debugMode = true; // allow force of debug mode via URL | |
} | |
/* | |
if (_id(_s.debugID)) { | |
return false; | |
} | |
var oD, oDebug, oTarget, oToggle, tmp; | |
if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) { | |
oD = _doc.createElement('div'); | |
oD.id = _s.debugID + '-toggle'; | |
oToggle = { | |
'position': 'fixed', | |
'bottom': '0px', | |
'right': '0px', | |
'width': '1.2em', | |
'height': '1.2em', | |
'lineHeight': '1.2em', | |
'margin': '2px', | |
'textAlign': 'center', | |
'border': '1px solid #999', | |
'cursor': 'pointer', | |
'background': '#fff', | |
'color': '#333', | |
'zIndex': 10001 | |
}; | |
oD.appendChild(_doc.createTextNode('-')); | |
oD.onclick = _toggleDebug; | |
oD.title = 'Toggle SM2 debug console'; | |
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'); | |
if (_s.debugMode && !_id(oD.id)) { | |
try { | |
oTarget = _getDocument(); | |
oTarget.appendChild(oD); | |
} catch(e2) { | |
throw new Error(_str('appXHTML')); | |
} | |
oTarget.appendChild(oDebug); | |
} | |
} | |
oTarget = null; | |
*/ | |
} | |
_createMovie = function(smID, smURL) { | |
var specialCase = null, | |
remoteURL = (smURL?smURL:_s.url), | |
localURL = (_s.altURL?_s.altURL:remoteURL), | |
oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(), s, x, sClass, side = '100%', isRTL = null, html = _doc.getElementsByTagName('html')[0]; | |
isRTL = (html && html.dir && html.dir.match(/rtl/i)); | |
smID = (typeof smID === 'undefined'?_s.id:smID); | |
if (_didAppend && _appendSuccess) { | |
return false; // ignore if already succeeded | |
} | |
function _initMsg() { | |
//_s._wD('-- SoundManager 2 ' + _s.version + (!_html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_html5Only ? (_s.useMovieStar?', MovieStar mode':'') + (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : (_s.useFastPolling?'fast':'normal')) + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1); | |
} | |
if (_html5Only) { | |
_setVersionInfo(); | |
_initMsg(); | |
_s.oMC = _id(_s.movieID); | |
_init(); | |
// prevent multiple init attempts | |
_didAppend = true; | |
_appendSuccess = true; | |
return false; | |
} | |
_didAppend = true; | |
// safety check for legacy (change to Flash 9 URL) | |
_setVersionInfo(); | |
_s.url = _normalizeMovieURL(_s._overHTTP?remoteURL:localURL); | |
smURL = _s.url; | |
_s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); | |
if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { | |
_s.specialWmodeCase = true; | |
// 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 Jan.2011 (?) | |
//_wDS('spcWmode'); | |
_s.wmode = null; | |
} | |
oEmbed = { | |
'name': smID, | |
'id': smID, | |
'src': smURL, | |
'width': side, | |
'height': side, | |
'quality': 'high', | |
'allowScriptAccess': _s.allowScriptAccess, | |
'bgcolor': _s.bgColor, | |
'pluginspage': 'http://www.macromedia.com/go/getflashplayer', | |
'type': 'application/x-shockwave-flash', | |
'wmode': _s.wmode, | |
'hasPriority': 'true' // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html | |
}; | |
if (_s.debugFlash) { | |
oEmbed.FlashVars = 'debug=1'; | |
} | |
if (!_s.wmode) { | |
delete oEmbed.wmode; // don't write empty attribute | |
} | |
if (_isIE) { | |
// IE is "special". | |
oMovie = _doc.createElement('div'); | |
movieHTML = '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '"><param name="movie" value="' + smURL + '" /><param name="AllowScriptAccess" value="' + _s.allowScriptAccess + '" /><param name="quality" value="' + oEmbed.quality + '" />' + (_s.wmode?'<param name="wmode" value="' + _s.wmode + '" /> ':'') + '<param name="bgcolor" value="' + _s.bgColor + '" />' + (_s.debugFlash?'<param name="FlashVars" value="' + oEmbed.FlashVars + '" />':'') + '</object>'; | |
} else { | |
oMovie = _doc.createElement('embed'); | |
for (tmp in oEmbed) { | |
if (oEmbed.hasOwnProperty(tmp)) { | |
oMovie.setAttribute(tmp, oEmbed[tmp]); | |
} | |
} | |
} | |
_initDebug(); | |
extraClass = _getSWFCSS(); | |
oTarget = _getDocument(); | |
if (oTarget) { | |
_s.oMC = _id(_s.movieID)?_id(_s.movieID):_doc.createElement('div'); | |
if (!_s.oMC.id) { | |
_s.oMC.id = _s.movieID; | |
_s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass; | |
// "hide" flash movie | |
s = null; | |
oEl = null; | |
if (!_s.useFlashBlock) { | |
if (_s.useHighPerformance) { | |
s = { | |
'position': 'fixed', | |
'width': '8px', | |
'height': '8px', | |
// >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes. | |
'bottom': '0px', | |
'left': '0px', | |
'overflow': 'hidden' | |
}; | |
} else { | |
s = { | |
'position': 'absolute', | |
'width': '6px', | |
'height': '6px', | |
'top': '-9999px', | |
'left': '-9999px' | |
}; | |
if (isRTL) { | |
s.left = Math.abs(parseInt(s.left,10))+'px'; | |
} | |
} | |
} | |
if (_isWebkit) { | |
_s.oMC.style.zIndex = 10000; // soundcloud-reported render/crash fix, safari 5 | |
} | |
if (!_s.debugFlash) { | |
for (x in s) { | |
if (s.hasOwnProperty(x)) { | |
_s.oMC.style[x] = s[x]; | |
} | |
} | |
} | |
try { | |
if (!_isIE) { | |
_s.oMC.appendChild(oMovie); | |
} | |
oTarget.appendChild(_s.oMC); | |
if (_isIE) { | |
oEl = _s.oMC.appendChild(_doc.createElement('div')); | |
oEl.className = _s.swfCSS.swfBox; | |
oEl.innerHTML = movieHTML; | |
} | |
_appendSuccess = true; | |
} catch(e) { | |
throw new Error(_str('appXHTML')); | |
} | |
} else { | |
// it's already in the document. | |
sClass = _s.oMC.className; | |
_s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:''); | |
_s.oMC.appendChild(oMovie); | |
if (_isIE) { | |
oEl = _s.oMC.appendChild(_doc.createElement('div')); | |
oEl.className = _s.swfCSS.swfBox; | |
oEl.innerHTML = movieHTML; | |
} | |
_appendSuccess = true; | |
} | |
} | |
if (specialCase) { | |
//_s._wD(specialCase); | |
} | |
_initMsg(); | |
//_s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_s._overHTTP && _s.altURL?' (alternate URL)':''), 1); | |
return true; | |
}; | |
_idCheck = this.getSoundById; | |
_initMovie = function() { | |
if (_html5Only) { | |
_createMovie(); | |
return false; | |
} | |
// attempt to get, or create, movie | |
if (_s.o) { | |
return false; // may already exist | |
} | |
_s.o = _s.getMovie(_s.id); // inline markup | |
if (!_s.o) { | |
if (!_oRemoved) { | |
// try to create | |
_createMovie(_s.id, _s.url); | |
} else { | |
// try to re-append removed movie after reboot() | |
if (!_isIE) { | |
_s.oMC.appendChild(_oRemoved); | |
} else { | |
_s.oMC.innerHTML = _oRemovedHTML; | |
} | |
_oRemoved = null; | |
_didAppend = true; | |
} | |
_s.o = _s.getMovie(_s.id); | |
} | |
if (_s.o) { | |
//_s._wD(_smc+'initMovie(): Got '+_s.o.nodeName+' element ('+(_didAppend?'created via JS':'static HTML')+')'); | |
//_wDS('waitEI'); | |
} | |
if (_s.oninitmovie instanceof Function) { | |
setTimeout(_s.oninitmovie, 1); | |
} | |
return true; | |
}; | |
_go = function(sURL) { | |
// where it all begins. | |
if (sURL) { | |
_s.url = sURL; | |
} | |
_initMovie(); | |
}; | |
_delayWaitForEI = function() { | |
setTimeout(_waitForEI, 500); | |
}; | |
_waitForEI = function() { | |
if (_waitingForEI) { | |
return false; | |
} | |
_waitingForEI = true; | |
_event.remove(_win, 'load', _delayWaitForEI); | |
if (_tryInitOnFocus && !_isFocused) { | |
//_wDS('waitFocus'); | |
return false; | |
} | |
var p; | |
if (!_didInit) { | |
p = _s.getMoviePercent(); | |
//_s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':'')))); | |
} | |
setTimeout(function() { | |
p = _s.getMoviePercent(); | |
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 (!_s._overHTTP && p) { | |
//_wDS('localFail', 2); | |
if (!_s.debugFlash) { | |
//_wDS('tryDebug', 2); | |
} | |
} | |
if (p === 0) { | |
// if 0 (not null), probably a 404. | |
//_s._wD(_str('swf404', _s.url)); | |
} | |
//_debugTS('flashtojs', false, ': Timed out' + _s._overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); | |
} | |
// give up / time-out, depending | |
if (!_didInit && _okToDisable) { | |
if (p === null) { | |
// SWF failed. Maybe blocked. | |
if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { | |
if (_s.useFlashBlock) { | |
_flashBlockHandler(); | |
} | |
//_wDS('waitForever'); | |
} else { | |
// old SM2 behaviour, simply fail | |
_failSafely(true); | |
} | |
} else { | |
// flash loaded? Shouldn't be a blocking issue, then. | |
if (_s.flashLoadTimeout === 0) { | |
//_wDS('waitForever'); | |
} else { | |
_failSafely(true); | |
} | |
} | |
} | |
}, _s.flashLoadTimeout); | |
}; | |
_go = function(sURL) { | |
// where it all begins. | |
if (sURL) { | |
_s.url = sURL; | |
} | |
_initMovie(); | |
}; | |
/* | |
_wDS = function(o, errorLevel) { | |
if (!o) { | |
return ''; | |
} else { | |
return //_s._wD(_str(o), errorLevel); | |
} | |
}; | |
if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { | |
_s._wD = function(sText) {window.alert(sText);}; | |
} | |
_toggleDebug = function() { | |
var o = _id(_s.debugID), | |
oT = _id(_s.debugID + '-toggle'); | |
if (!o) { | |
return false; | |
} | |
if (_debugOpen) { | |
// minimize | |
oT.innerHTML = '+'; | |
o.style.display = 'none'; | |
} else { | |
oT.innerHTML = '-'; | |
o.style.display = 'block'; | |
} | |
_debugOpen = !_debugOpen; | |
}; | |
_debugTS = function(sEventType, bSuccess, sMessage) { | |
// troubleshooter debug hooks | |
if (typeof sm2Debugger !== 'undefined') { | |
try { | |
sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); | |
} catch(e) { | |
// oh well | |
} | |
} | |
return true; | |
}; | |
*/ | |
_getSWFCSS = function() { | |
var css = []; | |
if (_s.debugMode) { | |
css.push(_s.swfCSS.sm2Debug); | |
} | |
if (_s.debugFlash) { | |
css.push(_s.swfCSS.flashDebug); | |
} | |
if (_s.useHighPerformance) { | |
css.push(_s.swfCSS.highPerf); | |
} | |
return css.join(' '); | |
}; | |
_flashBlockHandler = function() { | |
// *possible* flash block situation. | |
var name = _str('fbHandler'), p = _s.getMoviePercent(), css = _s.swfCSS; | |
if (!_s.ok()) { | |
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')+')':'')); | |
} | |
_s.didFlashBlock = true; | |
_processOnEvents({type:'ontimeout',ignoreInit:true}); // fire onready(), complain lightly | |
if (_s.onerror instanceof Function) { | |
_s.onerror.apply(_win); | |
} | |
} else { | |
// SM2 loaded OK (or recovered) | |
if (_s.didFlashBlock) { | |
//_s._wD(name+': Unblocked'); | |
} | |
if (_s.oMC) { | |
_s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); | |
} | |
} | |
}; | |
_handleFocus = function() { | |
function cleanup() { | |
_event.remove(_win, 'focus', _handleFocus); | |
_event.remove(_win, 'load', _handleFocus); | |
} | |
if (_isFocused || !_tryInitOnFocus) { | |
cleanup(); | |
return true; | |
} | |
_okToDisable = true; | |
_isFocused = true; | |
//_s._wD(_smc+'handleFocus()'); | |
if (_isSafari && _tryInitOnFocus) { | |
// giant Safari 3.1 hack - assume mousemove = focus given lack of focus event | |
_event.remove(_win, 'mousemove', _handleFocus); | |
} | |
// allow init to restart | |
_waitingForEI = false; | |
cleanup(); | |
return true; | |
}; | |
_initComplete = function(bNoDisable) { | |
if (_didInit) { | |
return false; | |
} | |
if (_html5Only) { | |
// all good. | |
//_s._wD('-- SoundManager 2: loaded --'); | |
_didInit = true; | |
_processOnEvents(); | |
_initUserOnload(); | |
return true; | |
} | |
var sClass = _s.oMC.className, | |
wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()); | |
if (!wasTimeout) { | |
_didInit = true; | |
} | |
//_s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1); | |
if (_disabled || bNoDisable) { | |
if (_s.useFlashBlock) { | |
_s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); | |
} | |
_processOnEvents({type:'ontimeout'}); | |
//_debugTS('onload', false); | |
if (_s.onerror instanceof Function) { | |
_s.onerror.apply(_win); | |
} | |
return false; | |
} else { | |
//_debugTS('onload', true); | |
} | |
_event.add(_win, 'unload', _doNothing); // prevent browser from showing cached state via back button, because flash will be dead | |
if (_s.waitForWindowLoad && !_windowLoaded) { | |
//_wDS('waitOnload'); | |
_event.add(_win, 'load', _initUserOnload); | |
return false; | |
} else { | |
if (_s.waitForWindowLoad && _windowLoaded) { | |
//_wDS('docLoaded'); | |
} | |
_initUserOnload(); | |
} | |
return true; | |
}; | |
_addOnEvent = function(sType, oMethod, oScope) { | |
if (typeof _on_queue[sType] === 'undefined') { | |
_on_queue[sType] = []; | |
} | |
_on_queue[sType].push({ | |
'method': oMethod, | |
'scope': (oScope || null), | |
'fired': false | |
}); | |
}; | |
_processOnEvents = function(oOptions) { | |
if (!oOptions) { // assume onready, if unspecified | |
oOptions = { | |
type: 'onready' | |
}; | |
} | |
if (!_didInit && oOptions && !oOptions.ignoreInit) { | |
// not ready yet. | |
return false; | |
} | |
var status = { | |
success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled) | |
}, | |
srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]), // queue specified by type, or none | |
queue = [], i, j, | |
canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok()); | |
for (i = 0; i < srcQueue.length; i++) { | |
if (srcQueue[i].fired !== true) { | |
queue.push(srcQueue[i]); | |
} | |
} | |
if (queue.length) { | |
//_s._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, [status]); | |
} else { | |
queue[i].method(status); | |
} | |
if (!canRetry) { // flashblock case doesn't count here | |
queue[i].fired = true; | |
} | |
} | |
} | |
return true; | |
}; | |
_initUserOnload = function() { | |
_win.setTimeout(function() { | |
if (_s.useFlashBlock) { | |
_flashBlockHandler(); | |
} | |
_processOnEvents(); | |
// call user-defined "onload", scoped to window | |
if (_s.onload instanceof Function) { | |
//_wDS('onload', 1); | |
_s.onload.apply(_win); | |
//_wDS('onloadOK', 1); | |
} | |
if (_s.waitForWindowLoad) { | |
_event.add(_win, 'load', _initUserOnload); | |
} | |
},1); | |
}; | |
_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 (_hasFlash !== undefined) { | |
// this work has already been done. | |
return _hasFlash; | |
} | |
var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.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') { | |
try { | |
obj = new AX('ShockwaveFlash.ShockwaveFlash'); | |
} catch(e) { | |
// oh well | |
} | |
hasPlugin = (!!obj); | |
} | |
_hasFlash = hasPlugin; | |
return hasPlugin; | |
}; | |
_featureCheck = function() { | |
var needsFlash, item, | |
isSpecial = (_ua.match(/iphone os (1|2|3_0|3_1)/i)?true:false); // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works. | |
if (isSpecial) { | |
_s.hasHTML5 = false; // has Audio(), but is broken; let it load links directly. | |
_html5Only = true; // ignore flash case, however | |
if (_s.oMC) { | |
_s.oMC.style.display = 'none'; | |
} | |
return false; | |
} | |
if (_s.useHTML5Audio) { | |
if (!_s.html5 || !_s.html5.canPlayType) { | |
//_s._wD('SoundManager: No HTML5 Audio() support detected.'); | |
_s.hasHTML5 = false; | |
return true; | |
} else { | |
_s.hasHTML5 = true; | |
} | |
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 (_detectFlash()) { | |
return true; | |
} | |
} | |
} else { | |
// flash required. | |
return true; | |
} | |
for (item in _s.audioFormats) { | |
if (_s.audioFormats.hasOwnProperty(item) && _s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) { | |
// may need flash for this format? | |
needsFlash = true; | |
} | |
} | |
// sanity check.. | |
if (_s.ignoreFlash) { | |
needsFlash = false; | |
} | |
_html5Only = (_s.useHTML5Audio && _s.hasHTML5 && !needsFlash && !_s.requireFlash); | |
return (_detectFlash() && needsFlash); | |
}; | |
_init = function() { | |
var item, tests = []; | |
//_wDS('init'); | |
// called after onload() | |
if (_didInit) { | |
//_wDS('didInit'); | |
return false; | |
} | |
function _cleanup() { | |
_event.remove(_win, 'load', _s.beginDelayedInit); | |
} | |
if (_s.hasHTML5) { | |
for (item in _s.audioFormats) { | |
if (_s.audioFormats.hasOwnProperty(item)) { | |
tests.push(item+': '+_s.html5[item]); | |
} | |
} | |
//_s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); | |
} | |
if (_html5Only) { | |
if (!_didInit) { | |
// we don't need no steenking flash! | |
_cleanup(); | |
_s.enabled = true; | |
_initComplete(); | |
} | |
return true; | |
} | |
// flash path | |
_initMovie(); | |
try { | |
//_wDS('flashJS'); | |
_s.o._externalInterfaceTest(false); // attempt to talk to Flash | |
if (!_s.allowPolling) { | |
//_wDS('noPolling', 1); | |
} else { | |
_setPolling(true, _s.flashPollingInterval ? _s.flashPollingInterval : (_s.useFastPolling ? 10 : 50)); | |
} | |
if (!_s.debugMode) { | |
_s.o._disableDebug(); | |
} | |
_s.enabled = true; | |
//_debugTS('jstoflash', true); | |
} catch(e) { | |
//_s._wD('js/flash exception: ' + e.toString()); | |
//_debugTS('jstoflash', false); | |
_failSafely(true); // don't disable, for reboot() | |
_initComplete(); | |
return false; | |
} | |
_initComplete(); | |
// event cleanup | |
_cleanup(); | |
return true; | |
}; | |
_beginInit = function() { | |
if (_initPending) { | |
return false; | |
} | |
_createMovie(); | |
_initMovie(); | |
_initPending = true; | |
return true; | |
}; | |
_dcLoaded = function() { | |
if (_didDCLoaded) { | |
return false; | |
} | |
_didDCLoaded = true; | |
_initDebug(); | |
if (!_s.useHTML5Audio) { | |
if (!_detectFlash()) { | |
//_s._wD('SoundManager: No Flash detected, trying HTML5'); | |
_s.useHTML5Audio = true; | |
} | |
} | |
_testHTML5(); | |
_s.html5.usingFlash = _featureCheck(); | |
_needsFlash = _s.html5.usingFlash; | |
_didDCLoaded = true; | |
if (_doc.removeEventListener) { | |
_doc.removeEventListener('DOMContentLoaded', _dcLoaded, false); | |
} | |
_go(); | |
return true; | |
}; | |
_startTimer = function(oSound) { | |
if (!oSound._hasTimer) { | |
oSound._hasTimer = true; | |
} | |
}; | |
_stopTimer = function(oSound) { | |
if (oSound._hasTimer) { | |
oSound._hasTimer = false; | |
} | |
}; | |
_die = function() { | |
if (_s.onerror instanceof Function) { | |
_s.onerror(); | |
} | |
_s.disable(); | |
}; | |
_badSafariFix = function() { | |
// special case: "bad" Safari can fall back to flash for MP3/MP4 | |
if (!_isBadSafari || !_detectFlash()) { | |
return false; // doesn't apply | |
} | |
var aF = _s.audioFormats, i, item; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
// special case: "bad" Safari can fall back to flash for MP3/MP4 | |
if (item === 'mp3' || item === 'mp4') { | |
//_s._wD(_sm+': Using flash fallback for '+item+' format'); | |
_s.html5[item] = false; | |
// assign result to related formats, too | |
if (aF[item] && aF[item].related) { | |
for (i<aF[item].related.length; i--;) { | |
_s.html5[aF[item].related[i]] = false; | |
} | |
} | |
} | |
} | |
} | |
}; | |
// pseudo-private methods called by Flash | |
this._setSandboxType = function(sandboxType) { | |
/* | |
var sb = _s.sandbox; | |
sb.type = sandboxType; | |
sb.description = sb.types[(typeof 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); | |
} else if (sb.type === 'localWithNetwork') { | |
sb.noRemote = false; | |
sb.noLocal = true; | |
} else if (sb.type === 'localTrusted') { | |
sb.noRemote = false; | |
sb.noLocal = false; | |
} | |
*/ | |
}; | |
this._externalInterfaceOK = function(flashDate) { | |
// flash callback confirming flash loaded, EI working etc. | |
// flashDate = approx. timing/delay info for JS/flash bridge | |
if (_s.swfLoaded) { | |
return false; | |
} | |
var eiTime = new Date().getTime(); | |
//_s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); | |
//_debugTS('swf', true); | |
//_debugTS('flashtojs', true); | |
_s.swfLoaded = true; | |
_tryInitOnFocus = false; | |
if (_isBadSafari) { | |
_badSafariFix(); | |
} | |
if (_isIE) { | |
// IE needs a timeout OR delay until window.onload - may need TODO: investigating | |
setTimeout(_init, 100); | |
} else { | |
_init(); | |
} | |
}; | |
_dcIE = function() { | |
if (_doc.readyState === 'complete') { | |
_dcLoaded(); | |
_doc.detachEvent('onreadystatechange', _dcIE); | |
} | |
return true; | |
}; | |
// focus and window load, init | |
if (!_s.hasHTML5 || _needsFlash) { | |
// only applies to Flash mode | |
_event.add(_win, 'focus', _handleFocus); | |
_event.add(_win, 'load', _handleFocus); | |
_event.add(_win, 'load', _delayWaitForEI); | |
if (_isSafari && _tryInitOnFocus) { | |
_event.add(_win, 'mousemove', _handleFocus); // massive Safari focus hack | |
} | |
} | |
if (_doc.addEventListener) { | |
_doc.addEventListener('DOMContentLoaded', _dcLoaded, false); | |
} else if (_doc.attachEvent) { | |
_doc.attachEvent('onreadystatechange', _dcIE); | |
} else { | |
// no add/attachevent support - safe to assume no JS -> Flash either | |
//_debugTS('onload', false); | |
_die(); | |
} | |
if (_doc.readyState === 'complete') { | |
setTimeout(_dcLoaded,100); | |
} | |
} // SoundManager() | |
// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading | |
if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { | |
soundManager = new SoundManager(); | |
} | |
// public interfaces | |
window.SoundManager = SoundManager; // constructor | |
window.soundManager = soundManager; // public API, flash callbacks etc | |
}(window)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @license | |
* SoundManager 2: JavaScript Sound for the Web | |
* ---------------------------------------------- | |
* http://schillmania.com/projects/soundmanager2/ | |
* | |
* Copyright (c) 2007, Scott Schiller. All rights reserved. | |
* Code provided under the BSD License: | |
* http://schillmania.com/projects/soundmanager2/license.txt | |
* | |
* V2.97a.20110306 | |
*/ | |
/*jslint white: false, onevar: true, undef: true, nomen: false, eqeqeq: true, plusplus: false, bitwise: true, regexp: false, newcap: true, immed: true */ | |
/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */ | |
(function(window) { | |
var soundManager = null; | |
function SoundManager(smURL, smID) { | |
this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. | |
this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available+configured) | |
this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues | |
this.useConsole = true; // use firebug/safari console.log()-type debug console if available | |
this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug | |
this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() | |
this.nullURL = 'about:blank'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) | |
this.allowPolling = true; // allow flash to poll for status update (required for whileplaying() events, peak, sound spectrum functions to work.) | |
this.useFastPolling = false; // uses lower flash timer interval for higher callback frequency, best combined with useHighPerformance | |
this.useMovieStar = true; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio formats (AAC, M4V, FLV, MOV etc.) | |
this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000' | |
this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag | |
this.flashPollingInterval = null; // msec for polling interval. Defaults to 50 unless useFastPolling = true. | |
this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity) | |
this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top) | |
this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain' | |
this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable. | |
this.useHTML5Audio = false; // Beta feature: Use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible. | |
this.html5Test = /^probably$/i; // HTML5 Audio().canPlayType() test. /^(probably|maybe)$/i if you want to be more liberal/risky. | |
this.useGlobalHTML5Audio = true; // (experimental) if true, re-use single HTML5 audio object across all sounds. Enabled by default on mobile devices/iOS. | |
this.requireFlash = false; // (experimental) if true, prevents "HTML5-only" mode when flash present. Allows flash to handle RTMP/serverURL, but HTML5 for other cases | |
this.audioFormats = { | |
// determines HTML5 support, flash requirements | |
// eg. if MP3 or MP4 required, Flash fallback is used if HTML5 can't play it | |
// shotgun approach to MIME testing due to browser variance | |
'mp3': { | |
'type': ['audio/mpeg; codecs="mp3"','audio/mpeg','audio/mp3','audio/MPA','audio/mpa-robust'], | |
'required': true | |
}, | |
'mp4': { | |
'related': ['aac','m4a'], // additional formats under the MP4 container | |
'type': ['audio/mp4; codecs="mp4a.40.2"','audio/aac','audio/x-m4a','audio/MP4A-LATM','audio/mpeg4-generic'], | |
'required': true | |
}, | |
'ogg': { | |
'type': ['audio/ogg; codecs=vorbis'], | |
'required': false | |
}, | |
'wav': { | |
'type': ['audio/wav; codecs="1"','audio/wav','audio/wave','audio/x-wav'], | |
'required': false | |
} | |
}; | |
this.defaultOptions = { | |
'autoLoad': false, // enable automatic loading (otherwise .load() will be called on demand with .play(), the latter being nicer on bandwidth - if you want to .load yourself, you also can) | |
'stream': true, // allows playing before entire file has loaded (recommended) | |
'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) | |
'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0) | |
'onid3': null, // callback function for "ID3 data is added/available" | |
'onload': null, // callback function for "load finished" | |
'whileloading': null, // callback function for "download progress update" (X of Y bytes received) | |
'onplay': null, // callback for "play" start | |
'onpause': null, // callback for "pause" | |
'onresume': null, // callback for "resume" (pause toggle) | |
'whileplaying': null, // callback during play (position update) | |
'onstop': null, // callback for "user stop" | |
'onfailure': null, // callback function for when playing fails | |
'onfinish': null, // callback function for "sound finished playing" | |
'onbeforefinish': null, // callback for "before sound finished playing (at [time])" | |
'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) | |
'onbeforefinishcomplete': null,// function to call when said sound finishes playing | |
'onjustbeforefinish': null, // callback for [n] msec before end of current sound | |
'onjustbeforefinishtime': 200, // [n] - if not using, set to 0 (or null handler) and event will not fire. | |
'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time | |
'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled | |
'position': null, // offset (milliseconds) to seek to within loaded sound data. | |
'pan': 0, // "pan" settings, left-to-right, -100 to 100 | |
'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3 | |
'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access) | |
'volume': 100 // self-explanatory. 0-100, the latter being the max. | |
}; | |
this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used | |
'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL | |
'usePeakData': false, // enable left/right channel peak (level) data | |
'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. | |
'useEQData': false, // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. | |
'onbufferchange': null, // callback for "isBuffering" property change | |
'ondataerror': null // callback for waveform/eq data access error (flash playing audio in other tabs/domains) | |
}; | |
this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio options, merged into defaultOptions if flash 9+movieStar mode is enabled | |
'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.) | |
'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants | |
'onconnect': null, // rtmp: callback for connection to flash media server | |
'duration': null // rtmp: song duration (msec) | |
}; | |
this.version = null; | |
this.versionNumber = 'V2.97a.20110306'; | |
this.movieURL = null; | |
this.url = (smURL || null); | |
this.altURL = null; | |
this.swfLoaded = false; | |
this.enabled = false; | |
this.o = null; | |
this.movieID = 'sm2-container'; | |
this.id = (smID || 'sm2movie'); | |
this.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', | |
'swfUnblocked': 'swf_unblocked', // or loaded OK | |
'sm2Debug': 'sm2_debug', | |
'highPerf': 'high_performance', | |
'flashDebug': 'flash_debug' | |
}; | |
this.oMC = null; | |
this.sounds = {}; | |
this.soundIDs = []; | |
this.muted = false; | |
this.debugID = 'soundmanager-debug'; | |
this.debugURLParam = /([#?&])debug=1/i; | |
this.specialWmodeCase = false; | |
this.didFlashBlock = false; | |
this.filePattern = null; | |
this.filePatterns = { | |
'flash8': /\.mp3(\?.*)?$/i, | |
'flash9': /\.mp3(\?.*)?$/i | |
}; | |
this.baseMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3 | |
this.netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // mp3, mp4, aac etc. | |
this.netStreamTypes = ['aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2']; // Flash v9.0r115+ "moviestar" formats | |
this.netStreamPattern = new RegExp('\\.(' + this.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); | |
this.mimePattern = this.baseMimeTypes; | |
this.features = { | |
'buffering': false, | |
'peakData': false, | |
'waveformData': false, | |
'eqData': false, | |
'movieStar': false | |
}; | |
this.sandbox = { | |
// <d> | |
'type': null, | |
'types': { | |
'remote': 'remote (domain-based) rules', | |
'localWithFile': 'local with file access (no internet access)', | |
'localWithNetwork': 'local with network (internet access only, no local access)', | |
'localTrusted': 'local, trusted (local+internet access)' | |
}, | |
'description': null, | |
'noRemote': null, | |
'noLocal': null | |
// </d> | |
}; | |
this.hasHTML5 = null; // switch for handling logic | |
this.html5 = { // stores canPlayType() results, etc. treat as read-only. | |
// mp3: boolean | |
// mp4: boolean | |
'usingFlash': null // set if/when flash fallback is needed | |
}; | |
this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?) | |
// --- private SM2 internals --- | |
var SMSound, | |
_s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _fV = this.flashVersion, _doc = document, _doNothing, _init, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _go, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _beginInit, _strings, _initMovie, _dcLoaded, _didDCLoaded, _getDocument, _createMovie, _die, _setPolling, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5Only = false, _html5CanPlay, _html5Ext, _dcIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, | |
_is_pre = _ua.match(/pre\//i), _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _isMobile = (_ua.match(/mobile/i) || _is_pre || _is_iDevice), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), | |
_isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_(3|4|5|6)/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Known Apple "radar" 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 = (typeof _doc.hasFocus === 'undefined' && _isSafari), _okToDisable = !_tryInitOnFocus; | |
this._use_maybe = (_wl.match(/sm2\-useHTML5Maybe\=1/i)); // temporary feature: #sm2-useHTML5Maybe=1 forces loose canPlay() check | |
this._overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null); | |
this.useAltURL = !this._overHTTP; // use altURL if not "online" | |
this._global_a = null; | |
if (_is_iDevice || _is_pre) { | |
// during HTML5 beta period (off by default), may as well force it on Apple + Palm, flash support unlikely | |
_s.useHTML5Audio = true; | |
_s.ignoreFlash = true; | |
if (_s.useGlobalHTML5Audio) { | |
_useGlobalHTML5Audio = true; | |
} | |
} | |
if (_is_pre || this._use_maybe) { | |
// less-strict canPlayType() checking option | |
_s.html5Test = /^(probably|maybe)$/i; | |
} | |
// Temporary feature: allow force of HTML5 via URL: #sm2-usehtml5audio=0 or 1 | |
// <d> | |
(function(){ | |
var a = '#sm2-usehtml5audio=', l = _wl, b = null; | |
if (l.indexOf(a) !== -1) { | |
b = (l.charAt(l.indexOf(a)+a.length) === '1'); | |
if (typeof console !== 'undefined' && typeof console.log !== 'undefined') { | |
console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter'); | |
} | |
_s.useHTML5Audio = b; | |
} | |
}()); | |
// </d> | |
// --- public API methods --- | |
this.ok = function() { | |
return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); | |
}; | |
this.supported = this.ok; // legacy | |
this.getMovie = function(smID) { | |
return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); | |
}; | |
this.createSound = function(oOptions) { | |
var _cs = _sm+'.createSound(): ', | |
thisOptions = null, oSound = null, _tO = null; | |
if (!_didInit || !_s.ok()) { | |
_complain(_cs + _str(!_didInit?'notReady':'notOK')); | |
return false; | |
} | |
if (arguments.length === 2) { | |
// function overloading in JS! :) ..assume simple createSound(id,url) use case | |
oOptions = { | |
'id': arguments[0], | |
'url': arguments[1] | |
}; | |
} | |
thisOptions = _mixin(oOptions); // inherit from defaultOptions | |
_tO = thisOptions; // alias | |
// <d> | |
if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) { | |
_s._wD(_cs + _str('badID', _tO.id), 2); | |
} | |
_s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1); | |
// </d> | |
if (_idCheck(_tO.id, true)) { | |
_s._wD(_cs + _tO.id + ' exists', 1); | |
return _s.sounds[_tO.id]; | |
} | |
function make() { | |
thisOptions = _loopFix(thisOptions); | |
_s.sounds[_tO.id] = new SMSound(_tO); | |
_s.soundIDs.push(_tO.id); | |
return _s.sounds[_tO.id]; | |
} | |
if (_html5OK(_tO)) { | |
oSound = make(); | |
_s._wD('Loading sound '+_tO.id+' via HTML5'); | |
oSound._setup_html5(_tO); | |
} else { | |
if (_fV > 8 && _s.useMovieStar) { | |
if (_tO.isMovieStar === null) { | |
_tO.isMovieStar = ((_tO.serverURL || (_tO.type?_tO.type.match(_s.netStreamPattern):false)||_tO.url.match(_s.netStreamPattern))?true:false); | |
} | |
if (_tO.isMovieStar) { | |
_s._wD(_cs + 'using MovieStar handling'); | |
} | |
if (_tO.isMovieStar) { | |
if (_tO.usePeakData) { | |
_wDS('noPeak'); | |
_tO.usePeakData = false; | |
} | |
if (_tO.loops > 1) { | |
_wDS('noNSLoop'); | |
} | |
} | |
} | |
_tO = _policyFix(_tO, _cs); | |
oSound = make(); | |
if (_fV === 8) { | |
_s.o._createSound(_tO.id, _tO.onjustbeforefinishtime, _tO.loops||1, _tO.usePolicyFile); | |
} else { | |
_s.o._createSound(_tO.id, _tO.url, _tO.onjustbeforefinishtime, _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) { | |
// We are connected immediately | |
oSound.connected = true; | |
if (_tO.onconnect) { | |
_tO.onconnect.apply(oSound); | |
} | |
} | |
} | |
if ((_tO.autoLoad || _tO.autoPlay) && !_tO.serverURL) { | |
oSound.load(_tO); // call load for non-rtmp streams | |
} | |
} | |
if (_tO.autoPlay && !_tO.serverURL) { // rtmp will play in onconnect | |
oSound.play(); | |
} | |
return oSound; | |
}; | |
this.destroySound = function(sID, _bFromSound) { | |
// explicitly destroy a sound before normal page unload, etc. | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
var oS = _s.sounds[sID], i; | |
oS._iO = {}; // Disable all callbacks while the sound is being destroyed | |
oS.stop(); | |
oS.unload(); | |
for (i = 0; i < _s.soundIDs.length; i++) { | |
if (_s.soundIDs[i] === sID) { | |
_s.soundIDs.splice(i, 1); | |
break; | |
} | |
} | |
if (!_bFromSound) { | |
// ignore if being called from SMSound instance | |
oS.destruct(true); | |
} | |
oS = null; | |
delete _s.sounds[sID]; | |
return true; | |
}; | |
this.load = function(sID, oOptions) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].load(oOptions); | |
}; | |
this.unload = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].unload(); | |
}; | |
this.play = function(sID, oOptions) { | |
var fN = _sm+'.play(): '; | |
if (!_didInit || !_s.ok()) { | |
_complain(fN + _str(!_didInit?'notReady':'notOK')); | |
return false; | |
} | |
if (!_idCheck(sID)) { | |
if (!(oOptions instanceof Object)) { | |
oOptions = { | |
url: oOptions | |
}; // overloading use case: play('mySound','/path/to/some.mp3'); | |
} | |
if (oOptions && oOptions.url) { | |
// overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); | |
_s._wD(fN + 'attempting to create "' + sID + '"', 1); | |
oOptions.id = sID; | |
return _s.createSound(oOptions).play(); | |
} else { | |
return false; | |
} | |
} | |
return _s.sounds[sID].play(oOptions); | |
}; | |
this.start = this.play; // just for convenience | |
this.setPosition = function(sID, nMsecOffset) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setPosition(nMsecOffset); | |
}; | |
this.stop = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
_s._wD(_sm+'.stop(' + sID + ')', 1); | |
return _s.sounds[sID].stop(); | |
}; | |
this.stopAll = function() { | |
_s._wD(_sm+'.stopAll()', 1); | |
for (var oSound in _s.sounds) { | |
if (_s.sounds[oSound] instanceof SMSound) { | |
_s.sounds[oSound].stop(); // apply only to sound objects | |
} | |
} | |
}; | |
this.pause = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].pause(); | |
}; | |
this.pauseAll = function() { | |
for (var i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].pause(); | |
} | |
}; | |
this.resume = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].resume(); | |
}; | |
this.resumeAll = function() { | |
for (var i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].resume(); | |
} | |
}; | |
this.togglePause = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].togglePause(); | |
}; | |
this.setPan = function(sID, nPan) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setPan(nPan); | |
}; | |
this.setVolume = function(sID, nVol) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].setVolume(nVol); | |
}; | |
this.mute = function(sID) { | |
var fN = _sm+'.mute(): ', | |
i = 0; | |
if (typeof sID !== 'string') { | |
sID = null; | |
} | |
if (!sID) { | |
_s._wD(fN + 'Muting all sounds'); | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].mute(); | |
} | |
_s.muted = true; | |
} else { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
_s._wD(fN + 'Muting "' + sID + '"'); | |
return _s.sounds[sID].mute(); | |
} | |
return true; | |
}; | |
this.muteAll = function() { | |
_s.mute(); | |
}; | |
this.unmute = function(sID) { | |
var fN = _sm+'.unmute(): ', i; | |
if (typeof sID !== 'string') { | |
sID = null; | |
} | |
if (!sID) { | |
_s._wD(fN + 'Unmuting all sounds'); | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].unmute(); | |
} | |
_s.muted = false; | |
} else { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
_s._wD(fN + 'Unmuting "' + sID + '"'); | |
return _s.sounds[sID].unmute(); | |
} | |
return true; | |
}; | |
this.unmuteAll = function() { | |
_s.unmute(); | |
}; | |
this.toggleMute = function(sID) { | |
if (!_idCheck(sID)) { | |
return false; | |
} | |
return _s.sounds[sID].toggleMute(); | |
}; | |
this.getMemoryUse = function() { | |
if (_fV === 8) { | |
return 0; | |
} | |
if (_s.o) { | |
return parseInt(_s.o._getMemoryUse(), 10); | |
} | |
}; | |
this.disable = function(bNoDisable) { | |
// destroy all functions | |
if (typeof bNoDisable === 'undefined') { | |
bNoDisable = false; | |
} | |
if (_disabled) { | |
return false; | |
} | |
_disabled = true; | |
_wDS('shutdown', 1); | |
for (var i = _s.soundIDs.length; i--;) { | |
_disableObject(_s.sounds[_s.soundIDs[i]]); | |
} | |
_initComplete(bNoDisable); // fire "complete", despite fail | |
_event.remove(_win, 'load', _initUserOnload); | |
return true; | |
}; | |
this.canPlayMIME = function(sMIME) { | |
var result; | |
if (_s.hasHTML5) { | |
result = _html5CanPlay({type:sMIME}); | |
} | |
if (!_needsFlash || result) { | |
// no flash, or OK | |
return result; | |
} else { | |
return (sMIME?(sMIME.match(_s.mimePattern)?true:false):null); | |
} | |
}; | |
this.canPlayURL = function(sURL) { | |
var result; | |
if (_s.hasHTML5) { | |
result = _html5CanPlay(sURL); | |
} | |
if (!_needsFlash || result) { | |
// no flash, or OK | |
return result; | |
} else { | |
return (sURL?(sURL.match(_s.filePattern)?true:false):null); | |
} | |
}; | |
this.canPlayLink = function(oLink) { | |
if (typeof oLink.type !== 'undefined' && oLink.type) { | |
if (_s.canPlayMIME(oLink.type)) { | |
return true; | |
} | |
} | |
return _s.canPlayURL(oLink.href); | |
}; | |
this.getSoundById = function(sID, suppressDebug) { | |
if (!sID) { | |
throw new Error(_sm+'.getSoundById(): sID is null/undefined'); | |
} | |
var result = _s.sounds[sID]; | |
if (!result && !suppressDebug) { | |
_s._wD('"' + sID + '" is an invalid sound ID.', 2); | |
} | |
return result; | |
}; | |
this.onready = function(oMethod, oScope) { | |
var sType = 'onready'; | |
if (oMethod && oMethod instanceof Function) { | |
if (_didInit) { | |
_wDS('queue', sType); | |
} | |
if (!oScope) { | |
oScope = _win; | |
} | |
_addOnEvent(sType, oMethod, oScope); | |
_processOnEvents(); | |
return true; | |
} else { | |
throw _str('needFunction', sType); | |
} | |
}; | |
this.ontimeout = function(oMethod, oScope) { | |
var sType = 'ontimeout'; | |
if (oMethod && oMethod instanceof Function) { | |
if (_didInit) { | |
_wDS('queue'); | |
} | |
if (!oScope) { | |
oScope = _win; | |
} | |
_addOnEvent(sType, oMethod, oScope); | |
_processOnEvents({type:sType}); | |
return true; | |
} else { | |
throw _str('needFunction', sType); | |
} | |
}; | |
this.getMoviePercent = function() { | |
return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); | |
}; | |
this._writeDebug = function(sText, sType, bTimestamp) { | |
// pseudo-private console.log()-style output | |
// <d> | |
var sDID = 'soundmanager-debug', o, oItem, sMethod; | |
if (!_s.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); | |
} else { | |
console.log(sText); | |
} | |
if (_s.useConsoleOnly) { | |
return true; | |
} | |
} | |
try { | |
o = _id(sDID); | |
if (!o) { | |
return false; | |
} | |
oItem = _doc.createElement('div'); | |
if (++_wdCount % 2 === 0) { | |
oItem.className = 'sm2-alt'; | |
} | |
if (typeof sType === 'undefined') { | |
sType = 0; | |
} else { | |
sType = parseInt(sType, 10); | |
} | |
oItem.appendChild(_doc.createTextNode(sText)); | |
if (sType) { | |
if (sType >= 2) { | |
oItem.style.fontWeight = 'bold'; | |
} | |
if (sType === 3) { | |
oItem.style.color = '#ff3333'; | |
} | |
} | |
// o.appendChild(oItem); // top-to-bottom | |
o.insertBefore(oItem, o.firstChild); // bottom-to-top | |
} catch(e) { | |
// oh well | |
} | |
o = null; | |
// </d> | |
return true; | |
}; | |
this._wD = this._writeDebug; // alias | |
this._debug = function() { | |
// <d> | |
_wDS('currentObj', 1); | |
for (var i = 0, j = _s.soundIDs.length; i < j; i++) { | |
_s.sounds[_s.soundIDs[i]]._debug(); | |
} | |
// </d> | |
}; | |
this.reboot = function() { | |
// attempt to reset and init SM2 | |
_s._wD(_sm+'.reboot()'); | |
if (_s.soundIDs.length) { | |
_s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...'); | |
} | |
var i, j; | |
for (i = _s.soundIDs.length; i--;) { | |
_s.sounds[_s.soundIDs[i]].destruct(); | |
} | |
// trash ze flash | |
try { | |
if (_isIE) { | |
_oRemovedHTML = _s.o.innerHTML; | |
} | |
_oRemoved = _s.o.parentNode.removeChild(_s.o); | |
_s._wD('Flash movie removed.'); | |
} catch(e) { | |
// uh-oh. | |
_wDS('badRemove', 2); | |
} | |
// actually, force recreate of movie. | |
_oRemovedHTML = _oRemoved = null; | |
_s.enabled = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false; | |
_s.soundIDs = _s.sounds = []; | |
_s.o = null; | |
for (i in _on_queue) { | |
if (_on_queue.hasOwnProperty(i)) { | |
for (j = _on_queue[i].length; j--;) { | |
_on_queue[i][j].fired = false; | |
} | |
} | |
} | |
_s._wD(_sm + ': Rebooting...'); | |
_win.setTimeout(function() { | |
_s.beginDelayedInit(); | |
}, 20); | |
}; | |
this.destruct = function() { | |
_s._wD(_sm+'.destruct()'); | |
_s.disable(true); | |
}; | |
this.beginDelayedInit = function() { | |
// _s._wD(_sm+'.beginDelayedInit()'); | |
_windowLoaded = true; | |
_dcLoaded(); | |
setTimeout(_beginInit, 20); | |
_delayWaitForEI(); | |
}; | |
// Wrap html5 event handlers so we don't call them on destroyed sounds | |
function _html5_event(oFn) { | |
return function(e) { | |
if (!this._t || !this._t._a) { | |
if (this._t && this._t.sID) { | |
_s._wD(_h5+'ignoring '+e.type+': '+this._t.sID); | |
} else { | |
_s._wD(_h5+'ignoring '+e.type); | |
} | |
return null; | |
} else { | |
return oFn.call(this, e); | |
} | |
}; | |
} | |
this._html5_events = { | |
// HTML5 event-name-to-handler map | |
abort: _html5_event(function(e) { | |
_s._wD(_h5+'abort: '+this._t.sID); | |
}), | |
// enough has loaded to play | |
canplay: _html5_event(function(e) { | |
_s._wD(_h5+'canplay: '+this._t.sID+', '+this._t.url); | |
this._t._onbufferchange(0); | |
var position1K = (!isNaN(this._t.position)?this._t.position/1000:null); | |
// set the position if position was set before the sound loaded | |
this._t._html5_canplay = true; | |
if (this._t.position && this.currentTime !== position1K) { | |
_s._wD(_h5+'canplay: setting position to '+position1K+''); | |
try { | |
this.currentTime = position1K; | |
} catch(ee) { | |
_s._wD(_h5+'setting position failed: '+ee.message, 2); | |
} | |
} | |
}), | |
load: _html5_event(function(e) { | |
if (!this._t.loaded) { | |
this._t._onbufferchange(0); | |
// should be 1, and the same | |
this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration()); | |
this._t._onload(true); | |
} | |
}), | |
emptied: _html5_event(function(e) { | |
_s._wD(_h5+'emptied: '+this._t.sID); | |
}), | |
ended: _html5_event(function(e) { | |
_s._wD(_h5+'ended: '+this._t.sID); | |
this._t._onfinish(); | |
}), | |
error: _html5_event(function(e) { | |
_s._wD(_h5+'error: '+this.error.code); | |
// call load with error state? | |
this._t._onload(false); | |
}), | |
loadeddata: _html5_event(function(e) { | |
_s._wD(_h5+'loadeddata: '+this._t.sID); | |
}), | |
loadedmetadata: _html5_event(function(e) { | |
_s._wD(_h5+'loadedmetadata: '+this._t.sID); | |
}), | |
loadstart: _html5_event(function(e) { | |
_s._wD(_h5+'loadstart: '+this._t.sID); | |
// assume buffering at first | |
this._t._onbufferchange(1); | |
}), | |
play: _html5_event(function(e) { | |
_s._wD(_h5+'play: '+this._t.sID+', '+this._t.url); | |
// once play starts, no buffering | |
this._t._onbufferchange(0); | |
}), | |
// TODO: verify if this is actually implemented anywhere yet. | |
playing: _html5_event(function(e) { | |
_s._wD(_h5+'playing: '+this._t.sID+', '+this._t.url); | |
// once play starts, no buffering | |
this._t._onbufferchange(0); | |
}), | |
progress: _html5_event(function(e) { | |
if (this._t.loaded) { | |
return false; | |
} | |
var i, j, str, loadSum = 0, buffered = 0, | |
isProgress = (e.type === 'progress'), | |
ranges = e.target.buffered, | |
loaded = (e.loaded||0), // firefox 3.6 implements e.loaded/total (bytes) | |
total = (e.total||1); | |
if (ranges && ranges.length) { | |
// if loaded is 0, try TimeRanges implementation as % of load | |
// https://developer.mozilla.org/en/DOM/TimeRanges | |
for (i=ranges.length; i--;) { | |
buffered = (ranges.end(i) - ranges.start(i)); | |
} | |
// linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges | |
loaded = buffered/e.target.duration; | |
// <d> | |
if (isProgress && ranges.length > 1) { | |
str = []; | |
j = ranges.length; | |
for (i=0; i<j; i++) { | |
str.push(e.target.buffered.start(i) +'-'+ e.target.buffered.end(i)); | |
} | |
_s._wD(_h5+'progress: timeRanges: '+str.join(', ')); | |
} | |
// </d> | |
if (isProgress && !isNaN(loaded)) { | |
_s._wD(_h5+'progress: '+this._t.sID+': ' + Math.floor(loaded*100)+'% loaded'); | |
} | |
} | |
if (!isNaN(loaded)) { | |
this._t._onbufferchange(0); // if progress, likely not buffering | |
this._t._whileloading(loaded, total, this._t._get_html5_duration()); | |
if (loaded && total && loaded === total) { | |
// in case "onload" doesn't fire (eg. gecko 1.9.2) | |
_s._html5_events.load.call(this, e); | |
} | |
} | |
}), | |
ratechange: _html5_event(function(e) { | |
_s._wD(_h5+'ratechange: '+this._t.sID); | |
}), | |
suspend: _html5_event(function(e) { | |
// download paused/stopped, may have finished (eg. onload) | |
_s._wD(_h5+'suspend: '+this._t.sID); | |
_s._html5_events.progress.call(this, e); | |
}), | |
stalled: _html5_event(function(e) { | |
_s._wD(_h5+'stalled: '+this._t.sID); | |
}), | |
timeupdate: _html5_event(function(e) { | |
this._t._onTimer(); | |
}), | |
waiting: _html5_event(function(e) { // see also: seeking | |
_s._wD(_h5+'waiting: '+this._t.sID); | |
// playback faster than download rate, etc. | |
this._t._onbufferchange(1); | |
}) | |
}; | |
// --- SMSound (sound object) instance --- | |
SMSound = function(oOptions) { | |
var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer; | |
this.sID = oOptions.id; | |
this.url = oOptions.url; | |
this.options = _mixin(oOptions); | |
this.instanceOptions = this.options; // per-play-instance-specific options | |
this._iO = this.instanceOptions; // short alias | |
// assign property defaults | |
this.pan = this.options.pan; | |
this.volume = this.options.volume; | |
this._lastURL = null; | |
this.isHTML5 = false; | |
this._a = null; | |
// --- public methods --- | |
this.id3 = {}; | |
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 (_t.options[stuff] instanceof Function) { | |
// handle functions specially | |
sF = _t.options[stuff].toString(); | |
sF = sF.replace(/\s\s+/g, ' '); // normalize spaces | |
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}'); | |
} | |
// </d> | |
}; | |
this._debug(); | |
this.load = function(oOptions) { | |
var oS = null; | |
if (typeof oOptions !== 'undefined') { | |
_t._iO = _mixin(oOptions); | |
_t.instanceOptions = _t._iO; | |
} else { | |
oOptions = _t.options; | |
_t._iO = oOptions; | |
_t.instanceOptions = _t._iO; | |
if (_t._lastURL && _t._lastURL !== _t.url) { | |
_wDS('manURL'); | |
_t._iO.url = _t.url; | |
_t.url = null; | |
} | |
} | |
if (!_t._iO.url) { | |
_t._iO.url = _t.url; | |
} | |
_s._wD('SMSound.load(): ' + _t._iO.url, 1); | |
if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) { | |
_wDS('onURL', 1); | |
return _t; | |
} | |
_t._lastURL = _t.url; | |
_t.loaded = false; | |
_t.readyState = 1; | |
_t.playState = 0; | |
if (_html5OK(_t._iO)) { | |
oS = _t._setup_html5(_t._iO); | |
if (!oS._called_load) { | |
_s._wD(_h5+'load: '+_t.sID); | |
oS.load(); | |
oS._called_load = true; | |
if (_t._iO.autoPlay) { | |
_t.play(); | |
} | |
} else { | |
_s._wD('HTML5 ignoring request to load again: '+_t.sID); | |
} | |
} else { | |
try { | |
_t.isHTML5 = false; | |
_t._iO = _policyFix(_loopFix(_t._iO)); | |
if (_fV === 8) { | |
_s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile); | |
} else { | |
_s.o._load(_t.sID, _t._iO.url, _t._iO.stream?true:false, _t._iO.autoPlay?true:false, _t._iO.loops||1, _t._iO.autoLoad?true:false, _t._iO.usePolicyFile); | |
} | |
} catch(e) { | |
_wDS('smError', 2); | |
_debugTS('onload', false); | |
_die(); | |
} | |
} | |
return _t; | |
}; | |
this.unload = function() { | |
// Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 | |
// Flash 9/AS3: Close stream, preventing further load | |
if (_t.readyState !== 0) { | |
_s._wD('SMSound.unload(): "' + _t.sID + '"'); | |
if (!_t.isHTML5) { | |
if (_fV === 8) { | |
_s.o._unload(_t.sID, _s.nullURL); | |
} else { | |
_s.o._unload(_t.sID); | |
} | |
} else { | |
_stop_html5_timer(); | |
if (_t._a) { | |
// abort()-style method here, stop loading? (doesn't exist?) | |
_t._a.pause(); | |
// if (!_useGlobalHTML5Audio || (_useGlobalHTML5Audio && _t.playState)) { // if global audio, only unload if actively playing | |
_t._a.src = ''; // https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media | |
// } | |
} | |
} | |
// reset load/status flags | |
_resetProperties(); | |
} | |
return _t; | |
}; | |
this.destruct = function(_bFromSM) { | |
_s._wD('SMSound.destruct(): "' + _t.sID + '"'); | |
if (!_t.isHTML5) { | |
// kill sound within Flash | |
// Disable the onfailure handler | |
_t._iO.onfailure = null; | |
_s.o._destroySound(_t.sID); | |
} else { | |
_stop_html5_timer(); | |
if (_t._a) { | |
// abort()-style method here, stop loading? (doesn't exist?) | |
_t._a.pause(); | |
_t._a.src = ''; // https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media | |
if (!_useGlobalHTML5Audio) { | |
_t._remove_html5_events(); | |
} | |
} | |
} | |
if (!_bFromSM) { | |
_s.destroySound(_t.sID, true); // ensure deletion from controller | |
} | |
}; | |
this.play = function(oOptions, _updatePlayState) { | |
var fN = 'SMSound.play(): ', allowMulti; | |
_updatePlayState = _updatePlayState === undefined ? true : _updatePlayState; // default true | |
if (!oOptions) { | |
oOptions = {}; | |
} | |
_t._iO = _mixin(oOptions, _t._iO); | |
_t._iO = _mixin(_t._iO, _t.options); | |
_t.instanceOptions = _t._iO; | |
if (_t._iO.serverURL) { | |
if (!_t.connected) { | |
if (!_t.getAutoPlay()) { | |
_s._wD(fN+' Netstream not connected yet - setting autoPlay'); | |
_t.setAutoPlay(true); | |
} | |
return _t; // play will be called in _onconnect() | |
} | |
} | |
if (_html5OK(_t._iO)) { | |
_t._setup_html5(_t._iO); | |
_start_html5_timer(); | |
} | |
if (_t.playState === 1 && !_t.paused) { | |
allowMulti = _t._iO.multiShot; | |
if (!allowMulti) { | |
_s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1); | |
return _t; | |
} else { | |
_s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1); | |
if (_t.isHTML5) { | |
// TODO: BUG? | |
_t.setPosition(_t._iO.position); | |
} | |
} | |
} | |
if (!_t.loaded) { | |
if (_t.readyState === 0) { | |
_s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1); | |
// try to get this sound playing ASAP | |
if (!_t.isHTML5) { | |
_t._iO.autoPlay = true; // assign directly because setAutoPlay() increments the instanceCount | |
_t.load(_t._iO); | |
} else { | |
_t.load(_t._iO); | |
// _t.readyState = 1; // redundant | |
} | |
} else if (_t.readyState === 2) { | |
_s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2); | |
return _t; | |
} else { | |
_s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1); | |
} | |
} else { | |
_s._wD(fN + '"' + _t.sID + '"'); | |
} | |
// Streams will pause when their buffer is full if they are being loaded. | |
// In this case paused is true, but the song hasn't started playing yet. If | |
// we just call resume() the onplay() callback will never be called. So | |
// only call resume() if the position is > 0. | |
// Another reason is because options like volume won't have been applied yet. | |
if (_t.paused && _t.position && _t.position > 0) { // https://gist.github.com/37b17df75cc4d7a90bf6 | |
_s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1); | |
_t.resume(); | |
} else { | |
_s._wD(fN+'"'+ _t.sID+'" is starting to play'); | |
_t.playState = 1; | |
_t.paused = false; | |
if (!_t.instanceCount || _t._iO.multiShotEvents || (_fV > 8 && !_t.isHTML5 && !_t.getAutoPlay())) { | |
_t.instanceCount++; | |
} | |
_t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); | |
if (!_t.isHTML5) { | |
_t._iO = _policyFix(_loopFix(_t._iO)); | |
} | |
if (_t._iO.onplay && _updatePlayState) { | |
_t._iO.onplay.apply(_t); | |
_t._onplay_called = true; | |
} | |
_t.setVolume(_t._iO.volume, true); | |
_t.setPan(_t._iO.pan, true); | |
if (!_t.isHTML5) { | |
_s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t.position:_t.position / 1000)); | |
} else { | |
_start_html5_timer(); | |
_t._setup_html5().play(); | |
} | |
} | |
return _t; | |
}; | |
this.start = this.play; // just for convenience | |
this.stop = function(bAll) { | |
if (_t.playState === 1) { | |
_t._onbufferchange(0); | |
_t.resetOnPosition(0); | |
if (!_t.isHTML5) { | |
_t.playState = 0; | |
} | |
_t.paused = false; | |
if (_t._iO.onstop) { | |
_t._iO.onstop.apply(_t); | |
} | |
if (!_t.isHTML5) { | |
_s.o._stop(_t.sID, bAll); | |
// hack for netStream: just unload | |
if (_t._iO.serverURL) { | |
_t.unload(); | |
} | |
} else { | |
if (_t._a) { | |
_t.setPosition(0); // act like Flash, though | |
_t._a.pause(); // html5 has no stop() | |
_t.playState = 0; | |
_t._onTimer(); // and update UI | |
_stop_html5_timer(); | |
_t.unload(); | |
} | |
} | |
_t.instanceCount = 0; | |
_t._iO = {}; | |
} | |
return _t; | |
}; | |
this.setAutoPlay = function(autoPlay) { | |
_s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off')); | |
_t._iO.autoPlay = autoPlay; | |
if (_t.isHTML5) { | |
if (_t._a && autoPlay) { | |
_t.play(); // HTML5 onload isn't reliable | |
} | |
} else { | |
_s.o._setAutoPlay(_t.sID, 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.sID+' incremented instance count to '+_t.instanceCount); | |
} | |
} | |
}; | |
this.getAutoPlay = function() { | |
return _t._iO.autoPlay; | |
}; | |
this.setPosition = function(nMsecOffset, bNoDebug) { | |
if (nMsecOffset === undefined) { | |
nMsecOffset = 0; | |
} | |
// Use the duration from the instance options, if we don't have a track duration yet. | |
var original_pos, position, position1K, offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0))); // position >= 0 and <= current available (loaded) duration | |
original_pos = _t.position; | |
_t.position = offset; | |
position1K = _t.position/1000; | |
_t.resetOnPosition(_t.position); | |
_t._iO.position = offset; | |
if (!_t.isHTML5) { | |
position = _fV === 9 ? _t.position : position1K; | |
if (_t.readyState && _t.readyState !== 2) { | |
_s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState)); // if paused or not playing, will not resume (by playing) | |
} | |
} else if (_t._a) { | |
// Set the position in the canplay handler if the sound is not ready yet | |
if (_t._html5_canplay) { | |
if (_t._a.currentTime !== position1K) { | |
// Only set the position if we need to. | |
// 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'); | |
try { | |
_t._a.currentTime = position1K; | |
} catch(e) { | |
_s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2); | |
} | |
} | |
} else { | |
_s._wD('setPosition('+position1K+'): delaying, sound not ready'); | |
} | |
} | |
if (_t.isHTML5) { | |
if (_t.paused) { // if paused, refresh UI right away | |
_t._onTimer(true); // force update | |
} | |
} | |
return _t; | |
}; | |
this.pause = function(bCallFlash) { | |
if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) { | |
return _t; | |
} | |
_s._wD('SMSound.pause()'); | |
_t.paused = true; | |
if (!_t.isHTML5) { | |
if (bCallFlash || bCallFlash === undefined) { | |
_s.o._pause(_t.sID); | |
} | |
} else { | |
_t._setup_html5().pause(); | |
_stop_html5_timer(); | |
} | |
if (_t._iO.onpause) { | |
_t._iO.onpause.apply(_t); | |
} | |
return _t; | |
}; | |
// When auto-loaded streams pause on buffer full they have a playState of 0. | |
// We need to make sure that the playState is set to 1 when these streams "resume". | |
// | |
// When a paused stream is resumed, we need to trigger the onplay() callback if it | |
// hasn't been called already. In this case since the sound is being played for the | |
// first time, I think it's more appropriate to call onplay() rather than onresume(). | |
this.resume = function() { | |
if (!_t.paused) { | |
return _t; | |
} | |
_s._wD('SMSound.resume()'); | |
_t.paused = false; | |
_t.playState = 1; | |
if (!_t.isHTML5) { | |
if (_t._iO.isMovieStar) { | |
// 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.o._pause(_t.sID); // flash method is toggle-based (pause/resume) | |
} else { | |
_t._setup_html5().play(); | |
_start_html5_timer(); | |
} | |
if (!_t._onplay_called && _t._iO.onplay) { | |
_t._iO.onplay.apply(_t); | |
_t._onplay_called = true; | |
} else if (_t._iO.onresume) { | |
_t._iO.onresume.apply(_t); | |
} | |
return _t; | |
}; | |
this.togglePause = function() { | |
_s._wD('SMSound.togglePause()'); | |
if (_t.playState === 0) { | |
_t.play({ | |
position: (_fV === 9 && !_t.isHTML5 ? _t.position:_t.position / 1000) | |
}); | |
return _t; | |
} | |
if (_t.paused) { | |
_t.resume(); | |
} else { | |
_t.pause(); | |
} | |
return _t; | |
}; | |
this.setPan = function(nPan, bInstanceOnly) { | |
if (typeof nPan === 'undefined') { | |
nPan = 0; | |
} | |
if (typeof bInstanceOnly === 'undefined') { | |
bInstanceOnly = false; | |
} | |
if (!_t.isHTML5) { | |
_s.o._setPan(_t.sID, nPan); | |
} // else { no HTML5 pan? } | |
_t._iO.pan = nPan; | |
if (!bInstanceOnly) { | |
_t.pan = nPan; | |
} | |
return _t; | |
}; | |
this.setVolume = function(nVol, bInstanceOnly) { | |
if (typeof nVol === 'undefined') { | |
nVol = 100; | |
} | |
if (typeof bInstanceOnly === 'undefined') { | |
bInstanceOnly = false; | |
} | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol); | |
} else if (_t._a) { | |
_t._a.volume = nVol/100; | |
} | |
_t._iO.volume = nVol; | |
if (!bInstanceOnly) { | |
_t.volume = nVol; | |
} | |
return _t; | |
}; | |
this.mute = function() { | |
_t.muted = true; | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, 0); | |
} else if (_t._a) { | |
_t._a.muted = true; | |
} | |
return _t; | |
}; | |
this.unmute = function() { | |
_t.muted = false; | |
var hasIO = typeof _t._iO.volume !== 'undefined'; | |
if (!_t.isHTML5) { | |
_s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume); | |
} else if (_t._a) { | |
_t._a.muted = false; | |
} | |
return _t; | |
}; | |
this.toggleMute = function() { | |
return (_t.muted?_t.unmute():_t.mute()); | |
}; | |
this.onposition = function(nPosition, oMethod, oScope) { | |
// TODO: allow for ranges, too? eg. (nPosition instanceof Array) | |
_t._onPositionItems.push({ | |
position: nPosition, | |
method: oMethod, | |
scope: (typeof oScope !== 'undefined'?oScope:_t), | |
fired: false | |
}); | |
return _t; | |
}; | |
this.processOnPosition = function() { | |
var i, item, j = _t._onPositionItems.length; | |
if (!j || !_t.playState || _t._onPositionFired >= j) { | |
return false; | |
} | |
for (i=j; i--;) { | |
item = _t._onPositionItems[i]; | |
if (!item.fired && _t.position >= item.position) { | |
item.method.apply(item.scope,[item.position]); | |
item.fired = true; | |
_s._onPositionFired++; | |
} | |
} | |
return true; | |
}; | |
this.resetOnPosition = function(nPosition) { | |
// reset "fired" for items interested in this position | |
var i, item, j = _t._onPositionItems.length; | |
if (!j) { | |
return false; | |
} | |
for (i=j; i--;) { | |
item = _t._onPositionItems[i]; | |
if (item.fired && nPosition <= item.position) { | |
item.fired = false; | |
_s._onPositionFired--; | |
} | |
} | |
return true; | |
}; | |
// pseudo-private soundManager reference | |
this._onTimer = function(bForce) { | |
// HTML5-only _whileplaying() etc. | |
var time, x = {}; | |
if (_t._hasTimer || bForce) { | |
if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) { // TODO: May not need to track readyState (1 = loading) | |
_t.duration = _t._get_html5_duration(); | |
_t.durationEstimate = _t.duration; | |
time = _t._a.currentTime?_t._a.currentTime*1000:0; | |
_t._whileplaying(time,x,x,x,x); | |
return true; | |
} else { | |
_s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK')); | |
return false; | |
} | |
} | |
}; | |
// --- private internals --- | |
this._get_html5_duration = function() { | |
var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)); | |
return (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null)); | |
}; | |
_start_html5_timer = function() { | |
if (_t.isHTML5) { | |
_startTimer(_t); | |
} | |
}; | |
_stop_html5_timer = function() { | |
if (_t.isHTML5) { | |
_stopTimer(_t); | |
} | |
}; | |
_resetProperties = function(bLoaded) { | |
_t._onPositionItems = []; | |
_t._onPositionFired = 0; | |
_t._hasTimer = null; | |
_t._onplay_called = false; | |
_t._a = null; | |
_t._html5_canplay = false; | |
_t.bytesLoaded = null; | |
_t.bytesTotal = null; | |
_t.position = null; | |
_t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null); | |
_t.durationEstimate = null; | |
_t.failures = 0; | |
_t.loaded = false; | |
_t.playState = 0; | |
_t.paused = false; | |
_t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success | |
_t.muted = false; | |
_t.didBeforeFinish = false; | |
_t.didJustBeforeFinish = false; | |
_t.isBuffering = false; | |
_t.instanceOptions = {}; | |
_t.instanceCount = 0; | |
_t.peakData = { | |
left: 0, | |
right: 0 | |
}; | |
_t.waveformData = { | |
left: [], | |
right: [] | |
}; | |
_t.eqData = []; // legacy: 1D array | |
_t.eqData.left = []; | |
_t.eqData.right = []; | |
}; | |
_resetProperties(); | |
// pseudo-private methods used by soundManager | |
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); | |
if (_a) { | |
if (_a._t && _oldIO.url === _iO.url) { | |
return _a; // same url, ignore request | |
} | |
_s._wD('setting new URL on existing object: '+_dURL+', old URL: '+d(_oldIO.url)); | |
/* | |
* "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 (_useGlobalHTML5Audio && _a._t.playState && _a._t && _iO.url !== _oldIO.url) { | |
_a._t.stop(); | |
} | |
_resetProperties(); // new URL, so reset load/playstate and so on | |
_a.src = _iO.url; | |
} else { | |
_s._wD('creating HTML5 Audio() element with URL: '+_dURL); | |
_a = new Audio(_iO.url); | |
if (_useGlobalHTML5Audio) { | |
_s._global_a = _a; | |
} | |
} | |
_a._called_load = false; | |
_t.isHTML5 = true; | |
_t._a = _a; // store a ref on the track | |
_a._t = _t; // store a ref on the audio | |
_t._add_html5_events(); | |
_a.loop = (_iO.loops>1?'loop':''); | |
if (_iO.autoLoad || _iO.autoPlay) { | |
_a.autobuffer = 'auto'; // early HTML5 implementation (non-standard) | |
_a.preload = 'auto'; // standard | |
_t.load(); | |
} else { | |
_a.autobuffer = false; // early HTML5 implementation (non-standard) | |
_a.preload = 'none'; // standard | |
} | |
_a.loop = (_iO.loops>1?'loop':''); // boolean instead of "loop", for webkit? - spec says string. http://www.w3.org/TR/html-markup/audio.html#audio.attrs.loop | |
return _a; | |
}; | |
// related private methods | |
this._add_html5_events = function() { | |
if (_t._a._added_events) { | |
return false; | |
} | |
var f; | |
function add(oEvt, oFn, bCapture) { | |
return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null; | |
} | |
_s._wD(_h5+'adding event listeners: '+_t.sID); | |
_t._a._added_events = true; | |
for (f in _s._html5_events) { | |
if (_s._html5_events.hasOwnProperty(f)) { | |
add(f, _s._html5_events[f]); | |
} | |
} | |
return true; | |
}; | |
// Keep this externally accessible | |
this._remove_html5_events = function() { | |
// Remove event listeners | |
function remove(oEvt, oFn, bCapture) { | |
return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null); | |
} | |
_s._wD(_h5+'removing event listeners: '+_t.sID); | |
_t._a._added_events = false; | |
for (var f in _s._html5_events) { | |
if (_s._html5_events.hasOwnProperty(f)) { | |
remove(f, _s._html5_events[f]); | |
} | |
} | |
}; | |
// --- "private" methods called by Flash --- | |
this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) { | |
_t.bytesLoaded = nBytesLoaded; | |
_t.bytesTotal = nBytesTotal; | |
_t.duration = Math.floor(nDuration); | |
_t.bufferLength = nBufferLength; | |
if (!_t._iO.isMovieStar) { | |
if (_t._iO.duration) { | |
// use options, if specified and larger | |
_t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration; | |
} else { | |
_t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10); | |
} | |
if (_t.durationEstimate === undefined) { | |
_t.durationEstimate = _t.duration; | |
} | |
if (_t.readyState !== 3 && _t._iO.whileloading) { | |
_t._iO.whileloading.apply(_t); | |
} | |
} else { | |
_t.durationEstimate = _t.duration; | |
if (_t.readyState !== 3 && _t._iO.whileloading) { | |
_t._iO.whileloading.apply(_t); | |
} | |
} | |
}; | |
this._onid3 = function(oID3PropNames, oID3Data) { | |
// oID3PropNames: string array (names) | |
// ID3Data: string array (data) | |
_s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.'); | |
var oData = [], i, j; | |
for (i = 0, j = oID3PropNames.length; i < j; i++) { | |
oData[oID3PropNames[i]] = oID3Data[i]; | |
} | |
_t.id3 = _mixin(_t.id3, oData); | |
if (_t._iO.onid3) { | |
_t._iO.onid3.apply(_t); | |
} | |
}; | |
this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) { | |
if (isNaN(nPosition) || nPosition === null) { | |
return false; // flash safety net | |
} | |
if (_t.playState === 0 && nPosition > 0) { | |
// invalid position edge case for end/stop | |
nPosition = 0; | |
} | |
_t.position = nPosition; | |
_t.processOnPosition(); | |
if (_fV > 8 && !_t.isHTML5) { | |
if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) { | |
_t.peakData = { | |
left: oPeakData.leftPeak, | |
right: oPeakData.rightPeak | |
}; | |
} | |
if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) { | |
_t.waveformData = { | |
left: oWaveformDataLeft.split(','), | |
right: oWaveformDataRight.split(',') | |
}; | |
} | |
if (_t._iO.useEQData) { | |
if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) { | |
var eqLeft = oEQData.leftEQ.split(','); | |
_t.eqData = eqLeft; | |
_t.eqData.left = eqLeft; | |
if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) { | |
_t.eqData.right = oEQData.rightEQ.split(','); | |
} | |
} | |
} | |
} | |
if (_t.playState === 1) { | |
// special case/hack: ensure buffering is false if loading from cache (and not yet started) | |
if (!_t.isHTML5 && _s.flashVersion === 8 && !_t.position && _t.isBuffering) { | |
_t._onbufferchange(0); | |
} | |
if (_t._iO.whileplaying) { | |
_t._iO.whileplaying.apply(_t); // flash may call after actual finish | |
} | |
if ((_t.loaded || (!_t.loaded && _t._iO.isMovieStar)) && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration - _t.position <= _t._iO.onbeforefinishtime) { | |
_t._onbeforefinish(); | |
} | |
} | |
return true; | |
}; | |
// Only applies to RTMP | |
this._onconnect = function(bSuccess) { | |
var fN = 'SMSound._onconnect(): '; | |
bSuccess = (bSuccess === 1); | |
_s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2)); | |
_t.connected = bSuccess; | |
if (bSuccess) { | |
_t.failures = 0; | |
if (_idCheck(_t.sID)) { | |
if (_t.getAutoPlay()) { | |
_t.play(undefined, _t.getAutoPlay()); // only update the play state if auto playing | |
} else if (_t._iO.autoLoad) { | |
_t.load(); | |
} | |
} | |
if (_t._iO.onconnect) { | |
_t._iO.onconnect.apply(_t,[bSuccess]); | |
} | |
} | |
}; | |
this._onload = function(nSuccess) { | |
var fN = 'SMSound._onload(): ', loadOK = (nSuccess?true:false); | |
_s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2)); | |
// <d> | |
if (!loadOK && !_t.isHTML5) { | |
if (_s.sandbox.noRemote === true) { | |
_s._wD(fN + _str('noNet'), 1); | |
} | |
if (_s.sandbox.noLocal === true) { | |
_s._wD(fN + _str('noLocal'), 1); | |
} | |
} | |
// </d> | |
_t.loaded = loadOK; | |
_t.readyState = loadOK?3:2; | |
_t._onbufferchange(0); | |
if (_t._iO.onload) { | |
_t._iO.onload.apply(_t, [loadOK]); | |
} | |
return true; | |
}; | |
// fire onfailure() only once at most | |
// 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.sID+'" count '+_t.failures); | |
if (_t._iO.onfailure && _t.failures === 1) { | |
_t._iO.onfailure(_t, msg, level, code); | |
} else { | |
_s._wD('SMSound._onfailure(): ignoring'); | |
} | |
}; | |
this._onbeforefinish = function() { | |
if (!_t.didBeforeFinish) { | |
_t.didBeforeFinish = true; | |
if (_t._iO.onbeforefinish) { | |
_s._wD('SMSound._onbeforefinish(): "' + _t.sID + '"'); | |
_t._iO.onbeforefinish.apply(_t); | |
} | |
} | |
}; | |
this._onjustbeforefinish = function(msOffset) { | |
if (!_t.didJustBeforeFinish) { | |
_t.didJustBeforeFinish = true; | |
if (_t._iO.onjustbeforefinish) { | |
_s._wD('SMSound._onjustbeforefinish(): "' + _t.sID + '"'); | |
_t._iO.onjustbeforefinish.apply(_t); | |
} | |
} | |
}; | |
this._onfinish = function() { | |
// _s._wD('SMSound._onfinish(): "' + _t.sID + '" got instanceCount '+_t.instanceCount); | |
var _io_onfinish = _t._iO.onfinish; // store local copy before it gets trashed.. | |
_t._onbufferchange(0); | |
_t.resetOnPosition(0); | |
if (_t._iO.onbeforefinishcomplete) { | |
_t._iO.onbeforefinishcomplete.apply(_t); | |
} | |
// reset some state items | |
_t.didBeforeFinish = false; | |
_t.didJustBeforeFinish = false; | |
if (_t.instanceCount) { | |
_t.instanceCount--; | |
if (!_t.instanceCount) { | |
// reset instance options | |
_t.playState = 0; | |
_t.paused = false; | |
_t.instanceCount = 0; | |
_t.instanceOptions = {}; | |
_t._iO = {}; | |
_stop_html5_timer(); | |
} | |
if (!_t.instanceCount || _t._iO.multiShotEvents) { | |
// fire onfinish for last, or every instance | |
if (_io_onfinish) { | |
_s._wD('SMSound._onfinish(): "' + _t.sID + '"'); | |
_io_onfinish.apply(_t); | |
} | |
} | |
} | |
}; | |
this._onbufferchange = function(nIsBuffering) { | |
var fN = 'SMSound._onbufferchange()'; | |
if (_t.playState === 0) { | |
// ignore if not playing | |
return false; | |
} | |
if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) { | |
return false; | |
} | |
_t.isBuffering = (nIsBuffering === 1); | |
if (_t._iO.onbufferchange) { | |
_s._wD(fN + ': ' + nIsBuffering); | |
_t._iO.onbufferchange.apply(_t); | |
} | |
return true; | |
}; | |
this._ondataerror = function(sError) { | |
// flash 9 wave/eq data handler | |
if (_t.playState > 0) { // hack: called at start, and end from flash at/after onfinish() | |
_s._wD('SMSound._ondataerror(): ' + sError); | |
if (_t._iO.ondataerror) { | |
_t._iO.ondataerror.apply(_t); | |
} | |
} | |
}; | |
}; // SMSound() | |
// --- private SM2 internals --- | |
_getDocument = function() { | |
return (_doc.body?_doc.body:(_doc._docElement?_doc.documentElement:_doc.getElementsByTagName('div')[0])); | |
}; | |
_id = function(sID) { | |
return _doc.getElementById(sID); | |
}; | |
_mixin = function(oMain, oAdd) { | |
// non-destructive merge | |
var o1 = {}, i, o2, o; | |
for (i in oMain) { // clone c1 | |
if (oMain.hasOwnProperty(i)) { | |
o1[i] = oMain[i]; | |
} | |
} | |
o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd); | |
for (o in o2) { | |
if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') { | |
o1[o] = o2[o]; | |
} | |
} | |
return o1; | |
}; | |
_event = (function() { | |
var old = (_win.attachEvent), | |
evt = { | |
add: (old?'attachEvent':'addEventListener'), | |
remove: (old?'detachEvent':'removeEventListener') | |
}; | |
function getArgs(oArgs) { | |
var args = _slice.call(oArgs), len = args.length; | |
if (old) { | |
args[1] = 'on' + args[1]; // prefix | |
if (len > 3) { | |
args.pop(); // no capture | |
} | |
} else if (len === 3) { | |
args.push(false); | |
} | |
return args; | |
} | |
function apply(args, sType) { | |
var element = args.shift(), | |
method = [evt[sType]]; | |
if (old) { | |
element[method](args[0], args[1]); | |
} else { | |
element[method].apply(element, args); | |
} | |
} | |
function add() { | |
apply(getArgs(arguments), 'add'); | |
} | |
function remove() { | |
apply(getArgs(arguments), 'remove'); | |
} | |
return { | |
'add': add, | |
'remove': remove | |
}; | |
}()); | |
_html5OK = function(iO) { | |
return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay(iO.url)||_html5Only)); // Use type, if specified. If HTML5-only mode, no other options, so just give 'er | |
}; | |
_html5CanPlay = function(sURL) { | |
// try to find MIME, test and return truthiness | |
if (!_s.useHTML5Audio || !_s.hasHTML5) { | |
return false; | |
} | |
var result, mime, offset, fileExt, item, aF = _s.audioFormats; | |
if (!_html5Ext) { | |
_html5Ext = []; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
_html5Ext.push(item); | |
if (aF[item].related) { | |
_html5Ext = _html5Ext.concat(aF[item].related); | |
} | |
} | |
} | |
_html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')','i'); | |
} | |
mime = (typeof sURL.type !== 'undefined'?sURL.type:null); | |
fileExt = (typeof sURL === 'string'?sURL.toLowerCase().match(_html5Ext):null); // TODO: Strip URL queries, etc. | |
if (!fileExt || !fileExt.length) { | |
if (!mime) { | |
return false; | |
} else { | |
// audio/mp3 -> mp3, result should be known | |
offset = mime.indexOf(';'); | |
fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6); // strip "audio/X; codecs.." | |
} | |
} else { | |
fileExt = fileExt[0].substr(1); // "mp3", for example | |
} | |
if (fileExt && typeof _s.html5[fileExt] !== 'undefined') { | |
// result known | |
return _s.html5[fileExt]; | |
} else { | |
if (!mime) { | |
if (fileExt && _s.html5[fileExt]) { | |
return _s.html5[fileExt]; | |
} else { | |
// best-case guess, audio/whatever-dot-filename-format-you're-playing | |
mime = 'audio/'+fileExt; | |
} | |
} | |
result = _s.html5.canPlayType(mime); | |
_s.html5[fileExt] = result; | |
// _s._wD('canPlayType, found result: '+result); | |
return result; | |
} | |
}; | |
_testHTML5 = function() { | |
if (!_s.useHTML5Audio || typeof Audio === 'undefined') { | |
return false; | |
} | |
var a = (typeof Audio !== 'undefined' ? new Audio(null):null), item, support = {}, aF, i, _hasFlash = _detectFlash(); | |
function _cp(m) { | |
var canPlay, i, j, isOK = false; | |
if (!a || typeof a.canPlayType !== 'function') { | |
return false; | |
} | |
if (m instanceof Array) { | |
// iterate through all mime types, return any successes | |
for (i=0, j=m.length; i<j && !isOK; i++) { | |
if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) { | |
isOK = true; | |
_s.html5[m[i]] = true; | |
} | |
} | |
return isOK; | |
} else { | |
canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false); | |
return (canPlay && (canPlay.match(_s.html5Test)?true:false)); | |
} | |
} | |
// test all registered formats + codecs | |
aF = _s.audioFormats; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
support[item] = _cp(aF[item].type); | |
// assign result to related formats, too | |
if (aF[item] && aF[item].related) { | |
for (i=aF[item].related.length; i--;) { | |
_s.html5[aF[item].related[i]] = support[item]; | |
} | |
} | |
} | |
} | |
support.canPlayType = (a?_cp:null); | |
_s.html5 = _mixin(_s.html5, support); | |
return true; | |
}; | |
_strings = { | |
// <d> | |
notReady: 'Not loaded yet - wait for soundManager.onload()/onready()', | |
notOK: 'Audio support is not available.', | |
appXHTML: _smc + 'createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.', | |
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.)', | |
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 focus-related event..', | |
waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...', | |
waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...', | |
needFunction: _sm + ': Function object expected for %s', | |
badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character', | |
noMS: 'MovieStar mode not enabled. Exiting.', | |
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 to call Flash from JS..', | |
noPolling: _sm + ': Polling (whileloading()/whileplaying() support) is disabled.', | |
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.', | |
noPeak: 'Warning: peakData features unsupported for movieStar formats', | |
shutdown: _sm + '.disable(): Shutting down', | |
queue: _sm + ': Queueing %s handler', | |
smFail: _sm + ': Failed to initialise.', | |
smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.', | |
fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..', | |
fbLoaded: 'Flash loaded', | |
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.', | |
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', | |
mfOn: 'mobileFlash::enabling on-screen flash repositioning', | |
policy: 'Enabling usePolicyFile for data access' | |
// </d> | |
}; | |
_str = function() { // o [,items to replace] | |
// <d> | |
var args = _slice.call(arguments), // real array, please | |
o = args.shift(), // first arg | |
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]); | |
} | |
} | |
return str; | |
// </d> | |
}; | |
_loopFix = function(sOpt) { | |
// flash 8 requires stream = false for looping to work | |
if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) { | |
_wDS('as2loop'); | |
sOpt.stream = false; | |
} | |
return sOpt; | |
}; | |
_policyFix = function(sOpt, sPre) { | |
if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) { | |
_s._wD((sPre?sPre+':':'') + _str('policy')); | |
sOpt.usePolicyFile = true; | |
} | |
return sOpt; | |
}; | |
_complain = function(sMsg) { | |
if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') { | |
console.warn(sMsg); | |
} else { | |
_s._wD(sMsg); | |
} | |
}; | |
_doNothing = function() { | |
return false; | |
}; | |
_disableObject = function(o) { | |
for (var oProp in o) { | |
if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') { | |
o[oProp] = _doNothing; | |
} | |
} | |
oProp = null; | |
}; | |
_failSafely = function(bNoDisable) { | |
// general failure exception handler | |
if (typeof bNoDisable === 'undefined') { | |
bNoDisable = false; | |
} | |
if (_disabled || bNoDisable) { | |
_wDS('smFail', 2); | |
_s.disable(bNoDisable); | |
} | |
}; | |
_normalizeMovieURL = function(smURL) { | |
var urlParams = null; | |
if (smURL) { | |
if (smURL.match(/\.swf(\?.*)?$/i)) { | |
urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4); | |
if (urlParams) { | |
return smURL; // assume user knows what they're doing | |
} | |
} else if (smURL.lastIndexOf('/') !== smURL.length - 1) { | |
smURL = smURL + '/'; | |
} | |
} | |
return (smURL && smURL.lastIndexOf('/') !== - 1?smURL.substr(0, smURL.lastIndexOf('/') + 1):'./') + _s.movieURL; | |
}; | |
_setVersionInfo = function() { | |
if (_fV !== 8 && _fV !== 9) { | |
_s._wD(_str('badFV', _fV, _defaultFlashVersion)); | |
_s.flashVersion = _defaultFlashVersion; | |
} | |
var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf'); // debug flash movie, if applicable | |
if (_s.useHTML5Audio && !_html5Only && _s.audioFormats.mp4.required && _s.flashVersion < 9) { | |
_s._wD(_str('needfl9')); | |
_s.flashVersion = 9; | |
} | |
_fV = _s.flashVersion; // short-hand for internal use | |
_s.version = _s.versionNumber + (_html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)')); | |
// set up default options | |
if (_fV > 8) { | |
_s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options); | |
_s.features.buffering = true; | |
} | |
if (_fV > 8 && _s.useMovieStar) { | |
// flash 9+ support for movieStar formats as well as MP3 | |
_s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions); | |
_s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _s.netStreamTypes.join('|') + ')(\\?.*)?$', 'i'); | |
_s.mimePattern = _s.netStreamMimeTypes; | |
_s.features.movieStar = true; | |
} else { | |
_s.useMovieStar = false; | |
_s.features.movieStar = false; | |
} | |
_s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')]; | |
_s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf',isDebug); | |
_s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8); | |
}; | |
_setPolling = function(bPolling, bHighPerformance) { | |
if (!_s.o || !_s.allowPolling) { | |
return false; | |
} | |
_s.o._setPolling(bPolling, bHighPerformance); | |
}; | |
function _initDebug() { | |
if (_s.debugURLParam.test(_wl)) { | |
_s.debugMode = true; // allow force of debug mode via URL | |
} | |
// <d> | |
if (_id(_s.debugID)) { | |
return false; | |
} | |
var oD, oDebug, oTarget, oToggle, tmp; | |
if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) { | |
oD = _doc.createElement('div'); | |
oD.id = _s.debugID + '-toggle'; | |
oToggle = { | |
'position': 'fixed', | |
'bottom': '0px', | |
'right': '0px', | |
'width': '1.2em', | |
'height': '1.2em', | |
'lineHeight': '1.2em', | |
'margin': '2px', | |
'textAlign': 'center', | |
'border': '1px solid #999', | |
'cursor': 'pointer', | |
'background': '#fff', | |
'color': '#333', | |
'zIndex': 10001 | |
}; | |
oD.appendChild(_doc.createTextNode('-')); | |
oD.onclick = _toggleDebug; | |
oD.title = 'Toggle SM2 debug console'; | |
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'); | |
if (_s.debugMode && !_id(oD.id)) { | |
try { | |
oTarget = _getDocument(); | |
oTarget.appendChild(oD); | |
} catch(e2) { | |
throw new Error(_str('appXHTML')); | |
} | |
oTarget.appendChild(oDebug); | |
} | |
} | |
oTarget = null; | |
// </d> | |
} | |
_createMovie = function(smID, smURL) { | |
var specialCase = null, | |
remoteURL = (smURL?smURL:_s.url), | |
localURL = (_s.altURL?_s.altURL:remoteURL), | |
oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(), s, x, sClass, side = '100%', isRTL = null, html = _doc.getElementsByTagName('html')[0]; | |
isRTL = (html && html.dir && html.dir.match(/rtl/i)); | |
smID = (typeof smID === 'undefined'?_s.id:smID); | |
if (_didAppend && _appendSuccess) { | |
return false; // ignore if already succeeded | |
} | |
function _initMsg() { | |
_s._wD('-- SoundManager 2 ' + _s.version + (!_html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_html5Only ? (_s.useMovieStar?', MovieStar mode':'') + (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : (_s.useFastPolling?'fast':'normal')) + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1); | |
} | |
if (_html5Only) { | |
_setVersionInfo(); | |
_initMsg(); | |
_s.oMC = _id(_s.movieID); | |
_init(); | |
// prevent multiple init attempts | |
_didAppend = true; | |
_appendSuccess = true; | |
return false; | |
} | |
_didAppend = true; | |
// safety check for legacy (change to Flash 9 URL) | |
_setVersionInfo(); | |
_s.url = _normalizeMovieURL(_s._overHTTP?remoteURL:localURL); | |
smURL = _s.url; | |
_s.wmode = (!_s.wmode && _s.useHighPerformance && !_s.useMovieStar?'transparent':_s.wmode); | |
if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) { | |
_s.specialWmodeCase = true; | |
// 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 Jan.2011 (?) | |
_wDS('spcWmode'); | |
_s.wmode = null; | |
} | |
oEmbed = { | |
'name': smID, | |
'id': smID, | |
'src': smURL, | |
'width': side, | |
'height': side, | |
'quality': 'high', | |
'allowScriptAccess': _s.allowScriptAccess, | |
'bgcolor': _s.bgColor, | |
'pluginspage': 'http://www.macromedia.com/go/getflashplayer', | |
'type': 'application/x-shockwave-flash', | |
'wmode': _s.wmode, | |
'hasPriority': 'true' // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html | |
}; | |
if (_s.debugFlash) { | |
oEmbed.FlashVars = 'debug=1'; | |
} | |
if (!_s.wmode) { | |
delete oEmbed.wmode; // don't write empty attribute | |
} | |
if (_isIE) { | |
// IE is "special". | |
oMovie = _doc.createElement('div'); | |
movieHTML = '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '"><param name="movie" value="' + smURL + '" /><param name="AllowScriptAccess" value="' + _s.allowScriptAccess + '" /><param name="quality" value="' + oEmbed.quality + '" />' + (_s.wmode?'<param name="wmode" value="' + _s.wmode + '" /> ':'') + '<param name="bgcolor" value="' + _s.bgColor + '" />' + (_s.debugFlash?'<param name="FlashVars" value="' + oEmbed.FlashVars + '" />':'') + '</object>'; | |
} else { | |
oMovie = _doc.createElement('embed'); | |
for (tmp in oEmbed) { | |
if (oEmbed.hasOwnProperty(tmp)) { | |
oMovie.setAttribute(tmp, oEmbed[tmp]); | |
} | |
} | |
} | |
_initDebug(); | |
extraClass = _getSWFCSS(); | |
oTarget = _getDocument(); | |
if (oTarget) { | |
_s.oMC = _id(_s.movieID)?_id(_s.movieID):_doc.createElement('div'); | |
if (!_s.oMC.id) { | |
_s.oMC.id = _s.movieID; | |
_s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass; | |
// "hide" flash movie | |
s = null; | |
oEl = null; | |
if (!_s.useFlashBlock) { | |
if (_s.useHighPerformance) { | |
s = { | |
'position': 'fixed', | |
'width': '8px', | |
'height': '8px', | |
// >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes. | |
'bottom': '0px', | |
'left': '0px', | |
'overflow': 'hidden' | |
}; | |
} else { | |
s = { | |
'position': 'absolute', | |
'width': '6px', | |
'height': '6px', | |
'top': '-9999px', | |
'left': '-9999px' | |
}; | |
if (isRTL) { | |
s.left = Math.abs(parseInt(s.left,10))+'px'; | |
} | |
} | |
} | |
if (_isWebkit) { | |
_s.oMC.style.zIndex = 10000; // soundcloud-reported render/crash fix, safari 5 | |
} | |
if (!_s.debugFlash) { | |
for (x in s) { | |
if (s.hasOwnProperty(x)) { | |
_s.oMC.style[x] = s[x]; | |
} | |
} | |
} | |
try { | |
if (!_isIE) { | |
_s.oMC.appendChild(oMovie); | |
} | |
oTarget.appendChild(_s.oMC); | |
if (_isIE) { | |
oEl = _s.oMC.appendChild(_doc.createElement('div')); | |
oEl.className = _s.swfCSS.swfBox; | |
oEl.innerHTML = movieHTML; | |
} | |
_appendSuccess = true; | |
} catch(e) { | |
throw new Error(_str('appXHTML')); | |
} | |
} else { | |
// it's already in the document. | |
sClass = _s.oMC.className; | |
_s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:''); | |
_s.oMC.appendChild(oMovie); | |
if (_isIE) { | |
oEl = _s.oMC.appendChild(_doc.createElement('div')); | |
oEl.className = _s.swfCSS.swfBox; | |
oEl.innerHTML = movieHTML; | |
} | |
_appendSuccess = true; | |
} | |
} | |
if (specialCase) { | |
_s._wD(specialCase); | |
} | |
_initMsg(); | |
_s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_s._overHTTP && _s.altURL?' (alternate URL)':''), 1); | |
return true; | |
}; | |
_idCheck = this.getSoundById; | |
_initMovie = function() { | |
if (_html5Only) { | |
_createMovie(); | |
return false; | |
} | |
// attempt to get, or create, movie | |
if (_s.o) { | |
return false; // may already exist | |
} | |
_s.o = _s.getMovie(_s.id); // inline markup | |
if (!_s.o) { | |
if (!_oRemoved) { | |
// try to create | |
_createMovie(_s.id, _s.url); | |
} else { | |
// try to re-append removed movie after reboot() | |
if (!_isIE) { | |
_s.oMC.appendChild(_oRemoved); | |
} else { | |
_s.oMC.innerHTML = _oRemovedHTML; | |
} | |
_oRemoved = null; | |
_didAppend = true; | |
} | |
_s.o = _s.getMovie(_s.id); | |
} | |
if (_s.o) { | |
_s._wD(_smc+'initMovie(): Got '+_s.o.nodeName+' element ('+(_didAppend?'created via JS':'static HTML')+')'); | |
_wDS('waitEI'); | |
} | |
if (_s.oninitmovie instanceof Function) { | |
setTimeout(_s.oninitmovie, 1); | |
} | |
return true; | |
}; | |
_go = function(sURL) { | |
// where it all begins. | |
if (sURL) { | |
_s.url = sURL; | |
} | |
_initMovie(); | |
}; | |
_delayWaitForEI = function() { | |
setTimeout(_waitForEI, 500); | |
}; | |
_waitForEI = function() { | |
if (_waitingForEI) { | |
return false; | |
} | |
_waitingForEI = true; | |
_event.remove(_win, 'load', _delayWaitForEI); | |
if (_tryInitOnFocus && !_isFocused) { | |
_wDS('waitFocus'); | |
return false; | |
} | |
var p; | |
if (!_didInit) { | |
p = _s.getMoviePercent(); | |
_s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':'')))); | |
} | |
setTimeout(function() { | |
p = _s.getMoviePercent(); | |
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 (!_s._overHTTP && p) { | |
_wDS('localFail', 2); | |
if (!_s.debugFlash) { | |
_wDS('tryDebug', 2); | |
} | |
} | |
if (p === 0) { | |
// if 0 (not null), probably a 404. | |
_s._wD(_str('swf404', _s.url)); | |
} | |
_debugTS('flashtojs', false, ': Timed out' + _s._overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)'); | |
} | |
// give up / time-out, depending | |
if (!_didInit && _okToDisable) { | |
if (p === null) { | |
// SWF failed. Maybe blocked. | |
if (_s.useFlashBlock || _s.flashLoadTimeout === 0) { | |
if (_s.useFlashBlock) { | |
_flashBlockHandler(); | |
} | |
_wDS('waitForever'); | |
} else { | |
// old SM2 behaviour, simply fail | |
_failSafely(true); | |
} | |
} else { | |
// flash loaded? Shouldn't be a blocking issue, then. | |
if (_s.flashLoadTimeout === 0) { | |
_wDS('waitForever'); | |
} else { | |
_failSafely(true); | |
} | |
} | |
} | |
}, _s.flashLoadTimeout); | |
}; | |
_go = function(sURL) { | |
// where it all begins. | |
if (sURL) { | |
_s.url = sURL; | |
} | |
_initMovie(); | |
}; | |
// <d> | |
_wDS = function(o, errorLevel) { | |
if (!o) { | |
return ''; | |
} else { | |
return _s._wD(_str(o), errorLevel); | |
} | |
}; | |
if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { | |
_s._wD = function(sText) {window.alert(sText);}; | |
} | |
_toggleDebug = function() { | |
var o = _id(_s.debugID), | |
oT = _id(_s.debugID + '-toggle'); | |
if (!o) { | |
return false; | |
} | |
if (_debugOpen) { | |
// minimize | |
oT.innerHTML = '+'; | |
o.style.display = 'none'; | |
} else { | |
oT.innerHTML = '-'; | |
o.style.display = 'block'; | |
} | |
_debugOpen = !_debugOpen; | |
}; | |
_debugTS = function(sEventType, bSuccess, sMessage) { | |
// troubleshooter debug hooks | |
if (typeof sm2Debugger !== 'undefined') { | |
try { | |
sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); | |
} catch(e) { | |
// oh well | |
} | |
} | |
return true; | |
}; | |
// </d> | |
_getSWFCSS = function() { | |
var css = []; | |
if (_s.debugMode) { | |
css.push(_s.swfCSS.sm2Debug); | |
} | |
if (_s.debugFlash) { | |
css.push(_s.swfCSS.flashDebug); | |
} | |
if (_s.useHighPerformance) { | |
css.push(_s.swfCSS.highPerf); | |
} | |
return css.join(' '); | |
}; | |
_flashBlockHandler = function() { | |
// *possible* flash block situation. | |
var name = _str('fbHandler'), p = _s.getMoviePercent(), css = _s.swfCSS; | |
if (!_s.ok()) { | |
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')+')':'')); | |
} | |
_s.didFlashBlock = true; | |
_processOnEvents({type:'ontimeout',ignoreInit:true}); // fire onready(), complain lightly | |
if (_s.onerror instanceof Function) { | |
_s.onerror.apply(_win); | |
} | |
} else { | |
// SM2 loaded OK (or recovered) | |
if (_s.didFlashBlock) { | |
_s._wD(name+': Unblocked'); | |
} | |
if (_s.oMC) { | |
_s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' '); | |
} | |
} | |
}; | |
_handleFocus = function() { | |
function cleanup() { | |
_event.remove(_win, 'focus', _handleFocus); | |
_event.remove(_win, 'load', _handleFocus); | |
} | |
if (_isFocused || !_tryInitOnFocus) { | |
cleanup(); | |
return true; | |
} | |
_okToDisable = true; | |
_isFocused = true; | |
_s._wD(_smc+'handleFocus()'); | |
if (_isSafari && _tryInitOnFocus) { | |
// giant Safari 3.1 hack - assume mousemove = focus given lack of focus event | |
_event.remove(_win, 'mousemove', _handleFocus); | |
} | |
// allow init to restart | |
_waitingForEI = false; | |
cleanup(); | |
return true; | |
}; | |
_initComplete = function(bNoDisable) { | |
if (_didInit) { | |
return false; | |
} | |
if (_html5Only) { | |
// all good. | |
_s._wD('-- SoundManager 2: loaded --'); | |
_didInit = true; | |
_processOnEvents(); | |
_initUserOnload(); | |
return true; | |
} | |
var sClass = _s.oMC.className, | |
wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()); | |
if (!wasTimeout) { | |
_didInit = true; | |
} | |
_s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1); | |
if (_disabled || bNoDisable) { | |
if (_s.useFlashBlock) { | |
_s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError); | |
} | |
_processOnEvents({type:'ontimeout'}); | |
_debugTS('onload', false); | |
if (_s.onerror instanceof Function) { | |
_s.onerror.apply(_win); | |
} | |
return false; | |
} else { | |
_debugTS('onload', true); | |
} | |
_event.add(_win, 'unload', _doNothing); // prevent browser from showing cached state via back button, because flash will be dead | |
if (_s.waitForWindowLoad && !_windowLoaded) { | |
_wDS('waitOnload'); | |
_event.add(_win, 'load', _initUserOnload); | |
return false; | |
} else { | |
if (_s.waitForWindowLoad && _windowLoaded) { | |
_wDS('docLoaded'); | |
} | |
_initUserOnload(); | |
} | |
return true; | |
}; | |
_addOnEvent = function(sType, oMethod, oScope) { | |
if (typeof _on_queue[sType] === 'undefined') { | |
_on_queue[sType] = []; | |
} | |
_on_queue[sType].push({ | |
'method': oMethod, | |
'scope': (oScope || null), | |
'fired': false | |
}); | |
}; | |
_processOnEvents = function(oOptions) { | |
if (!oOptions) { // assume onready, if unspecified | |
oOptions = { | |
type: 'onready' | |
}; | |
} | |
if (!_didInit && oOptions && !oOptions.ignoreInit) { | |
// not ready yet. | |
return false; | |
} | |
var status = { | |
success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled) | |
}, | |
srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]), // queue specified by type, or none | |
queue = [], i, j, | |
canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok()); | |
for (i = 0; i < srcQueue.length; i++) { | |
if (srcQueue[i].fired !== true) { | |
queue.push(srcQueue[i]); | |
} | |
} | |
if (queue.length) { | |
_s._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, [status]); | |
} else { | |
queue[i].method(status); | |
} | |
if (!canRetry) { // flashblock case doesn't count here | |
queue[i].fired = true; | |
} | |
} | |
} | |
return true; | |
}; | |
_initUserOnload = function() { | |
_win.setTimeout(function() { | |
if (_s.useFlashBlock) { | |
_flashBlockHandler(); | |
} | |
_processOnEvents(); | |
// call user-defined "onload", scoped to window | |
if (_s.onload instanceof Function) { | |
_wDS('onload', 1); | |
_s.onload.apply(_win); | |
_wDS('onloadOK', 1); | |
} | |
if (_s.waitForWindowLoad) { | |
_event.add(_win, 'load', _initUserOnload); | |
} | |
},1); | |
}; | |
_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 (_hasFlash !== undefined) { | |
// this work has already been done. | |
return _hasFlash; | |
} | |
var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.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') { | |
try { | |
obj = new AX('ShockwaveFlash.ShockwaveFlash'); | |
} catch(e) { | |
// oh well | |
} | |
hasPlugin = (!!obj); | |
} | |
_hasFlash = hasPlugin; | |
return hasPlugin; | |
}; | |
_featureCheck = function() { | |
var needsFlash, item, | |
isSpecial = (_ua.match(/iphone os (1|2|3_0|3_1)/i)?true:false); // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works. | |
if (isSpecial) { | |
_s.hasHTML5 = false; // has Audio(), but is broken; let it load links directly. | |
_html5Only = true; // ignore flash case, however | |
if (_s.oMC) { | |
_s.oMC.style.display = 'none'; | |
} | |
return false; | |
} | |
if (_s.useHTML5Audio) { | |
if (!_s.html5 || !_s.html5.canPlayType) { | |
_s._wD('SoundManager: No HTML5 Audio() support detected.'); | |
_s.hasHTML5 = false; | |
return true; | |
} else { | |
_s.hasHTML5 = true; | |
} | |
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 (_detectFlash()) { | |
return true; | |
} | |
} | |
} else { | |
// flash required. | |
return true; | |
} | |
for (item in _s.audioFormats) { | |
if (_s.audioFormats.hasOwnProperty(item) && _s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) { | |
// may need flash for this format? | |
needsFlash = true; | |
} | |
} | |
// sanity check.. | |
if (_s.ignoreFlash) { | |
needsFlash = false; | |
} | |
_html5Only = (_s.useHTML5Audio && _s.hasHTML5 && !needsFlash && !_s.requireFlash); | |
return (_detectFlash() && needsFlash); | |
}; | |
_init = function() { | |
var item, tests = []; | |
_wDS('init'); | |
// called after onload() | |
if (_didInit) { | |
_wDS('didInit'); | |
return false; | |
} | |
function _cleanup() { | |
_event.remove(_win, 'load', _s.beginDelayedInit); | |
} | |
if (_s.hasHTML5) { | |
for (item in _s.audioFormats) { | |
if (_s.audioFormats.hasOwnProperty(item)) { | |
tests.push(item+': '+_s.html5[item]); | |
} | |
} | |
_s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1); | |
} | |
if (_html5Only) { | |
if (!_didInit) { | |
// we don't need no steenking flash! | |
_cleanup(); | |
_s.enabled = true; | |
_initComplete(); | |
} | |
return true; | |
} | |
// flash path | |
_initMovie(); | |
try { | |
_wDS('flashJS'); | |
_s.o._externalInterfaceTest(false); // attempt to talk to Flash | |
if (!_s.allowPolling) { | |
_wDS('noPolling', 1); | |
} else { | |
_setPolling(true, _s.flashPollingInterval ? _s.flashPollingInterval : (_s.useFastPolling ? 10 : 50)); | |
} | |
if (!_s.debugMode) { | |
_s.o._disableDebug(); | |
} | |
_s.enabled = true; | |
_debugTS('jstoflash', true); | |
} catch(e) { | |
_s._wD('js/flash exception: ' + e.toString()); | |
_debugTS('jstoflash', false); | |
_failSafely(true); // don't disable, for reboot() | |
_initComplete(); | |
return false; | |
} | |
_initComplete(); | |
// event cleanup | |
_cleanup(); | |
return true; | |
}; | |
_beginInit = function() { | |
if (_initPending) { | |
return false; | |
} | |
_createMovie(); | |
_initMovie(); | |
_initPending = true; | |
return true; | |
}; | |
_dcLoaded = function() { | |
if (_didDCLoaded) { | |
return false; | |
} | |
_didDCLoaded = true; | |
_initDebug(); | |
if (!_s.useHTML5Audio) { | |
if (!_detectFlash()) { | |
_s._wD('SoundManager: No Flash detected, trying HTML5'); | |
_s.useHTML5Audio = true; | |
} | |
} | |
_testHTML5(); | |
_s.html5.usingFlash = _featureCheck(); | |
_needsFlash = _s.html5.usingFlash; | |
_didDCLoaded = true; | |
if (_doc.removeEventListener) { | |
_doc.removeEventListener('DOMContentLoaded', _dcLoaded, false); | |
} | |
_go(); | |
return true; | |
}; | |
_startTimer = function(oSound) { | |
if (!oSound._hasTimer) { | |
oSound._hasTimer = true; | |
} | |
}; | |
_stopTimer = function(oSound) { | |
if (oSound._hasTimer) { | |
oSound._hasTimer = false; | |
} | |
}; | |
_die = function() { | |
if (_s.onerror instanceof Function) { | |
_s.onerror(); | |
} | |
_s.disable(); | |
}; | |
_badSafariFix = function() { | |
// special case: "bad" Safari can fall back to flash for MP3/MP4 | |
if (!_isBadSafari || !_detectFlash()) { | |
return false; // doesn't apply | |
} | |
var aF = _s.audioFormats, i, item; | |
for (item in aF) { | |
if (aF.hasOwnProperty(item)) { | |
// special case: "bad" Safari can fall back to flash for MP3/MP4 | |
if (item === 'mp3' || item === 'mp4') { | |
_s._wD(_sm+': Using flash fallback for '+item+' format'); | |
_s.html5[item] = false; | |
// assign result to related formats, too | |
if (aF[item] && aF[item].related) { | |
for (i<aF[item].related.length; i--;) { | |
_s.html5[aF[item].related[i]] = false; | |
} | |
} | |
} | |
} | |
} | |
}; | |
// pseudo-private methods called by Flash | |
this._setSandboxType = function(sandboxType) { | |
// <d> | |
var sb = _s.sandbox; | |
sb.type = sandboxType; | |
sb.description = sb.types[(typeof 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); | |
} else if (sb.type === 'localWithNetwork') { | |
sb.noRemote = false; | |
sb.noLocal = true; | |
} else if (sb.type === 'localTrusted') { | |
sb.noRemote = false; | |
sb.noLocal = false; | |
} | |
// </d> | |
}; | |
this._externalInterfaceOK = function(flashDate) { | |
// flash callback confirming flash loaded, EI working etc. | |
// flashDate = approx. timing/delay info for JS/flash bridge | |
if (_s.swfLoaded) { | |
return false; | |
} | |
var eiTime = new Date().getTime(); | |
_s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':'')); | |
_debugTS('swf', true); | |
_debugTS('flashtojs', true); | |
_s.swfLoaded = true; | |
_tryInitOnFocus = false; | |
if (_isBadSafari) { | |
_badSafariFix(); | |
} | |
if (_isIE) { | |
// IE needs a timeout OR delay until window.onload - may need TODO: investigating | |
setTimeout(_init, 100); | |
} else { | |
_init(); | |
} | |
}; | |
_dcIE = function() { | |
if (_doc.readyState === 'complete') { | |
_dcLoaded(); | |
_doc.detachEvent('onreadystatechange', _dcIE); | |
} | |
return true; | |
}; | |
// focus and window load, init | |
if (!_s.hasHTML5 || _needsFlash) { | |
// only applies to Flash mode | |
_event.add(_win, 'focus', _handleFocus); | |
_event.add(_win, 'load', _handleFocus); | |
_event.add(_win, 'load', _delayWaitForEI); | |
if (_isSafari && _tryInitOnFocus) { | |
_event.add(_win, 'mousemove', _handleFocus); // massive Safari focus hack | |
} | |
} | |
if (_doc.addEventListener) { | |
_doc.addEventListener('DOMContentLoaded', _dcLoaded, false); | |
} else if (_doc.attachEvent) { | |
_doc.attachEvent('onreadystatechange', _dcIE); | |
} else { | |
// no add/attachevent support - safe to assume no JS -> Flash either | |
_debugTS('onload', false); | |
_die(); | |
} | |
if (_doc.readyState === 'complete') { | |
setTimeout(_dcLoaded,100); | |
} | |
} // SoundManager() | |
// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading | |
if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { | |
soundManager = new SoundManager(); | |
} | |
// public interfaces | |
window.SoundManager = SoundManager; // constructor | |
window.soundManager = soundManager; // public API, flash callbacks etc | |
}(window)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment