From f848fcedf6b26940f20c12a456c51d1c215a02bb Mon Sep 17 00:00:00 2001 From: riccardo Date: Mon, 28 Mar 2011 20:59:48 +0200 Subject: [PATCH] updated soundmanager (and changed some obsolete functions), modified css to be a little bit more object oriented (button styles), implemented volume (still to be done) --- telemeta/htdocs/css/telemeta.css | 117 +- telemeta/htdocs/js/application.js | 30 +- telemeta/htdocs/js/playerUtils.js | 37 +- .../htdocs/js/soundmanager2-nodebug-jsmin.js | 76 + telemeta/htdocs/js/soundmanager2.js | 3703 ++++++++++++----- telemeta/htdocs/js/soundmanager2_old.js | 1247 ++++++ telemeta/htdocs/swf/soundmanager2.swf | Bin 2435 -> 2867 bytes telemeta/htdocs/swf/soundmanager2_flash9.swf | Bin 8079 -> 8604 bytes .../htdocs/swf/soundmanager2_flash9_old.swf | Bin 0 -> 8079 bytes telemeta/htdocs/swf/soundmanager2_old.swf | Bin 0 -> 2435 bytes .../htdocs/timeside/skins/lab/img/volume.png | Bin 0 -> 1198 bytes telemeta/htdocs/timeside/skins/lab/style.css | 7 + telemeta/htdocs/timeside/src/player.js | 49 +- telemeta/htdocs/timeside/src/playlist.js | 2 +- telemeta/htdocs/timeside/src/soundprovider.js | 19 +- telemeta/templates/telemeta_default/base.html | 2 +- .../telemeta_default/collection_add.html | 6 +- .../telemeta_default/collection_detail.html | 10 +- .../telemeta_default/collection_edit.html | 6 +- .../telemeta_default/collection_list.html | 2 +- .../telemeta_default/geo_continents.html | 4 +- telemeta/templates/telemeta_default/home.html | 11 +- .../templates/telemeta_default/login.html | 2 +- .../telemeta_default/mediaitem_add.html | 6 +- .../telemeta_default/mediaitem_copy.html | 6 +- .../telemeta_default/mediaitem_detail.html | 15 +- .../telemeta_default/mediaitem_edit.html | 6 +- .../telemeta_default/mediaitem_list.html | 2 +- 28 files changed, 4277 insertions(+), 1088 deletions(-) create mode 100755 telemeta/htdocs/js/soundmanager2-nodebug-jsmin.js mode change 100644 => 100755 telemeta/htdocs/js/soundmanager2.js create mode 100644 telemeta/htdocs/js/soundmanager2_old.js mode change 100644 => 100755 telemeta/htdocs/swf/soundmanager2.swf mode change 100644 => 100755 telemeta/htdocs/swf/soundmanager2_flash9.swf create mode 100644 telemeta/htdocs/swf/soundmanager2_flash9_old.swf create mode 100644 telemeta/htdocs/swf/soundmanager2_old.swf create mode 100644 telemeta/htdocs/timeside/skins/lab/img/volume.png diff --git a/telemeta/htdocs/css/telemeta.css b/telemeta/htdocs/css/telemeta.css index 88116c5f..c35fa0c1 100644 --- a/telemeta/htdocs/css/telemeta.css +++ b/telemeta/htdocs/css/telemeta.css @@ -12,8 +12,7 @@ body { margin: 0em; } -a:link, a:visited { - /* border-bottom:1px dotted #BBB; */ +/*a:link, a:visited { color: #BB0000; text-decoration:none; } @@ -21,6 +20,15 @@ a:link:hover, a:visited:hover { background-color: transparent; color: #BB0000; text-decoration: underline; +}*/ +a, a:visited { + color: #BB0000; + text-decoration:none; +} +a:hover { + background-color: transparent; + color: #BB0000; + text-decoration: underline; } a img { border: none; } @@ -716,9 +724,10 @@ table.listing thead th { table.listing thead th :link:hover, table.listing thead th :visited:hover { background-color: transparent; } -table.listing a { +/*conflicts with buttons inside table*/ +/*table.listing a { border: none; -} +}*/ table.listing thead th a { padding-right: 12px; } @@ -982,85 +991,97 @@ a.image-link { } /*----------------------------------*/ - -.mediaitem_button, .mediaitem_button:visited, -.mediaitem_button:link{ - padding:4px 8px 4px 26px; /*top right bottom left - last value depends on the icon size (default=16)*/ - border-top: 1px solid #DDD; - border-left: 1px solid #DDD; - border-bottom: 1px solid #999; - border-right: 1px solid #999; - background-color: #f9f9f9; /*#626262;*/ - color:#444; - font-weight: bold; - background-repeat: no-repeat; +.component, .component_icon, .component:hover, .component_icon:hover, .component:visited, .component_icon:visited{ background-position: 1ex .5ex; -moz-border-radius: 1ex 1ex 1ex 1ex; -webkit-border-radius: 1ex 1ex 1ex 1ex; border-radius: 1ex 1ex 1ex 1ex; + padding:.7ex .7ex .7ex .7ex; + background-color: #f9f9f9; /*#626262;*/ + color:#444; + /*border: 1px solid #eee;*/ + text-decoration: none; + margin:0; +} +.component + .component, .component + .component_icon, .component_icon + .component , +.component_icon + .component_icon{ + margin-left: .1ex; +} + +.component_icon, .component_icon:hover, .component_icon:visited{ + background-repeat: no-repeat; + background-position: 1ex .5ex; + padding:4px 8px 4px 26px; /*top right bottom left - last value depends on the icon size (default=16)*/ } -.mediaitem_button:hover,.mediaitem_button:link:hover, .mediaitem_button:visited:hover{ - background-color: #e9e9e9; /*#e9e9d9;*/ + +.button, .button:visited, .button:hover{ + font-weight: bold; + border-top: 2px solid #e9e9e9 !important; + border-left: 2px solid #e9e9e9 !important; + border-right: 2px solid #e9e9e9 !important; + border-bottom: 2px solid #e9e9e9 !important; +} + +.button:hover{ + border-top: 2px solid #f9f9f9 !important; + border-left: 2px solid #f9f9f9 !important; + border-bottom: 2px solid #999 !important; + border-right: 2px solid #999 !important; + background-color: #f4f4f4; /*#e9e9d9;*/ color: #000; /*#6A0307;*/ - text-decoration: none; } -.mediaitem_button_no_icon{ - padding:4px 8px 4px 8px !important; + + +.list_item, .list_item:visited, .list_item:hover{ + display:block; + color:#6A0307 !important; +} + +.list_item:hover{ + background-color: #6A0307; + color:white !important; } -.mediaitem_button_edit{ + +.icon_edit{ background-image: url('/images/edit_page.png'); } -.mediaitem_button_copy{ +.icon_copy{ background-image: url('/images/copy_page.png'); } -.mediaitem_button_previous{ +.icon_previous{ background-image: url('/images/previous.png'); } -.mediaitem_button_next{ +.icon_next{ background-image: url('/images/next.png'); } -.mediaitem_button_dublin_core{ +.icon_dublin_core{ background-image: url('/images/dublin_core.png'); } -.mediaitem_button_cancel{ +.icon_cancel{ background-image: url('/images/cancel.png'); } -.mediaitem_button_save{ +.icon_save{ background-image: url('/images/save.png'); } -.mediaitem_button_add{ +.icon_add{ background-image: url('/images/add.png'); } -.mediaitem_button_login{ +.icon_login{ background-image: url('/images/password.png'); } -.mediaitem_button_search{ +.icon_search{ background-image: url('/images/find.png'); } -.mediaitem_button_ok{ +.icon_ok{ background-image: url('/images/ok.png'); } -.mediaitem_button_csv{ +.icon_csv{ background-image: url('/images/csv.png'); } -.mediaitem_button_playlist{ +.icon_playlist{ background-image: url('/images/playlist.png'); } -a.listItem, a.listItem:visited, a.listItem:link{ - display:block; - border:0px; - font-weight: normal; - color:#6A0307; - background-color: ''; - text-decoration: none; -} - -a.listItem:hover,a.listItem:link:hover, a.listItem:visited:hover{ - background-color: #6A0307; - color:white; - text-decoration: none; -} .addToPlaylist { margin:0.5ex; diff --git a/telemeta/htdocs/js/application.js b/telemeta/htdocs/js/application.js index f3d50718..12442a4d 100644 --- a/telemeta/htdocs/js/application.js +++ b/telemeta/htdocs/js/application.js @@ -210,10 +210,6 @@ var popup={ var div = this.jQuery('
').css({ //this is _cfg_ position: 'absolute', overflow:'auto', //necessary to properly display the content - border: '1px solid #DDD', - backgroundColor:'#f9f9f9', //same as mediaitem_button (see telemeta.css) - padding:'1ex', - margin: '0', display: 'none', zIndex:1000 }); @@ -222,15 +218,20 @@ var popup={ } return div; }, - className: undefined, + className: 'component', divShadow: function(){ - return this.jQuery('
').css({ //this is _cfg_ + var divShadow = this.jQuery('
').css({ //this is _cfg_ position: 'absolute', display: 'none', overflow:'visible', - backgroundColor:'#000', + padding: '0 !important', //otherwise setting divShadow dimension is tricky + backgroundColor:'#000 !important', //shadow must be black zIndex:999 }); + if(this.className){ + divShadow.addClass(this.className); + } + return divShadow; }, // mouseDownNamespace : "mousedown.popup__", // keyDownNamespace : "keydown.popup__", @@ -490,12 +491,13 @@ var popup={ return onCancel(); } }; - var subdiv = $J('
').append( + var subdiv = $J('
').css({'padding':'1ex','float':'right'}). + append( $J(''). html('Ok'). - css('float','right'). - addClass('mediaitem_button'). - addClass('mediaitem_button_ok'). + addClass('component_icon'). + addClass('button'). + addClass('icon_ok'). attr('href','#'). click(function(){ return onOk(); @@ -505,9 +507,9 @@ var popup={ subdiv.append( $J(''). html('Cancel'). - css('float','right'). - addClass('mediaitem_button'). - addClass('mediaitem_button_cancel'). + addClass('component_icon'). + addClass('button'). + addClass('icon_cancel'). attr('href','#'). click(function(){ return onCancel(); diff --git a/telemeta/htdocs/js/playerUtils.js b/telemeta/htdocs/js/playerUtils.js index fcaa34f3..93b0c51c 100644 --- a/telemeta/htdocs/js/playerUtils.js +++ b/telemeta/htdocs/js/playerUtils.js @@ -15,10 +15,16 @@ function togglePlayerMaximization() { } else { ctr = $('#player_maximized').append(view); } - ctr.css({opacity: 0, display: 'block'}); - if (player) + ctr.css({ + opacity: 0, + display: 'block' + }); + if (player){ player.resize(); - ctr.animate({opacity: 1}, 100); + } + ctr.animate({ + opacity: 1 + }, 100); } function load_sound() { @@ -31,14 +37,15 @@ function load_sound() { TimeSide.load(function() { provider.setSource(sound); }); - // sound.load(); // Auto-loading overloads the Django test server + // sound.load(); // Auto-loading overloads the Django test server } } function change_visualizer() { set_player_image_url($('#visualizer_id').get(0).value); - if (player) + if (player){ player.refreshImage(); + } return false; } @@ -46,7 +53,7 @@ function load_player(duration) { $(document).ready(function () { if (!$('#player').length){ return; - } + } soundUrl = $('.ts-wave a').attr('href'); $('.ts-wave a img').insertAfter('.ts-wave a'); @@ -54,7 +61,9 @@ function load_player(duration) { TimeSide.load(function() { map = new TimeSide.MarkerMap(); - provider = new TimeSide.SoundProvider({duration: duration}); + provider = new TimeSide.SoundProvider({ + duration: duration + }); player = new TimeSide.Player('#player', { image: get_player_image_src }); @@ -79,10 +88,18 @@ function load_player(duration) { load_sound(); }); - soundManager.onload = function() { + //old code valid for old version: + // soundManager.onload = function() { + // soundEngineReady = true; + // load_sound(); + // } + //replaced by: + soundManager.onready(function() { + // SM2 is ready to go! + //alert('okkkk'); soundEngineReady = true; - load_sound(); - } + load_sound(); // soundManager.createSound(), etc. + }); } diff --git a/telemeta/htdocs/js/soundmanager2-nodebug-jsmin.js b/telemeta/htdocs/js/soundmanager2-nodebug-jsmin.js new file mode 100755 index 00000000..afb35e1c --- /dev/null +++ b/telemeta/htdocs/js/soundmanager2-nodebug-jsmin.js @@ -0,0 +1,76 @@ +/** @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;h0)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;i1&&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=''+(b.wmode?' ':"")+''+(b.debugFlash?'':"")+""}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;h0) '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) @@ -35,328 +77,401 @@ function SoundManager(smURL,smID) { '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. + '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/video 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. + 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/video options, merged into defaultOptions if flash 9 + movieStar mode is enabled - 'onmetadata': null, // callback for when video width/height etc. are received - 'useVideo': false // if loading movieStar content, whether to show video - } - - this.flashBlockHelper = { - 'enabled': false, // experimental, removed with >v2.80 - 'message': [] // "nag bar" to show when messaging the user, if SM2 fails on firefox etc. + 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) }; - var _s = this; this.version = null; - this.versionNumber = 'V2.90a.20081028'; + this.versionNumber = 'V2.97a.20110306'; this.movieURL = null; - this.url = null; + this.url = (smURL || null); this.altURL = null; this.swfLoaded = false; this.enabled = false; this.o = null; - this.id = (smID||'sm2movie'); + 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.sounds = {}; this.soundIDs = []; this.muted = false; - this.isIE = (navigator.userAgent.match(/MSIE/i)); - this.isSafari = (navigator.userAgent.match(/safari/i)); - this.isGecko = (navigator.userAgent.match(/gecko/i)); this.debugID = 'soundmanager-debug'; - this._debugOpen = true; - this._didAppend = false; - this._appendSuccess = false; - this._didInit = false; - this._disabled = false; - this._windowLoaded = false; - this._hasConsole = (typeof console != 'undefined' && typeof console.log != 'undefined'); - this._debugLevels = ['log','info','warn','error']; - this._defaultFlashVersion = 8; + this.debugURLParam = /([#?&])debug=1/i; + this.specialWmodeCase = false; + this.didFlashBlock = false; + + this.filePattern = null; this.filePatterns = { - flash8: /\.(mp3)/i, - flash9: /\.(mp3)/i + 'flash8': /\.mp3(\?.*)?$/i, + 'flash9': /\.mp3(\?.*)?$/i }; - 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.filePattern = null; + + 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 = { - peakData: false, - waveformData: false, - eqData: false + '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)' + 'localTrusted': 'local, trusted (local+internet access)' }, 'description': null, 'noRemote': null, 'noLocal': null + // }; - this._setVersionInfo = function() { - if (_s.flashVersion != 8 && _s.flashVersion != 9) { - alert('soundManager.flashVersion must be 8 or 9. "'+_s.flashVersion+'" is invalid. Reverting to '+_s._defaultFlashVersion+'.'); - _s.flashVersion = _s._defaultFlashVersion; - } - _s.version = _s.versionNumber+(_s.flashVersion==9?' (AS3/Flash 9)':' (AS2/Flash 8)'); - // set up default options - if (_s.flashVersion > 8) { - _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.flash9Options); - } - if (_s.flashVersion > 8 && _s.useMovieStar) { - _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.movieStarOptions); - _s.filePatterns.flash9 = new RegExp('.(mp3|'+_s.netStreamTypes.join('|')+')','i'); - } else { - _s.useMovieStar = false; + 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; } - _s.filePattern = _s.filePatterns[(_s.flashVersion!=8?'flash9':'flash8')]; - _s.movieURL = (_s.flashVersion==8?'soundmanager2.swf':'soundmanager2_flash9.swf'); - _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion==9); } - this._overHTTP = (document.location?document.location.protocol.match(/http/i):null); - this._waitingforEI = false; - this._initPending = false; - this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined'); - this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null); - this._okToDisable = !this._tryInitOnFocus; + if (_is_pre || this._use_maybe) { + // less-strict canPlayType() checking option + _s.html5Test = /^(probably|maybe)$/i; + } - this.useAltURL = !this._overHTTP; // use altURL if not "online" + // 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; + } + }()); + // - var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'; + // --- public API methods --- - // --- public methods --- - - this.supported = function() { - return (_s._didInit && !_s._disabled); + this.ok = function() { + return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5)); }; - this.getMovie = function(smID) { - return _s.isIE?window[smID]:(_s.isSafari?document.getElementById(smID)||document[smID]:document.getElementById(smID)); - }; + this.supported = this.ok; // legacy - this.loadFromXML = function(sXmlUrl) { - try { - _s.o._loadFromXML(sXmlUrl); - } catch(e) { - _s._failSafely(); - return true; - }; + this.getMovie = function(smID) { + return _isIE?_win[smID]:(_isSafari?_id(smID) || _doc[smID]:_id(smID)); }; this.createSound = function(oOptions) { - if (!_s._didInit) throw new Error('soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods'); - if (arguments.length==2) { + 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 - var oOptions = {'id':arguments[0],'url':arguments[1]}; - }; - var thisOptions = _s._mergeObjects(oOptions); // inherit SM2 defaults - var _tO = thisOptions; // alias - _s._wD('soundManager.createSound(): '+_tO.id+' ('+_tO.url+')',1); - if (_s._idCheck(_tO.id,true)) { - _s._wD('soundManager.createSound(): '+_tO.id+' exists',1); + 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]; - }; - if (_s.flashVersion > 8 && _s.useMovieStar) { - if (_tO.isMovieStar == null) { - _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false); - } - if (_tO.isMovieStar) { - _s._wD('soundManager.createSound(): using MovieStar handling'); - } - if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) { - _s._wD('Warning: peak/waveform/eqData features unsupported for non-MP3 formats'); - _tO.usePeakData = false; - _tO.useWaveformData = false; - _tO.useEQData = false; - } - }; - _s.sounds[_tO.id] = new SMSound(_tO); - _s.soundIDs[_s.soundIDs.length] = _tO.id; - // AS2: - if (_s.flashVersion == 8) { - _s.o._createSound(_tO.id,_tO.onjustbeforefinishtime); - } else { - _s.o._createSound(_tO.id,_tO.url,_tO.onjustbeforefinishtime,_tO.usePeakData,_tO.useWaveformData,_tO.useEQData,_tO.isMovieStar,(_tO.isMovieStar?_tO.useVideo:false)); - }; - if (_tO.autoLoad || _tO.autoPlay) { - window.setTimeout(function() { - if (_s.sounds[_tO.id]) { - _s.sounds[_tO.id].load(_tO); - } - },20); - } - if (_tO.autoPlay) { - if (_s.flashVersion == 8) { - _s.sounds[_tO.id].playState = 1; // we can only assume this sound will be playing soon. - } else { - _s.sounds[_tO.id].play(); - } - } - return _s.sounds[_tO.id]; - }; - - this.createVideo = function(oOptions) { - if (arguments.length==2) { - var oOptions = {'id':arguments[0],'url':arguments[1]}; - }; - if (_s.flashVersion >= 9) { - oOptions.isMovieStar = true; - oOptions.useVideo = true; + } + + 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 { - _s._wD('soundManager.createVideo(): flash 9 required for video. Exiting.',2); - return false; + 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 (!_s.useMovieStar) { - _s._wD('soundManager.createVideo(): MovieStar mode not enabled. Exiting.',2); + + if (_tO.autoPlay && !_tO.serverURL) { // rtmp will play in onconnect + oSound.play(); } - return _s.createSound(oOptions); - } + return oSound; + }; - this.destroySound = function(sID,bFromSound) { + this.destroySound = function(sID, _bFromSound) { // explicitly destroy a sound before normal page unload, etc. - if (!_s._idCheck(sID)) return false; - for (var i=0; i<_s.soundIDs.length; i++) { - if (_s.soundIDs[i] == sID) { - _s.soundIDs.splice(i,1); - continue; - }; - }; - // conservative option: avoid crash with ze flash 8 - // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP + flash 8?? - // if (_s.flashVersion != 8) { - _s.sounds[sID].unload(); - // } - if (!bFromSound) { + 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 - _s.sounds[sID].destruct(); - }; + oS.destruct(true); + } + oS = null; delete _s.sounds[sID]; + return true; }; - this.destroyVideo = this.destroySound; - - this.load = function(sID,oOptions) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].load(oOptions); + this.load = function(sID, oOptions) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].load(oOptions); }; this.unload = function(sID) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].unload(); + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].unload(); }; - this.play = function(sID,oOptions) { - if (!_s._idCheck(sID)) { - if (typeof oOptions != 'Object') oOptions = {url:oOptions}; // overloading use case: play('mySound','/path/to/some.mp3'); + 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, creation + playing of sound: .play('someID',{url:'/path/to.mp3'}); - _s._wD('soundController.play(): attempting to create "'+sID+'"',1); + // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'}); + _s._wD(fN + 'attempting to create "' + sID + '"', 1); oOptions.id = sID; - _s.createSound(oOptions); + return _s.createSound(oOptions).play(); } else { return false; - }; - }; - _s.sounds[sID].play(oOptions); + } + } + return _s.sounds[sID].play(oOptions); }; this.start = this.play; // just for convenience - this.setPosition = function(sID,nMsecOffset) { - if (!_s._idCheck(sID)) return false; - nMsecOffset = Math.min((nMsecOffset||0),_s.duration); // don't allow seek past loaded duration - _s.sounds[sID].setPosition(nMsecOffset); + this.setPosition = function(sID, nMsecOffset) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPosition(nMsecOffset); }; this.stop = function(sID) { - if (!_s._idCheck(sID)) return false; - _s._wD('soundManager.stop('+sID+')',1); - _s.sounds[sID].stop(); + if (!_idCheck(sID)) { + return false; + } + _s._wD(_sm+'.stop(' + sID + ')', 1); + return _s.sounds[sID].stop(); }; this.stopAll = function() { - _s._wD('soundManager.stopAll()',1); + _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 - }; + if (_s.sounds[oSound] instanceof SMSound) { + _s.sounds[oSound].stop(); // apply only to sound objects + } + } }; this.pause = function(sID) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].pause(); + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].pause(); }; this.pauseAll = function() { - for (var i=_s.soundIDs.length; i--;) { + for (var i = _s.soundIDs.length; i--;) { _s.sounds[_s.soundIDs[i]].pause(); } }; this.resume = function(sID) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].resume(); + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].resume(); }; this.resumeAll = function() { - for (var i=_s.soundIDs.length; i--;) { + for (var i = _s.soundIDs.length; i--;) { _s.sounds[_s.soundIDs[i]].resume(); } }; this.togglePause = function(sID) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].togglePause(); + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].togglePause(); }; - this.setPan = function(sID,nPan) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].setPan(nPan); + this.setPan = function(sID, nPan) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setPan(nPan); }; - this.setVolume = function(sID,nVol) { - if (!_s._idCheck(sID)) return false; - _s.sounds[sID].setVolume(nVol); + this.setVolume = function(sID, nVol) { + if (!_idCheck(sID)) { + return false; + } + return _s.sounds[sID].setVolume(nVol); }; this.mute = function(sID) { - if (typeof sID != 'string') sID = null; + var fN = _sm+'.mute(): ', + i = 0; + if (typeof sID !== 'string') { + sID = null; + } if (!sID) { - var o = null; - _s._wD('soundManager.mute(): Muting all sounds'); - for (var i=_s.soundIDs.length; i--;) { + _s._wD(fN + 'Muting all sounds'); + for (i = _s.soundIDs.length; i--;) { _s.sounds[_s.soundIDs[i]].mute(); } _s.muted = true; } else { - if (!_s._idCheck(sID)) return false; - _s._wD('soundManager.mute(): Muting "'+sID+'"'); - _s.sounds[sID].mute(); + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Muting "' + sID + '"'); + return _s.sounds[sID].mute(); } + return true; }; this.muteAll = function() { @@ -364,884 +479,2528 @@ function SoundManager(smURL,smID) { }; this.unmute = function(sID) { - if (typeof sID != 'string') sID = null; + var fN = _sm+'.unmute(): ', i; + if (typeof sID !== 'string') { + sID = null; + } if (!sID) { - var o = null; - _s._wD('soundManager.unmute(): Unmuting all sounds'); - for (var i=_s.soundIDs.length; i--;) { + _s._wD(fN + 'Unmuting all sounds'); + for (i = _s.soundIDs.length; i--;) { _s.sounds[_s.soundIDs[i]].unmute(); } _s.muted = false; } else { - if (!_s._idCheck(sID)) return false; - _s._wD('soundManager.unmute(): Unmuting "'+sID+'"'); - _s.sounds[sID].unmute(); + if (!_idCheck(sID)) { + return false; + } + _s._wD(fN + 'Unmuting "' + sID + '"'); + return _s.sounds[sID].unmute(); } + return true; }; this.unmuteAll = function() { _s.unmute(); }; - this.setPolling = function(bPolling) { - if (!_s.o || !_s.allowPolling) return false; - // _s._wD('soundManager.setPolling('+bPolling+')'); - _s.o._setPolling(bPolling); + 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(bUnload) { + this.disable = function(bNoDisable) { // destroy all functions - if (_s._disabled) return false; - _s._disabled = true; - _s._wD('soundManager.disable(): Disabling all functions - future calls will return false.',1); - for (var i=_s.soundIDs.length; i--;) { - _s._disableObject(_s.sounds[_s.soundIDs[i]]); - }; - _s.initComplete(); // fire "complete", despite fail - _s._disableObject(_s); + 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.handleFlashBlock = function(bForce) { - // experimental, removed with >v2.80. - return false; + 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) { - return (sURL?(sURL.match(_s.filePattern)?true:false):null); + 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('SoundManager.getSoundById(): sID is null/undefined'); + 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); - // soundManager._wD('trace: '+arguments.callee.caller); - }; + _s._wD('"' + sID + '" is an invalid sound ID.', 2); + } return result; }; - this.onload = function() { - // window.onload() equivalent for SM2, ready to create sounds etc. - // this is a stub - you can override this in your own external script, eg. soundManager.onload = function() {} - soundManager._wD('Warning: soundManager.onload() is undefined.',2); - }; - - this.onerror = function() { - // stub for user handler, called when SM2 fails to load/init - }; - - // --- "private" methods --- - - this._idCheck = this.getSoundById; - - this._disableObject = function(o) { - for (var oProp in o) { - if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') o[oProp] = function(){return false;}; - }; - oProp = null; - }; - - this._failSafely = function() { - // exception handler for "object doesn't support this property or method" or general failure - var fpgssTitle = 'You may need to whitelist this location/domain eg. file:///C:/ or C:/ or mysite.com, or set ALWAYS ALLOW under the Flash Player Global Security Settings page. The latter is probably less-secure.'; - var flashCPL = 'view/edit'; - var FPGSS = 'FPGSS'; - if (!_s._disabled) { - _s._wD('soundManager: Failed to initialise.',2); - _s.disable(); - }; - }; - - this._normalizeMovieURL = function(smURL) { - if (smURL) { - if (smURL.match(/\.swf/)) { - smURL = smURL.substr(0,smURL.lastIndexOf('.swf')); + this.onready = function(oMethod, oScope) { + var sType = 'onready'; + if (oMethod && oMethod instanceof Function) { + if (_didInit) { + _wDS('queue', sType); } - if (smURL.lastIndexOf('/') != smURL.length-1) { - smURL = smURL+'/'; + if (!oScope) { + oScope = _win; } + _addOnEvent(sType, oMethod, oScope); + _processOnEvents(); + return true; + } else { + throw _str('needFunction', sType); } - return(smURL && smURL.lastIndexOf('/')!=-1?smURL.substr(0,smURL.lastIndexOf('/')+1):'./')+_s.movieURL; }; - this._getDocument = function() { - return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0])); + 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._getDocument._protected = true; - - this._createMovie = function(smID,smURL) { - if (_s._didAppend && _s._appendSuccess) return false; // ignore if already succeeded - if (window.location.href.indexOf('debug=1')+1) _s.debugMode = true; // allow force of debug mode via URL - _s._didAppend = true; - - // safety check for legacy (change to Flash 9 URL) - _s._setVersionInfo(); - var remoteURL = (smURL?smURL:_s.url); - var localURL = (_s.altURL?_s.altURL:remoteURL); - _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL); - smURL = _s.url; - - var htmlEmbed = ''; - var htmlObject = ''+(_s.useHighPerformance && !_s.useMovieStar?' ':'')+''; - var html = (!_s.isIE?htmlEmbed:htmlObject); - - var toggleElement = '
-
'; - var debugHTML = '
'; - var appXHTML = 'soundManager._createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.'; - - var oTarget = _s._getDocument(); - if (oTarget) { - - _s.oMC = document.getElementById('sm2-container')?document.getElementById('sm2-container'):document.createElement('div'); - if (!_s.oMC.id) { - _s.oMC.id = 'sm2-container'; - _s.oMC.className = 'movieContainer'; - // "hide" flash movie - var s = null; - if (_s.useHighPerformance) { - s = { - position: 'fixed', - width: '8px', - height: '8px', // must be at least 6px for flash to run fast. odd? yes. - bottom: '0px', - left: '0px', - zIndex:-1 // sit behind everything else - } - } else { - s = { - position: 'absolute', - width: '1px', - height: '1px', - bottom: '0px', - left: '0px' - } - } - var x = null; - for (x in s) { - _s.oMC.style[x] = s[x]; - } - try { - oTarget.appendChild(_s.oMC); - _s.oMC.innerHTML = html; - _s._appendSuccess = true; - } catch(e) { - throw new Error(appXHTML); - } - } else { - // it's already in the document. - _s.oMC.innerHTML = html; - _s._appendSuccess = true; - } - if (!document.getElementById(_s.debugID) && ((!_s._hasConsole||!_s.useConsole)||(_s.useConsole && _s._hasConsole && !_s.consoleOnly))) { - var oDebug = document.createElement('div'); - oDebug.id = _s.debugID; - oDebug.style.display = (_s.debugMode?'block':'none'); - if (_s.debugMode) { - try { - var oD = document.createElement('div'); - oTarget.appendChild(oD); - oD.innerHTML = toggleElement; - } catch(e) { - throw new Error(appXHTML); - }; - }; - oTarget.appendChild(oDebug); - }; - oTarget = null; - }; - _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s._wD?', high performance mode':'')+' --',1); - _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?'(alternate URL)':''),1); + this.getMoviePercent = function() { + return (_s.o && typeof _s.o.PercentLoaded !== 'undefined'?_s.o.PercentLoaded():null); }; - // aliased to this._wD() - this._writeDebug = function(sText,sType,bTimestamp) { - if (!_s.debugMode) return false; - if (typeof bTimestamp != 'undefined' && bTimestamp) { - sText = sText + ' | '+new Date().getTime(); - }; - if (_s._hasConsole && _s.useConsole) { - var sMethod = _s._debugLevels[sType]; - if (typeof console[sMethod] != 'undefined') { + 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; - }; - var sDID = 'soundmanager-debug'; + } + if (_s.useConsoleOnly) { + return true; + } + } try { - var o = document.getElementById(sDID); - if (!o) return false; - var oItem = document.createElement('div'); - sText = sText.replace(/\n/g,'
'); - if (typeof sType == 'undefined') { - var sType = 0; + 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); - }; - oItem.innerHTML = sText; + 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'; - }; + 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 + o.insertBefore(oItem, o.firstChild); // bottom-to-top } catch(e) { // oh well - }; + } o = null; + //
+ return true; }; - this._writeDebug._protected = true; - this._wD = this._writeDebug; - - this._wDAlert = function(sText) { alert(sText); }; - - if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) { - _s._wD = _s._wDAlert; - }; - - this._toggleDebug = function() { - var o = document.getElementById(_s.debugID); - var oT = document.getElementById(_s.debugID+'-toggle'); - if (!o) return false; - if (_s._debugOpen) { - // minimize - oT.innerHTML = '+'; - o.style.display = 'none'; - } else { - oT.innerHTML = '-'; - o.style.display = 'block'; - }; - _s._debugOpen = !_s._debugOpen; - }; - - this._toggleDebug._protected = true; + this._wD = this._writeDebug; // alias this._debug = function() { - _s._wD('--- soundManager._debug(): Current sound objects ---',1); - for (var i=0,j=_s.soundIDs.length; i + _wDS('currentObj', 1); + for (var i = 0, j = _s.soundIDs.length; i < j; i++) { _s.sounds[_s.soundIDs[i]]._debug(); - }; + } + // }; - this._mergeObjects = function(oMain,oAdd) { - // non-destructive merge - var o1 = {}; // clone o1 - for (var i in oMain) { - o1[i] = oMain[i]; + 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 o2 = (typeof oAdd == 'undefined'?_s.defaultOptions:oAdd); - for (var o in o2) { - if (typeof o1[o] == 'undefined') o1[o] = o2[o]; - }; - return o1; + 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.createMovie = function(sURL) { - if (sURL) _s.url = sURL; - _s._initMovie(); + this.destruct = function() { + _s._wD(_sm+'.destruct()'); + _s.disable(true); }; - this.go = this.createMovie; // nice alias - - this._initMovie = function() { - // attempt to get, or create, movie - if (_s.o) return false; // pre-init may have fired this function before window.onload(), may already exist - _s.o = _s.getMovie(_s.id); // try to get flash movie (inline markup) - if (!_s.o) { - // try to create - _s._createMovie(_s.id,_s.url); - _s.o = _s.getMovie(_s.id); - }; - if (_s.o) { - _s._wD('soundManager._initMovie(): Got '+_s.o.nodeName+' element ('+(_s._didAppend?'created via JS':'static HTML')+')',1); - _s._wD('soundManager._initMovie(): Waiting for ExternalInterface call from Flash..'); - }; + this.beginDelayedInit = function() { + // _s._wD(_sm+'.beginDelayedInit()'); + _windowLoaded = true; + _dcLoaded(); + setTimeout(_beginInit, 20); + _delayWaitForEI(); }; - this.waitForExternalInterface = function() { - if (_s._waitingForEI) return false; - _s._waitingForEI = true; - if (_s._tryInitOnFocus && !_s._isFocused) { - _s._wD('soundManager: Special case: Flash may not have started due to non-focused tab (Safari is lame), and/or focus cannot be detected. Waiting for focus-related event..'); - return false; - }; - if (!_s._didInit) { - _s._wD('soundManager: Getting impatient, still waiting for Flash.. ;)'); - }; - setTimeout(function() { - if (!_s._didInit) { - _s._wD('soundManager: No Flash response within reasonable time after document load.\nPossible causes: Flash version under 8, no support, or Flash security denying JS-Flash communication.',2); - if (!_s._overHTTP) { - _s._wD('soundManager: Loading this page from local/network file system (not over HTTP?) Flash security likely restricting JS-Flash access. Consider adding current URL to "trusted locations" in the Flash player security settings manager at '+flashCPLink+', or simply serve this content over HTTP.',2); - }; - }; - // if still not initialized and no other options, give up - if (!_s._didInit && _s._okToDisable) _s._failSafely(); - },750); - }; - - this.handleFocus = function() { - if (_s._isFocused || !_s._tryInitOnFocus) return true; - _s._okToDisable = true; - _s._isFocused = true; - _s._wD('soundManager.handleFocus()'); - if (_s._tryInitOnFocus) { - // giant Safari 3.1 hack - assume window in focus if mouse is moving, since document.hasFocus() not currently implemented. - window.removeEventListener('mousemove',_s.handleFocus,false); - }; - // allow init to restart - _s._waitingForEI = false; - setTimeout(_s.waitForExternalInterface,500); - // detach event - if (window.removeEventListener) { - window.removeEventListener('focus',_s.handleFocus,false); - } else if (window.detachEvent) { - window.detachEvent('onfocus',_s.handleFocus); - }; - }; - this.initComplete = function() { - if (_s._didInit) return false; - _s._didInit = true; - _s._wD('-- SoundManager 2 '+(_s._disabled?'failed to load':'loaded')+' ('+(_s._disabled?'security/load error':'OK')+') --',1); - if (_s._disabled) { - _s._wD('soundManager.initComplete(): calling soundManager.onerror()',1); - _s.onerror.apply(window); - return false; + // 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); + } }; - if (_s.waitForWindowLoad && !_s._windowLoaded) { - _s._wD('soundManager: Waiting for window.onload()'); - if (window.addEventListener) { - window.addEventListener('load',_s.initUserOnload,false); - } else if (window.attachEvent) { - window.attachEvent('onload',_s.initUserOnload); - }; - return false; + } + + 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 + + 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 (_s.waitForWindowLoad && _s._windowLoaded) { - _s._wD('soundManager: Document already loaded'); + 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 + 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 }; - _s.initUserOnload(); + 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 = '' + (_s.wmode?' ':'') + '' + (_s.debugFlash?'':'') + ''; + } 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(); }; - this.initUserOnload = function() { - _s._wD('soundManager.initComplete(): calling soundManager.onload()',1); - // call user-defined "onload", scoped to window - //try { - _s.onload.apply(window); - /* - } catch(e) { - // something broke (likely JS error in user function) - _s._wD('soundManager.onload() threw an exception: '+e.message,2); - setTimeout(function(){throw new Error(e)},20); - return false; - }; - */ - _s._wD('soundManager.onload() complete',1); + _delayWaitForEI = function() { + setTimeout(_waitForEI, 500); }; - this.init = function() { - _s._wD('-- soundManager.init() --'); - // called after onload() - _s._initMovie(); - if (_s._didInit) { - _s._wD('soundManager.init(): Already called?'); + _waitForEI = function() { + if (_waitingForEI) { return false; - }; - // event cleanup - if (window.removeEventListener) { - window.removeEventListener('load',_s.beginDelayedInit,false); - } else if (window.detachEvent) { - window.detachEvent('onload',_s.beginDelayedInit); - }; - try { - _s._wD('Attempting to call JS -> Flash..'); - _s.o._externalInterfaceTest(false); // attempt to talk to Flash - // _s._wD('Flash ExternalInterface call (JS-Flash) OK',1); - if (!_s.allowPolling) { - _s._wD('Polling (whileloading/whileplaying support) is disabled.',1); - } - _s.setPolling(true); - if (!_s.debugMode) _s.o._disableDebug(); - _s.enabled = true; - } catch(e) { - _s._failSafely(); - _s.initComplete(); + } + _waitingForEI = true; + _event.remove(_win, 'load', _delayWaitForEI); + if (_tryInitOnFocus && !_isFocused) { + _wDS('waitFocus'); return false; - }; - _s.initComplete(); + } + 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); }; - this.beginDelayedInit = function() { - _s._wD('soundManager.beginDelayedInit(): Document loaded'); - _s._windowLoaded = true; - setTimeout(_s.waitForExternalInterface,500); - setTimeout(_s.beginInit,20); + _go = function(sURL) { + // where it all begins. + if (sURL) { + _s.url = sURL; + } + _initMovie(); }; - this.beginInit = function() { - if (_s._initPending) return false; - _s.createMovie(); // ensure creation if not already done - _s._initMovie(); - _s._initPending = true; - return true; + // + _wDS = function(o, errorLevel) { + if (!o) { + return ''; + } else { + return _s._wD(_str(o), errorLevel); + } }; - this.domContentLoaded = function() { - _s._wD('soundManager.domContentLoaded()'); - if (document.removeEventListener) document.removeEventListener('DOMContentLoaded',_s.domContentLoaded,false); - _s.go(); - }; + if (_wl.indexOf('debug=alert') + 1 && _s.debugMode) { + _s._wD = function(sText) {window.alert(sText);}; + } - this._externalInterfaceOK = function() { - // callback from flash for confirming that movie loaded, EI is working etc. - if (_s.swfLoaded) return false; - _s._wD('soundManager._externalInterfaceOK()'); - _s.swfLoaded = true; - _s._tryInitOnFocus = false; - if (_s.isIE) { - // IE needs a timeout OR delay until window.onload - may need TODO: investigating - setTimeout(_s.init,100); + _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 { - _s.init(); - }; + oT.innerHTML = '-'; + o.style.display = 'block'; + } + _debugOpen = !_debugOpen; }; - 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; - _s._wD('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',2); - } else if (sb.type == 'localWithNetwork') { - sb.noRemote = false; - sb.noLocal = true; - } else if (sb.type == 'localTrusted') { - sb.noRemote = false; - sb.noLocal = false; - }; + _debugTS = function(sEventType, bSuccess, sMessage) { + // troubleshooter debug hooks + if (typeof sm2Debugger !== 'undefined') { + try { + sm2Debugger.handleEvent(sEventType, bSuccess, sMessage); + } catch(e) { + // oh well + } + } + return true; }; + // - this.destruct = function() { - _s._wD('soundManager.destruct()'); - _s.disable(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(' '); }; - - // SMSound (sound object) - - function SMSound(oOptions) { - var _t = this; - this.sID = oOptions.id; - this.url = oOptions.url; - this.options = _s._mergeObjects(oOptions); - this.instanceOptions = this.options; // per-play-instance-specific options - this._iO = this.instanceOptions; // short alias - this._debug = function() { - if (_s.debugMode) { - var stuff = null; - var msg = []; - var sF = null; - var sfBracket = null; - var maxLength = 64; // # of characters of function code to show before truncating - 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[msg.length] = ' '+stuff+': {'+sF.substr(sfBracket+1,(Math.min(Math.max(sF.indexOf('\n')-1,maxLength),maxLength))).replace(/\n/g,'')+'... }'; - } else { - msg[msg.length] = ' '+stuff+': '+_t.options[stuff]; - }; - }; - }; - _s._wD('SMSound() merged options: {\n'+msg.join(', \n')+'\n}'); - }; + _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(' '); + } + } }; - this._debug(); - - this.id3 = { - /* - Name/value pairs set via Flash when available - see reference for names: - http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001567.html - (eg., this.id3.songname or this.id3['songname']) - */ - }; - - this.resetProperties = function(bLoaded) { - _t.bytesLoaded = null; - _t.bytesTotal = null; - _t.position = null; - _t.duration = null; - _t.durationEstimate = null; - _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.instanceOptions = {}; - _t.instanceCount = 0; - _t.peakData = { - left: 0, - right: 0 - }; - _t.waveformData = []; - _t.eqData = []; + _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; }; - _t.resetProperties(); + _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; + }; - // --- public methods --- + _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 + }); + }; - this.load = function(oOptions) { - if (typeof oOptions != 'undefined') { - _t._iO = _s._mergeObjects(oOptions); - _t.instanceOptions = _t._iO; - } else { - var oOptions = _t.options; - _t._iO = oOptions; - _t.instanceOptions = _t._iO; - } - if (typeof _t._iO.url == 'undefined') _t._iO.url = _t.url; - _s._wD('soundManager.load(): '+_t._iO.url,1); - if (_t._iO.url == _t.url && _t.readyState != 0 && _t.readyState != 2) { - _s._wD('soundManager.load(): current URL already assigned.',1); + _processOnEvents = function(oOptions) { + if (!oOptions) { // assume onready, if unspecified + oOptions = { + type: 'onready' + }; + } + if (!_didInit && oOptions && !oOptions.ignoreInit) { + // not ready yet. return false; } - _t.loaded = false; - _t.readyState = 1; - _t.playState = (oOptions.autoPlay?1:0); // if autoPlay, assume "playing" is true (no way to detect when it actually starts in Flash unless onPlay is watched?) - try { - if (_s.flashVersion==8) { - _s.o._load(_t.sID,_t._iO.url,_t._iO.stream,_t._iO.autoPlay,(_t._iO.whileloading?1:0)); - } else { - _s.o._load(_t.sID,_t._iO.url,_t._iO.stream?true:false,_t._iO.autoPlay?true:false); // ,(_tO.whileloading?true:false) - if (_t._iO.isMovieStar && _t._iO.autoLoad && !_t._iO.autoPlay) { - // special case: MPEG4 content must start playing to load, then pause to prevent playing. - _t.pause(); + 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); } - }; - } catch(e) { - _s._wD('SMSound.load(): Exception: JS-Flash communication failed, or JS error.',2); - _s.onerror(); - _s.disable(); - }; + if (!canRetry) { // flashblock case doesn't count here + queue[i].fired = true; + } + } + } + return true; }; - 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.readyState != 2) { // reset if not error - _t.setPosition(0); // reset current sound positioning + _initUserOnload = function() { + _win.setTimeout(function() { + if (_s.useFlashBlock) { + _flashBlockHandler(); } - _s.o._unload(_t.sID,_s.nullURL); - // reset load/status flags - _t.resetProperties(); - } + _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); }; - this.destruct = function() { - // kill sound within Flash - _s._wD('SMSound.destruct(): "'+_t.sID+'"'); - _s.o._destroySound(_t.sID); - _s.destroySound(_t.sID,true); // ensure deletion from controller - } + _detectFlash = function() { - this.play = function(oOptions) { - if (!oOptions) oOptions = {}; - _t._iO = _s._mergeObjects(oOptions,_t._iO); - _t._iO = _s._mergeObjects(_t._iO,_t.options); - _t.instanceOptions = _t._iO; - if (_t.playState == 1) { - var allowMulti = _t._iO.multiShot; - if (!allowMulti) { - _s._wD('SMSound.play(): "'+_t.sID+'" already playing (one-shot)',1); - return false; - } else { - _s._wD('SMSound.play(): "'+_t.sID+'" already playing (multi-shot)',1); - }; - }; - if (!_t.loaded) { - if (_t.readyState == 0) { - _s._wD('SMSound.play(): Attempting to load "'+_t.sID+'"',1); - // try to get this sound playing ASAP - _t._iO.stream = true; - _t._iO.autoPlay = true; - // TODO: need to investigate when false, double-playing - // if (typeof oOptions.autoPlay=='undefined') _tO.autoPlay = true; // only set autoPlay if unspecified here - _t.load(_t._iO); // try to get this sound playing ASAP - } else if (_t.readyState == 2) { - _s._wD('SMSound.play(): Could not load "'+_t.sID+'" - exiting',2); - return false; - } else { - _s._wD('SMSound.play(): "'+_t.sID+'" is loading - attempting to play..',1); - }; - } else { - _s._wD('SMSound.play(): "'+_t.sID+'"'); - }; - if (_t.paused) { - _t.resume(); - } else { - _t.playState = 1; - if (!_t.instanceCount || _s.flashVersion == 9) _t.instanceCount++; - _t.position = (typeof _t._iO.position != 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); - if (_t._iO.onplay) _t._iO.onplay.apply(_t); - _t.setVolume(_t._iO.volume); - _t.setPan(_t._iO.pan); - _s.o._start(_t.sID,_t._iO.loop||1,(_s.flashVersion==9?_t.position:_t.position/1000)); - }; - }; + // 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 - this.start = this.play; // just for convenience + if (_hasFlash !== undefined) { + // this work has already been done. + return _hasFlash; + } - this.stop = function(bAll) { - if (_t.playState == 1) { - _t.playState = 0; - _t.paused = false; - // if (_s.defaultOptions.onstop) _s.defaultOptions.onstop.apply(_s); - if (_t._iO.onstop) _t._iO.onstop.apply(_t); - _s.o._stop(_t.sID,bAll); - _t.instanceCount = 0; - _t._iO = {}; - // _t.instanceOptions = _t._iO; - }; - }; + var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject; - this.setPosition = function(nMsecOffset) { - _t._iO.position = nMsecOffset; - _s._wD('SMSound.setPosition('+nMsecOffset+')'); - _s.o._setPosition(_t.sID,(_s.flashVersion==9?_t._iO.position:_t._iO.position/1000),(_t.paused||!_t.playState)); // if paused or not playing, will not resume (by playing) - }; + if (nP && nP.length) { - this.pause = function() { - if (_t.paused || _t.playState == 0) return false; - _s._wD('SMSound.pause()'); - _t.paused = true; - _s.o._pause(_t.sID); - if (_t._iO.onpause) _t._iO.onpause.apply(_t); - }; + 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; - this.resume = function() { - if (!_t.paused || _t.playState == 0) return false; - _s._wD('SMSound.resume()'); - _t.paused = false; - _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) - if (_t._iO.onresume) _t._iO.onresume.apply(_t); }; - this.togglePause = function() { - _s._wD('SMSound.togglePause()'); - if (!_t.playState) { - _t.play({position:(_s.flashVersion==9?_t.position:_t.position/1000)}); + _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 (_t.paused) { - _t.resume(); + } + 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 { - _t.pause(); - }; + // 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); }; - this.setPan = function(nPan) { - if (typeof nPan == 'undefined') nPan = 0; - _s.o._setPan(_t.sID,nPan); - _t._iO.pan = nPan; - }; + _init = function() { + var item, tests = []; + _wDS('init'); - this.setVolume = function(nVol) { - if (typeof nVol == 'undefined') nVol = 100; - _s.o._setVolume(_t.sID,(_s.muted&&!_t.muted)||_t.muted?0:nVol); - _t._iO.volume = nVol; - }; + // 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; + } - this.mute = function() { - _t.muted = true; - _s.o._setVolume(_t.sID,0); + // 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; }; - this.unmute = function() { - _t.muted = false; - _s.o._setVolume(_t.sID,typeof _t._iO.volume != 'undefined'?_t._iO.volume:_t.options.volume); + _beginInit = function() { + if (_initPending) { + return false; + } + _createMovie(); + _initMovie(); + _initPending = true; + return true; }; - // --- "private" methods called by Flash --- + _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; + }; - this._whileloading = function(nBytesLoaded,nBytesTotal,nDuration) { - if (!_t._iO.isMovieStar) { - _t.bytesLoaded = nBytesLoaded; - _t.bytesTotal = nBytesTotal; - _t.duration = Math.floor(nDuration); - _t.durationEstimate = parseInt((_t.bytesTotal/_t.bytesLoaded)*_t.duration); // estimate total time (will only be accurate with CBR MP3s.) - if (_t.readyState != 3 && _t._iO.whileloading) _t._iO.whileloading.apply(_t); - } else { - _t.bytesLoaded = nBytesLoaded; - _t.bytesTotal = nBytesTotal; - _t.duration = Math.floor(nDuration); - _t.durationEstimate = _t.duration; - if (_t.readyState != 3 && _t._iO.whileloading) _t._iO.whileloading.apply(_t); + _startTimer = function(oSound) { + if (!oSound._hasTimer) { + oSound._hasTimer = true; } }; - this._onid3 = function(oID3PropNames,oID3Data) { - // oID3PropNames: string array (names) - // ID3Data: string array (data) - _s._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.'); - var oData = []; - for (var i=0,j=oID3PropNames.length; i + 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._onfinish = function() { - // sound has finished playing - _t.playState = 0; - _t.paused = false; - if (_t._iO.onfinish) { - _s._wD('SMSound._onfinish(): "'+_t.sID+'"'); - _t._iO.onfinish.apply(_t); - } - if (_t._iO.onbeforefinishcomplete) _t._iO.onbeforefinishcomplete.apply(_t); - // reset some state items - _t.setPosition(0); - _t.didBeforeFinish = false; - _t.didJustBeforeFinish = false; - if (_t.instanceCount) { - _t.instanceCount--; - if (!_t.instanceCount) { - // reset instance options - _t.instanceCount = 0; - _t.instanceOptions = {}; - } + 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(); } }; - this._onmetadata = function(oMetaData) { - // movieStar mode only - _s._wD('SMSound.onmetadata()'); - // Contains a subset of metadata. Note that files may have their own unique metadata. - // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html - if (!oMetaData.width && !oMetaData.height) { - _s._wD('No width/height given, assuming defaults'); - oMetaData.width = 320; - oMetaData.height = 240; - }; - _t.metadata = oMetaData; // potentially-large object from flash - _t.width = oMetaData.width; - _t.height = oMetaData.height; - if (_t._iO.onmetadata) { - _s._wD('SMSound._onmetadata(): "'+_t.sID+'"'); - _t._iO.onmetadata.apply(_t); + _dcIE = function() { + if (_doc.readyState === 'complete') { + _dcLoaded(); + _doc.detachEvent('onreadystatechange', _dcIE); } - _s.wD('SMSound.onmetadata() complete'); + return true; }; - }; // SMSound() + // 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 + } + } - // register a few event handlers - if (window.addEventListener) { - window.addEventListener('focus',_s.handleFocus,false); - window.addEventListener('load',_s.beginDelayedInit,false); - window.addEventListener('unload',_s.destruct,false); - if (_s._tryInitOnFocus) window.addEventListener('mousemove',_s.handleFocus,false); // massive Safari focus hack - } else if (window.attachEvent) { - window.attachEvent('onfocus',_s.handleFocus); - window.attachEvent('onload',_s.beginDelayedInit); - window.attachEvent('unload',_s.destruct); + 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. - soundManager.onerror(); - soundManager.disable(); - }; + // no add/attachevent support - safe to assume no JS -> Flash either + _debugTS('onload', false); + _die(); + } + + if (_doc.readyState === 'complete') { + setTimeout(_dcLoaded,100); + } + +} // SoundManager() - if (document.addEventListener) document.addEventListener('DOMContentLoaded',_s.domContentLoaded,false); +// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading +if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) { + soundManager = new SoundManager(); +} -}; // SoundManager() +// public interfaces +window.SoundManager = SoundManager; // constructor +window.soundManager = soundManager; // public API, flash callbacks etc -var soundManager = new SoundManager(); +}(window)); diff --git a/telemeta/htdocs/js/soundmanager2_old.js b/telemeta/htdocs/js/soundmanager2_old.js new file mode 100644 index 00000000..216115ce --- /dev/null +++ b/telemeta/htdocs/js/soundmanager2_old.js @@ -0,0 +1,1247 @@ +/*! + SoundManager 2: Javascript Sound for the Web + -------------------------------------------- + http://schillmania.com/projects/soundmanager2/ + + Copyright (c) 2008, Scott Schiller. All rights reserved. + Code licensed under the BSD License: + http://schillmania.com/projects/soundmanager2/license.txt + + V2.90a.20081028 +*/ + +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.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 = 'null.mp3'; // 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 "while playing", peak, sound spectrum functions to work.) + this.useMovieStar = false; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio + video formats (AAC, M4V, FLV, MOV etc.) + this.useHighPerformance = true; // flash positioning trick, improves JS/flash callback speed, minimizes delay + this.bgColor = '#ffffff'; // movie (.swf) background color, useful if showing on-screen for video etc. + + 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) + '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" + '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 + 'position': null, // offset (milliseconds) to seek to within loaded sound data. + 'pan': 0, // "pan" settings, left-to-right, -100 to 100 + '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/video 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. + }; + + this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio/video options, merged into defaultOptions if flash 9 + movieStar mode is enabled + 'onmetadata': null, // callback for when video width/height etc. are received + 'useVideo': false // if loading movieStar content, whether to show video + } + + this.flashBlockHelper = { + 'enabled': false, // experimental, removed with >v2.80 + 'message': [] // "nag bar" to show when messaging the user, if SM2 fails on firefox etc. + }; + + var _s = this; + this.version = null; + this.versionNumber = 'V2.90a.20081028'; + this.movieURL = null; + this.url = null; + this.altURL = null; + this.swfLoaded = false; + this.enabled = false; + this.o = null; + this.id = (smID||'sm2movie'); + this.oMC = null; + this.sounds = []; + this.soundIDs = []; + this.muted = false; + this.isIE = (navigator.userAgent.match(/MSIE/i)); + this.isSafari = (navigator.userAgent.match(/safari/i)); + this.isGecko = (navigator.userAgent.match(/gecko/i)); + this.debugID = 'soundmanager-debug'; + this._debugOpen = true; + this._didAppend = false; + this._appendSuccess = false; + this._didInit = false; + this._disabled = false; + this._windowLoaded = false; + this._hasConsole = (typeof console != 'undefined' && typeof console.log != 'undefined'); + this._debugLevels = ['log','info','warn','error']; + this._defaultFlashVersion = 8; + this.filePatterns = { + flash8: /\.(mp3)/i, + flash9: /\.(mp3)/i + }; + 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.filePattern = null; + this.features = { + peakData: false, + waveformData: false, + eqData: 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._setVersionInfo = function() { + if (_s.flashVersion != 8 && _s.flashVersion != 9) { + alert('soundManager.flashVersion must be 8 or 9. "'+_s.flashVersion+'" is invalid. Reverting to '+_s._defaultFlashVersion+'.'); + _s.flashVersion = _s._defaultFlashVersion; + } + _s.version = _s.versionNumber+(_s.flashVersion==9?' (AS3/Flash 9)':' (AS2/Flash 8)'); + // set up default options + if (_s.flashVersion > 8) { + _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.flash9Options); + } + if (_s.flashVersion > 8 && _s.useMovieStar) { + _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.movieStarOptions); + _s.filePatterns.flash9 = new RegExp('.(mp3|'+_s.netStreamTypes.join('|')+')','i'); + } else { + _s.useMovieStar = false; + } + _s.filePattern = _s.filePatterns[(_s.flashVersion!=8?'flash9':'flash8')]; + _s.movieURL = (_s.flashVersion==8?'soundmanager2.swf':'soundmanager2_flash9.swf'); + _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion==9); + } + + this._overHTTP = (document.location?document.location.protocol.match(/http/i):null); + this._waitingforEI = false; + this._initPending = false; + this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined'); + this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null); + this._okToDisable = !this._tryInitOnFocus; + + this.useAltURL = !this._overHTTP; // use altURL if not "online" + + var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'; + + // --- public methods --- + + this.supported = function() { + return (_s._didInit && !_s._disabled); + }; + + this.getMovie = function(smID) { + return _s.isIE?window[smID]:(_s.isSafari?document.getElementById(smID)||document[smID]:document.getElementById(smID)); + }; + + this.loadFromXML = function(sXmlUrl) { + try { + _s.o._loadFromXML(sXmlUrl); + } catch(e) { + _s._failSafely(); + return true; + }; + }; + + this.createSound = function(oOptions) { + if (!_s._didInit) throw new Error('soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods'); + if (arguments.length==2) { + // function overloading in JS! :) ..assume simple createSound(id,url) use case + var oOptions = {'id':arguments[0],'url':arguments[1]}; + }; + var thisOptions = _s._mergeObjects(oOptions); // inherit SM2 defaults + var _tO = thisOptions; // alias + _s._wD('soundManager.createSound(): '+_tO.id+' ('+_tO.url+')',1); + if (_s._idCheck(_tO.id,true)) { + _s._wD('soundManager.createSound(): '+_tO.id+' exists',1); + return _s.sounds[_tO.id]; + }; + if (_s.flashVersion > 8 && _s.useMovieStar) { + if (_tO.isMovieStar == null) { + _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false); + } + if (_tO.isMovieStar) { + _s._wD('soundManager.createSound(): using MovieStar handling'); + } + if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) { + _s._wD('Warning: peak/waveform/eqData features unsupported for non-MP3 formats'); + _tO.usePeakData = false; + _tO.useWaveformData = false; + _tO.useEQData = false; + } + }; + _s.sounds[_tO.id] = new SMSound(_tO); + _s.soundIDs[_s.soundIDs.length] = _tO.id; + // AS2: + if (_s.flashVersion == 8) { + _s.o._createSound(_tO.id,_tO.onjustbeforefinishtime); + } else { + _s.o._createSound(_tO.id,_tO.url,_tO.onjustbeforefinishtime,_tO.usePeakData,_tO.useWaveformData,_tO.useEQData,_tO.isMovieStar,(_tO.isMovieStar?_tO.useVideo:false)); + }; + if (_tO.autoLoad || _tO.autoPlay) { + window.setTimeout(function() { + if (_s.sounds[_tO.id]) { + _s.sounds[_tO.id].load(_tO); + } + },20); + } + if (_tO.autoPlay) { + if (_s.flashVersion == 8) { + _s.sounds[_tO.id].playState = 1; // we can only assume this sound will be playing soon. + } else { + _s.sounds[_tO.id].play(); + } + } + return _s.sounds[_tO.id]; + }; + + this.createVideo = function(oOptions) { + if (arguments.length==2) { + var oOptions = {'id':arguments[0],'url':arguments[1]}; + }; + if (_s.flashVersion >= 9) { + oOptions.isMovieStar = true; + oOptions.useVideo = true; + } else { + _s._wD('soundManager.createVideo(): flash 9 required for video. Exiting.',2); + return false; + } + if (!_s.useMovieStar) { + _s._wD('soundManager.createVideo(): MovieStar mode not enabled. Exiting.',2); + } + return _s.createSound(oOptions); + } + + this.destroySound = function(sID,bFromSound) { + // explicitly destroy a sound before normal page unload, etc. + if (!_s._idCheck(sID)) return false; + for (var i=0; i<_s.soundIDs.length; i++) { + if (_s.soundIDs[i] == sID) { + _s.soundIDs.splice(i,1); + continue; + }; + }; + // conservative option: avoid crash with ze flash 8 + // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP + flash 8?? + // if (_s.flashVersion != 8) { + _s.sounds[sID].unload(); + // } + if (!bFromSound) { + // ignore if being called from SMSound instance + _s.sounds[sID].destruct(); + }; + delete _s.sounds[sID]; + }; + + this.destroyVideo = this.destroySound; + + this.load = function(sID,oOptions) { + if (!_s._idCheck(sID)) return false; + _s.sounds[sID].load(oOptions); + }; + + this.unload = function(sID) { + if (!_s._idCheck(sID)) return false; + _s.sounds[sID].unload(); + }; + + this.play = function(sID,oOptions) { + if (!_s._idCheck(sID)) { + if (typeof oOptions != 'Object') oOptions = {url:oOptions}; // overloading use case: play('mySound','/path/to/some.mp3'); + if (oOptions && oOptions.url) { + // overloading use case, creation + playing of sound: .play('someID',{url:'/path/to.mp3'}); + _s._wD('soundController.play(): attempting to create "'+sID+'"',1); + oOptions.id = sID; + _s.createSound(oOptions); + } else { + return false; + }; + }; + _s.sounds[sID].play(oOptions); + }; + + this.start = this.play; // just for convenience + + this.setPosition = function(sID,nMsecOffset) { + if (!_s._idCheck(sID)) return false; + nMsecOffset = Math.min((nMsecOffset||0),_s.duration); // don't allow seek past loaded duration + _s.sounds[sID].setPosition(nMsecOffset); + }; + + this.stop = function(sID) { + if (!_s._idCheck(sID)) return false; + _s._wD('soundManager.stop('+sID+')',1); + _s.sounds[sID].stop(); + }; + + this.stopAll = function() { + _s._wD('soundManager.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 (!_s._idCheck(sID)) return false; + _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 (!_s._idCheck(sID)) return false; + _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 (!_s._idCheck(sID)) return false; + _s.sounds[sID].togglePause(); + }; + + this.setPan = function(sID,nPan) { + if (!_s._idCheck(sID)) return false; + _s.sounds[sID].setPan(nPan); + }; + + this.setVolume = function(sID,nVol) { + if (!_s._idCheck(sID)) return false; + _s.sounds[sID].setVolume(nVol); + }; + + this.mute = function(sID) { + if (typeof sID != 'string') sID = null; + if (!sID) { + var o = null; + _s._wD('soundManager.mute(): Muting all sounds'); + for (var i=_s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].mute(); + } + _s.muted = true; + } else { + if (!_s._idCheck(sID)) return false; + _s._wD('soundManager.mute(): Muting "'+sID+'"'); + _s.sounds[sID].mute(); + } + }; + + this.muteAll = function() { + _s.mute(); + }; + + this.unmute = function(sID) { + if (typeof sID != 'string') sID = null; + if (!sID) { + var o = null; + _s._wD('soundManager.unmute(): Unmuting all sounds'); + for (var i=_s.soundIDs.length; i--;) { + _s.sounds[_s.soundIDs[i]].unmute(); + } + _s.muted = false; + } else { + if (!_s._idCheck(sID)) return false; + _s._wD('soundManager.unmute(): Unmuting "'+sID+'"'); + _s.sounds[sID].unmute(); + } + }; + + this.unmuteAll = function() { + _s.unmute(); + }; + + this.setPolling = function(bPolling) { + if (!_s.o || !_s.allowPolling) return false; + // _s._wD('soundManager.setPolling('+bPolling+')'); + _s.o._setPolling(bPolling); + }; + + this.disable = function(bUnload) { + // destroy all functions + if (_s._disabled) return false; + _s._disabled = true; + _s._wD('soundManager.disable(): Disabling all functions - future calls will return false.',1); + for (var i=_s.soundIDs.length; i--;) { + _s._disableObject(_s.sounds[_s.soundIDs[i]]); + }; + _s.initComplete(); // fire "complete", despite fail + _s._disableObject(_s); + }; + + this.handleFlashBlock = function(bForce) { + // experimental, removed with >v2.80. + return false; + }; + + this.canPlayURL = function(sURL) { + return (sURL?(sURL.match(_s.filePattern)?true:false):null); + }; + + this.getSoundById = function(sID,suppressDebug) { + if (!sID) throw new Error('SoundManager.getSoundById(): sID is null/undefined'); + var result = _s.sounds[sID]; + if (!result && !suppressDebug) { + _s._wD('"'+sID+'" is an invalid sound ID.',2); + // soundManager._wD('trace: '+arguments.callee.caller); + }; + return result; + }; + + this.onload = function() { + // window.onload() equivalent for SM2, ready to create sounds etc. + // this is a stub - you can override this in your own external script, eg. soundManager.onload = function() {} + soundManager._wD('Warning: soundManager.onload() is undefined.',2); + }; + + this.onerror = function() { + // stub for user handler, called when SM2 fails to load/init + }; + + // --- "private" methods --- + + this._idCheck = this.getSoundById; + + this._disableObject = function(o) { + for (var oProp in o) { + if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') o[oProp] = function(){return false;}; + }; + oProp = null; + }; + + this._failSafely = function() { + // exception handler for "object doesn't support this property or method" or general failure + var fpgssTitle = 'You may need to whitelist this location/domain eg. file:///C:/ or C:/ or mysite.com, or set ALWAYS ALLOW under the Flash Player Global Security Settings page. The latter is probably less-secure.'; + var flashCPL = 'view/edit'; + var FPGSS = 'FPGSS'; + if (!_s._disabled) { + _s._wD('soundManager: Failed to initialise.',2); + _s.disable(); + }; + }; + + this._normalizeMovieURL = function(smURL) { + if (smURL) { + if (smURL.match(/\.swf/)) { + smURL = smURL.substr(0,smURL.lastIndexOf('.swf')); + } + if (smURL.lastIndexOf('/') != smURL.length-1) { + smURL = smURL+'/'; + } + } + return(smURL && smURL.lastIndexOf('/')!=-1?smURL.substr(0,smURL.lastIndexOf('/')+1):'./')+_s.movieURL; + }; + + this._getDocument = function() { + return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0])); + }; + + this._getDocument._protected = true; + + this._createMovie = function(smID,smURL) { + if (_s._didAppend && _s._appendSuccess) return false; // ignore if already succeeded + if (window.location.href.indexOf('debug=1')+1) _s.debugMode = true; // allow force of debug mode via URL + _s._didAppend = true; + + // safety check for legacy (change to Flash 9 URL) + _s._setVersionInfo(); + var remoteURL = (smURL?smURL:_s.url); + var localURL = (_s.altURL?_s.altURL:remoteURL); + _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL); + smURL = _s.url; + + var htmlEmbed = ''; + var htmlObject = ''+(_s.useHighPerformance && !_s.useMovieStar?' ':'')+''; + var html = (!_s.isIE?htmlEmbed:htmlObject); + + var toggleElement = '
-
'; + var debugHTML = '
'; + var appXHTML = 'soundManager._createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.'; + + var oTarget = _s._getDocument(); + if (oTarget) { + + _s.oMC = document.getElementById('sm2-container')?document.getElementById('sm2-container'):document.createElement('div'); + if (!_s.oMC.id) { + _s.oMC.id = 'sm2-container'; + _s.oMC.className = 'movieContainer'; + // "hide" flash movie + var s = null; + if (_s.useHighPerformance) { + s = { + position: 'fixed', + width: '8px', + height: '8px', // must be at least 6px for flash to run fast. odd? yes. + bottom: '0px', + left: '0px', + zIndex:-1 // sit behind everything else + } + } else { + s = { + position: 'absolute', + width: '1px', + height: '1px', + bottom: '0px', + left: '0px' + } + } + var x = null; + for (x in s) { + _s.oMC.style[x] = s[x]; + } + try { + oTarget.appendChild(_s.oMC); + _s.oMC.innerHTML = html; + _s._appendSuccess = true; + } catch(e) { + throw new Error(appXHTML); + } + } else { + // it's already in the document. + _s.oMC.innerHTML = html; + _s._appendSuccess = true; + } + if (!document.getElementById(_s.debugID) && ((!_s._hasConsole||!_s.useConsole)||(_s.useConsole && _s._hasConsole && !_s.consoleOnly))) { + var oDebug = document.createElement('div'); + oDebug.id = _s.debugID; + oDebug.style.display = (_s.debugMode?'block':'none'); + if (_s.debugMode) { + try { + var oD = document.createElement('div'); + oTarget.appendChild(oD); + oD.innerHTML = toggleElement; + } catch(e) { + throw new Error(appXHTML); + }; + }; + oTarget.appendChild(oDebug); + }; + oTarget = null; + }; + _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s._wD?', high performance mode':'')+' --',1); + _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?'(alternate URL)':''),1); + }; + + // aliased to this._wD() + this._writeDebug = function(sText,sType,bTimestamp) { + if (!_s.debugMode) return false; + if (typeof bTimestamp != 'undefined' && bTimestamp) { + sText = sText + ' | '+new Date().getTime(); + }; + if (_s._hasConsole && _s.useConsole) { + var sMethod = _s._debugLevels[sType]; + if (typeof console[sMethod] != 'undefined') { + console[sMethod](sText); + } else { + console.log(sText); + }; + if (_s.useConsoleOnly) return true; + }; + var sDID = 'soundmanager-debug'; + try { + var o = document.getElementById(sDID); + if (!o) return false; + var oItem = document.createElement('div'); + sText = sText.replace(/\n/g,'
'); + if (typeof sType == 'undefined') { + var sType = 0; + } else { + sType = parseInt(sType); + }; + oItem.innerHTML = 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; + }; + this._writeDebug._protected = true; + this._wD = this._writeDebug; + + this._wDAlert = function(sText) { alert(sText); }; + + if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) { + _s._wD = _s._wDAlert; + }; + + this._toggleDebug = function() { + var o = document.getElementById(_s.debugID); + var oT = document.getElementById(_s.debugID+'-toggle'); + if (!o) return false; + if (_s._debugOpen) { + // minimize + oT.innerHTML = '+'; + o.style.display = 'none'; + } else { + oT.innerHTML = '-'; + o.style.display = 'block'; + }; + _s._debugOpen = !_s._debugOpen; + }; + + this._toggleDebug._protected = true; + + this._debug = function() { + _s._wD('--- soundManager._debug(): Current sound objects ---',1); + for (var i=0,j=_s.soundIDs.length; i Flash either. + soundManager.onerror(); + soundManager.disable(); + }; + + if (document.addEventListener) document.addEventListener('DOMContentLoaded',_s.domContentLoaded,false); + +}; // SoundManager() + +var soundManager = new SoundManager(); diff --git a/telemeta/htdocs/swf/soundmanager2.swf b/telemeta/htdocs/swf/soundmanager2.swf old mode 100644 new mode 100755 index 98ed98d5eb1088834f49de897b49a6d851160927..00519726828d02468772603985fb6bb39936dfe8 GIT binary patch literal 2867 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 Bx;6j+ diff --git a/telemeta/htdocs/swf/soundmanager2_flash9.swf b/telemeta/htdocs/swf/soundmanager2_flash9.swf old mode 100644 new mode 100755 index 14e45788e2deaa32b7daa420dd8b34d48d8025bb..81a7348181ba364d77b1b3d698d72be7df956290 GIT binary patch literal 8604 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 literal 8079 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 Bx;6j+ literal 0 HcmV?d00001 diff --git a/telemeta/htdocs/timeside/skins/lab/img/volume.png b/telemeta/htdocs/timeside/skins/lab/img/volume.png new file mode 100644 index 0000000000000000000000000000000000000000..fb28016447f279cdb8f6d495da47fe278502e965 GIT binary patch literal 1198 zcmeAS@N?(olHy`uVBq!ia0vp^HbA_BgAGXT;qFxjQjEnx?oJHr&dIz4a@dl*-Cck* z5d3uBT@R!<3p^r=85p>QL70(Y)*K0-AbW|YuPgg)W*H$?!H4SQLJSNndY&$hAr-gY z&fJ?P>?qRuJ}+jGY3?L(kCsnNnhi#sQxaG=6!3T+^bWXiL2;o56N{44pUys}g&{8m zxxQ#HMLl3-+A?#YM1S)7a`Wu|KtH z_k!o(NA*jv(;sQ4>ct3^SPWv=(6E47|RhYRl2h$k=ATC>V*hr@f@Qh^kA zE1=?yjlou@H@pe)d;P>kS0T8qb&81l#RrcpKgae=?JjxsWa?b4W&X)uB_&1A&3vD< zCT7V}v&+d29A2Ukx>Cm_+crPnEuk&?@{63s-NS#+ACui2`SIi|pt_JHr9Uro%gEL) z{rQu-_WR==uIFdV4X6E^zv$@EqnF|*FH28*dG2ntiLLQ!Eg3=AK$r0A)Asy-WN2>g z{`>cDk?+U8u6g}^{roQlzwQ41{=EIO*DK2lHv3DM9wn;(`|+=Lp3S{wlh0*){f~N- zRJCM&d;5I5OYPs^uh@8RiDp-2?R2@V%fEiRTCAj$wZ^>DIeyKDts!Cgac}1B>t7w0 zxb}MWd87C4fg!6trOwmd9d>bZ@=Al%>z?k=I&-ohp!dh)$H}P`iHV95SAy1GKR8WG ze}gIr0+Cv^M9xZ&1n+qpmKv=Ri8fkiV7@Ko&c_GGrkznf+oL^3bebd}2Cgu<1RM6WSLuc~Ubl;m3_$iGdb z>EQyUwXEA%fN%-Rwj(M0&AOtTIhkj2PA=P%;(bo*O_#3a>xvyo-tUy&cIfWx-lDwi ziO!{UHzsZN*q!7(xx?g!5EKTfYOi747V?#=*hnTsSuRJD<*=h`6gSvnPtKgqlX7g) zT0%E2apatwI%lJ*zIM)J-O8IEH=LaIr)P`nwkPRJbT_H$E9U}5B{OH|oGe{(aM}SV z)QU{h-LQ03_>9SkS1$wIzwE#?Cqb~ilYrJww&mFtqOxJB%(f?s*KATP6E#cqeq$xK zET=Pm3GYpz{T|Xl!HFP2rQB1~Zn*yX7N%W%>9V`^-<(dB*<9I&6TB0=C7Ggu1}C&` mJuq!mT%uoFsK2(swlDI!M%uRNeMgN!C5@-6pUXO@geCw(2^!)6 literal 0 HcmV?d00001 diff --git a/telemeta/htdocs/timeside/skins/lab/style.css b/telemeta/htdocs/timeside/skins/lab/style.css index 003f5a66..abc95433 100755 --- a/telemeta/htdocs/timeside/skins/lab/style.css +++ b/telemeta/htdocs/timeside/skins/lab/style.css @@ -71,6 +71,13 @@ background-position: 0 -28px; } +.ts-volume { + background-image: url('img/volume.png'); + background-repeat: no-repeat; + background-position: 0px 0px !important; + width:160px !important; +} + .ts-skin-lab .ts-player .ts-control .ts-playback .ts-play { background-image: url('img/play.png'); } diff --git a/telemeta/htdocs/timeside/src/player.js b/telemeta/htdocs/timeside/src/player.js index 02179f74..b120cac9 100644 --- a/telemeta/htdocs/timeside/src/player.js +++ b/telemeta/htdocs/timeside/src/player.js @@ -18,8 +18,8 @@ TimeSide(function($N, $J) { }, 'div.control': { 'div.layout': { - 'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker'] - //,'input.textMarker'] + 'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker' //] + ,'a.volume'] } }/*, 'div.marker-control': ['a.set-marker']*/ @@ -106,7 +106,14 @@ TimeSide(function($N, $J) { }); this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause)); this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay)); - + // + this.elements.volume.attr('href', '#').bind('mousedown', this.attach( + function(e){ + this.changeVolume(e); + } + )); + + //assigning title string to all anchors??????? this.elements.control.find('a').add(this.elements.setMarker) .attr('href', '#') @@ -144,7 +151,7 @@ TimeSide(function($N, $J) { .observe('move', this.forwardEvent) .draw(); this.refreshImage(); - this.resize(); + //this.resize(); //will be called in Timeside.load. var resizeTimer = null; $J(window).resize(this.attach(function() { if (resizeTimer){ @@ -152,6 +159,8 @@ TimeSide(function($N, $J) { } resizeTimer = setTimeout(this.attach(this.resize), 100); })); + //_updateVolumeChanged(this.soundProvider.getVolume()); + this.soundProvider.observe('volume',this.onVolumeChanged); //this.container.resize(this.attach(this.resize)); // Can loop ? }, @@ -250,6 +259,38 @@ TimeSide(function($N, $J) { return false; }, + changeVolume: function(event){ + var ticks = [18,26,33,40,47]; + var vol = event.layerX; + for(var i=0; i').html('Ok')); + p.show(jQuery('
').html('Ok')); setTimeout(function(){p.hide()},600); }); } diff --git a/telemeta/htdocs/timeside/src/soundprovider.js b/telemeta/htdocs/timeside/src/soundprovider.js index f0789913..621d81a0 100644 --- a/telemeta/htdocs/timeside/src/soundprovider.js +++ b/telemeta/htdocs/timeside/src/soundprovider.js @@ -52,11 +52,28 @@ TimeSide(function($N) { }, pause: function() { - if (this.sound) + if (this.sound){ this.sound.pause(); + } + return this; + }, + + setVolume: function(volume) { + if(typeof volume != 'number'){ + return this; + } + volume = volume<0 ? 0 : volume >100 ? 100 : parseInt(volume); + if (this.sound && this.sound.volume!==volume){ + this.sound.setVolume(volume); + } + this.fire('volume',{'volume':volume}); return this; }, + getVolume: function() { + return this.sound.volume; + }, + seek: function(offset) { if (this.sound) { this.sound.setPosition(offset * 1000); diff --git a/telemeta/templates/telemeta_default/base.html b/telemeta/templates/telemeta_default/base.html index 3873624f..50836abc 100644 --- a/telemeta/templates/telemeta_default/base.html +++ b/telemeta/templates/telemeta_default/base.html @@ -61,7 +61,7 @@
-{% trans "Search" %}
diff --git a/telemeta/templates/telemeta_default/collection_add.html b/telemeta/templates/telemeta_default/collection_add.html index 4d3ae9f9..6d0c0bbf 100644 --- a/telemeta/templates/telemeta_default/collection_add.html +++ b/telemeta/templates/telemeta_default/collection_add.html @@ -5,7 +5,7 @@ {% block submenu %}
{% block tools %} - {% trans "Cancel" %} + {% trans "Cancel" %} {% endblock tools %}
{% endblock %} @@ -25,8 +25,8 @@ {% endfor %} diff --git a/telemeta/templates/telemeta_default/collection_detail.html b/telemeta/templates/telemeta_default/collection_detail.html index a273a14b..1dd57e01 100644 --- a/telemeta/templates/telemeta_default/collection_detail.html +++ b/telemeta/templates/telemeta_default/collection_detail.html @@ -20,16 +20,16 @@ {% block submenu %}
{% block tools %} - Dublin Core + Dublin Core {% if user.is_authenticated and perms.telemeta.change_mediacollection %} - {% trans "Edit" %} - {% trans "Copy" %} + {% trans "Edit" %} + {% trans "Copy" %} {% endif %} {% if user.is_authenticated %} - {% trans "Add to playlist" %} + {% trans "Add to playlist" %} diff --git a/telemeta/templates/telemeta_default/collection_edit.html b/telemeta/templates/telemeta_default/collection_edit.html index 4ff14051..fd7eeb89 100644 --- a/telemeta/templates/telemeta_default/collection_edit.html +++ b/telemeta/templates/telemeta_default/collection_edit.html @@ -3,7 +3,7 @@ {% load telemeta_utils %} {% block tools %} - {% trans "Cancel" %} + {% trans "Cancel" %} {% endblock %} {% block infos %} @@ -20,8 +20,8 @@ {% endfor %} diff --git a/telemeta/templates/telemeta_default/collection_list.html b/telemeta/templates/telemeta_default/collection_list.html index 5f795a0c..8fd8ae22 100644 --- a/telemeta/templates/telemeta_default/collection_list.html +++ b/telemeta/templates/telemeta_default/collection_list.html @@ -7,7 +7,7 @@ {% block submenu %}
{% if user.is_authenticated and perms.telemeta.add_mediacollection %} - {% trans "Add" %} + {% trans "Add" %} {% endif %}
{% endblock %} diff --git a/telemeta/templates/telemeta_default/geo_continents.html b/telemeta/templates/telemeta_default/geo_continents.html index c7720afb..8bca2319 100644 --- a/telemeta/templates/telemeta_default/geo_continents.html +++ b/telemeta/templates/telemeta_default/geo_continents.html @@ -19,8 +19,8 @@ var resourceMap = new ResourceMap('.continents', { {% block submenu %}
{% if continents %} - {% trans "Map" %} | - {% trans "List" %} + {% trans "Map" %} | + {% trans "List" %} {% endif %}
{% endblock %} diff --git a/telemeta/templates/telemeta_default/home.html b/telemeta/templates/telemeta_default/home.html index 12da88e6..eeaa08bf 100644 --- a/telemeta/templates/telemeta_default/home.html +++ b/telemeta/templates/telemeta_default/home.html @@ -63,14 +63,15 @@

{% trans "Playlists" %}

- + {% trans "Add" %} {% for playlist in playlists %}

{{ playlist.playlist.title }}

- CSV - {% trans "Delete" %} - +
@@ -118,7 +119,7 @@ {% endif %} - {% trans "Delete" %} + {% trans "Delete" %} {% endfor %} diff --git a/telemeta/templates/telemeta_default/login.html b/telemeta/templates/telemeta_default/login.html index 1569d0b3..6997ae68 100644 --- a/telemeta/templates/telemeta_default/login.html +++ b/telemeta/templates/telemeta_default/login.html @@ -17,7 +17,7 @@ {{ form.password }}

- diff --git a/telemeta/templates/telemeta_default/mediaitem_add.html b/telemeta/templates/telemeta_default/mediaitem_add.html index 0f72f3c1..b85621be 100644 --- a/telemeta/templates/telemeta_default/mediaitem_add.html +++ b/telemeta/templates/telemeta_default/mediaitem_add.html @@ -11,7 +11,7 @@ {% if perms.telemeta.add_mediaitem %} {% block tools %} {% trans "Cancel" %} + class="component_icon button icon_cancel">{% trans "Cancel" %} {% endblock tools %} {% endif %} @@ -36,8 +36,8 @@ diff --git a/telemeta/templates/telemeta_default/mediaitem_copy.html b/telemeta/templates/telemeta_default/mediaitem_copy.html index 6c7e9f6f..e4036188 100644 --- a/telemeta/templates/telemeta_default/mediaitem_copy.html +++ b/telemeta/templates/telemeta_default/mediaitem_copy.html @@ -11,7 +11,7 @@
{% if user.is_authenticated and perms.telemeta.add_mediaitem %} {% block tools %} - {% trans "Cancel" %} + {% trans "Cancel" %} {% endblock tools %} {% endif %}
@@ -34,8 +34,8 @@ {% endfor %} diff --git a/telemeta/templates/telemeta_default/mediaitem_detail.html b/telemeta/templates/telemeta_default/mediaitem_detail.html index ab8665d3..61a96d53 100644 --- a/telemeta/templates/telemeta_default/mediaitem_detail.html +++ b/telemeta/templates/telemeta_default/mediaitem_detail.html @@ -24,6 +24,7 @@ soundManager.debugMode = false; set_player_image_url('{% url telemeta-item-visualize item.public_id,visualizer_id,"WIDTH","HEIGHT" %}'); load_player({{ item.approx_duration.as_seconds }}); + jQuery(document).ready(function(){ var content = $('#_popup_add_to_playlist').clone(true,true); $('#_add_to_playlist').click(function(e){return popup.show(content,e)}); @@ -37,17 +38,17 @@ {% block submenu %}
{% block tools %} - Dublin Core + Dublin Core {% if user.is_authenticated and perms.telemeta.change_mediaitem %} - {% trans "Edit" %} - {% trans "Copy" %} + {% trans "Edit" %} + {% trans "Copy" %} {% endif %} {% if user.is_authenticated %} - {% trans "Add to playlist" %} + {% trans "Add to playlist" %} @@ -55,8 +56,8 @@ {% endif %} - {% trans "Previous" %} - {% trans "Next" %} + {% trans "Previous" %} + {% trans "Next" %} {% endblock tools %}
{% endblock %} diff --git a/telemeta/templates/telemeta_default/mediaitem_edit.html b/telemeta/templates/telemeta_default/mediaitem_edit.html index a37e48e5..b53fe78c 100644 --- a/telemeta/templates/telemeta_default/mediaitem_edit.html +++ b/telemeta/templates/telemeta_default/mediaitem_edit.html @@ -3,7 +3,7 @@ {% load telemeta_utils %} {% block tools %} - {% trans "Cancel" %} + {% trans "Cancel" %} {% endblock tools %} {% block infos %} @@ -27,8 +27,8 @@ diff --git a/telemeta/templates/telemeta_default/mediaitem_list.html b/telemeta/templates/telemeta_default/mediaitem_list.html index 43f91c04..40155f96 100644 --- a/telemeta/templates/telemeta_default/mediaitem_list.html +++ b/telemeta/templates/telemeta_default/mediaitem_list.html @@ -8,7 +8,7 @@ {% block submenu %}
{% if user.is_authenticated and perms.telemeta.add_mediaitem %} - {% trans "Add" %} + {% trans "Add" %} {% endif %}
{% endblock %} -- 2.39.5