1/*! 2 SoundManager 2: Javascript Sound for the Web 3 -------------------------------------------- 4 http://schillmania.com/projects/soundmanager2/ 5 6 Copyright (c) 2008, Scott Schiller. All rights reserved. 7 Code licensed under the BSD License: 8 http://schillmania.com/projects/soundmanager2/license.txt 9 10 V2.93a.20090117 11*/ 12 13var soundManager = null; 14 15function SoundManager(smURL,smID) { 16 17 this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9. 18 this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available + configured) 19 this.useConsole = true; // use firebug/safari console.log()-type debug console if available 20 this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug 21 this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload() 22 this.nullURL = 'null.mp3'; // path to "null" (empty) MP3 file, used to unload sounds (Flash 8 only) 23 this.allowPolling = true; // allow flash to poll for status update (required for "while playing", peak, sound spectrum functions to work.) 24 this.useMovieStar = false; // enable support for Flash 9.0r115+ (codename "MovieStar") MPEG4 audio + video formats (AAC, M4V, FLV, MOV etc.) 25 this.bgColor = '#ffffff'; // movie (.swf) background color, useful if showing on-screen for video etc. 26 this.useHighPerformance = true; // position:fixed flash movie gives increased js/flash speed, but buggy and disabled for firefox/win32 by default (set value to 'always' to override) 27 28 this.defaultOptions = { 29 '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) 30 'stream': true, // allows playing before entire file has loaded (recommended) 31 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true) 32 'onid3': null, // callback function for "ID3 data is added/available" 33 'onload': null, // callback function for "load finished" 34 'whileloading': null, // callback function for "download progress update" (X of Y bytes received) 35 'onplay': null, // callback for "play" start 36 'onpause': null, // callback for "pause" 37 'onresume': null, // callback for "resume" (pause toggle) 38 'whileplaying': null, // callback during play (position update) 39 'onstop': null, // callback for "user stop" 40 'onfinish': null, // callback function for "sound finished playing" 41 'onbeforefinish': null, // callback for "before sound finished playing (at [time])" 42 'onbeforefinishtime': 5000, // offset (milliseconds) before end of sound to trigger beforefinish (eg. 1000 msec = 1 second) 43 'onbeforefinishcomplete':null, // function to call when said sound finishes playing 44 'onjustbeforefinish':null, // callback for [n] msec before end of current sound 45 'onjustbeforefinishtime':200, // [n] - if not using, set to 0 (or null handler) and event will not fire. 46 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time 47 'position': null, // offset (milliseconds) to seek to within loaded sound data. 48 'pan': 0, // "pan" settings, left-to-right, -100 to 100 49 'volume': 100 // self-explanatory. 0-100, the latter being the max. 50 }; 51 52 this.flash9Options = { // flash 9-only options, merged into defaultOptions if flash 9 is being used 53 'isMovieStar': null, // "MovieStar" MPEG4 audio/video mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL 54 'usePeakData': false, // enable left/right channel peak (level) data 55 'useWaveformData': false, // enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire. 56 'useEQData': false // enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive. 57 }; 58 59 this.movieStarOptions = { // flash 9.0r115+ MPEG4 audio/video options, merged into defaultOptions if flash 9 + movieStar mode is enabled 60 'onmetadata': null, // callback for when video width/height etc. are received 61 'useVideo': false // if loading movieStar content, whether to show video 62 }; 63 64 // jslint global declarations 65 /*global sm2Debugger, alert, console, document, navigator, setTimeout, window */ 66 67 var SMSound = null; // defined later 68 69 var _s = this; 70 this.version = null; 71 this.versionNumber = 'V2.93a.20090117'; 72 this.movieURL = null; 73 this.url = null; 74 this.altURL = null; 75 this.swfLoaded = false;
76 this.enabled = false; 77 this.o = null; 78 this.id = (smID||'sm2movie'); 79 this.oMC = null; 80 this.sounds = {}; 81 this.soundIDs = []; 82 this.muted = false; 83 this.isIE = (navigator.userAgent.match(/MSIE/i)); 84 this.isSafari = (navigator.userAgent.match(/safari/i)); 85 this.isGecko = (navigator.userAgent.match(/gecko/i)); 86 this.debugID = 'soundmanager-debug'; 87 this._debugOpen = true; 88 this._didAppend = false; 89 this._appendSuccess = false; 90 this._didInit = false; 91 this._disabled = false; 92 this._windowLoaded = false; 93 this._hasConsole = (typeof console != 'undefined' && typeof console.log != 'undefined'); 94 this._debugLevels = ['log','info','warn','error']; 95 this._defaultFlashVersion = 8; 96 97 this.filePatterns = { 98 flash8: /\.mp3(\?.*)?$/i, 99 flash9: /\.mp3(\?.*)?$/i 100 }; 101 102 this.netStreamTypes = ['aac','flv','mov','mp4','m4v','f4v','m4a','mp4v','3gp','3g2']; // Flash v9.0r115+ "moviestar" formats 103 this.netStreamPattern = new RegExp('\\.('+this.netStreamTypes.join('|')+')(\\?.*)?$','i'); 104 105 this.filePattern = null; 106 this.features = { 107 peakData: false, 108 waveformData: false, 109 eqData: false, 110 movieStar: false 111 }; 112 113 this.sandbox = { 114 'type': null, 115 'types': { 116 'remote': 'remote (domain-based) rules', 117 'localWithFile': 'local with file access (no internet access)', 118 'localWithNetwork': 'local with network (internet access only, no local access)', 119 'localTrusted': 'local, trusted (local + internet access)' 120 }, 121 'description': null, 122 'noRemote': null, 123 'noLocal': null 124 }; 125 126 this._setVersionInfo = function() { 127 if (_s.flashVersion != 8 && _s.flashVersion != 9) { 128 alert('soundManager.flashVersion must be 8 or 9. "'+_s.flashVersion+'" is invalid. Reverting to '+_s._defaultFlashVersion+'.'); 129 _s.flashVersion = _s._defaultFlashVersion; 130 } 131 _s.version = _s.versionNumber+(_s.flashVersion==9?' (AS3/Flash 9)':' (AS2/Flash 8)'); 132 // set up default options 133 if (_s.flashVersion > 8) { 134 _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.flash9Options); 135 } 136 if (_s.flashVersion > 8 && _s.useMovieStar) { 137 // flash 9+ support for movieStar formats as well as MP3 138 _s.defaultOptions = _s._mergeObjects(_s.defaultOptions,_s.movieStarOptions); 139 _s.filePatterns.flash9 = new RegExp('\\.(mp3|'+_s.netStreamTypes.join('|')+')(\\?.*)?$','i'); 140 _s.features.movieStar = true; 141 } else { 142 _s.useMovieStar = false; 143 _s.features.movieStar = false; 144 } 145 _s.filePattern = _s.filePatterns[(_s.flashVersion!=8?'flash9':'flash8')]; 146 _s.movieURL = (_s.flashVersion==8?'soundmanager2.swf':'soundmanager2_flash9.swf'); 147 _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_s.flashVersion==9); 148 }; 149 150 this._overHTTP = (document.location?document.location.protocol.match(/http/i):null); 151 this._waitingforEI = false; 152 this._initPending = false; 153 this._tryInitOnFocus = (this.isSafari && typeof document.hasFocus == 'undefined'); 154 this._isFocused = (typeof document.hasFocus != 'undefined'?document.hasFocus():null); 155 this._okToDisable = !this._tryInitOnFocus; 156 157 this.useAltURL = !this._overHTTP; // use altURL if not "online" 158 159 var flashCPLink = 'http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html'; 160 161 // --- public methods --- 162 163 this.supported = function() { 164 return (_s._didInit && !_s._disabled); 165 }; 166 167 this.getMovie = function(smID) { 168 return _s.isIE?window[smID]:(_s.isSafari?document.getElementById(smID)||document[smID]:document.getElementById(smID)); 169 }; 170 171 this.loadFromXML = function(sXmlUrl) { 172 try { 173 _s.o._loadFromXML(sXmlUrl); 174 } catch(e) { 175 _s._failSafely(); 176 return true; 177 } 178 }; 179 180 this.createSound = function(oOptions) { 181 if (!_s._didInit) { 182 throw new Error('soundManager.createSound(): Not loaded yet - wait for soundManager.onload() before calling sound-related methods'); 183 } 184 if (arguments.length == 2) { 185 // function overloading in JS! :) ..assume simple createSound(id,url) use case 186 oOptions = {'id':arguments[0],'url':arguments[1]}; 187 } 188 var thisOptions = _s._mergeObjects(oOptions); // inherit SM2 defaults 189 var _tO = thisOptions; // alias 190 _s._wD('soundManager.createSound(): '+_tO.id+' ('+_tO.url+')',1); 191 if (_s._idCheck(_tO.id,true)) { 192 _s._wD('soundManager.createSound(): '+_tO.id+' exists',1); 193 return _s.sounds[_tO.id]; 194 } 195 if (_s.flashVersion > 8 && _s.useMovieStar) { 196 if (_tO.isMovieStar === null) { 197 _tO.isMovieStar = (_tO.url.match(_s.netStreamPattern)?true:false); 198 } 199 if (_tO.isMovieStar) { 200 _s._wD('soundManager.createSound(): using MovieStar handling'); 201 } 202 if (_tO.isMovieStar && (_tO.usePeakData || _tO.useWaveformData || _tO.useEQData)) { 203 _s._wD('Warning: peak/waveform/eqData features unsupported for non-MP3 formats'); 204 _tO.usePeakData = false;
205 _tO.useWaveformData = false; 206 _tO.useEQData = false; 207 } 208 } 209 _s.sounds[_tO.id] = new SMSound(_tO); 210 _s.soundIDs[_s.soundIDs.length] = _tO.id; 211 // AS2: 212 if (_s.flashVersion == 8) { 213 _s.o._createSound(_tO.id,_tO.onjustbeforefinishtime); 214 } else { 215 _s.o._createSound(_tO.id,_tO.url,_tO.onjustbeforefinishtime,_tO.usePeakData,_tO.useWaveformData,_tO.useEQData,_tO.isMovieStar,(_tO.isMovieStar?_tO.useVideo:false)); 216 } 217 if (_tO.autoLoad || _tO.autoPlay) { 218 // TODO: does removing timeout here cause problems? 219 if (_s.sounds[_tO.id]) { 220 _s.sounds[_tO.id].load(_tO); 221 } 222 } 223 if (_tO.autoPlay) { 224 _s.sounds[_tO.id].play(); 225 } 226 return _s.sounds[_tO.id]; 227 }; 228 229 this.createVideo = function(oOptions) { 230 if (arguments.length==2) { 231 oOptions = {'id':arguments[0],'url':arguments[1]}; 232 } 233 if (_s.flashVersion >= 9) { 234 oOptions.isMovieStar = true; 235 oOptions.useVideo = true; 236 } else { 237 _s._wD('soundManager.createVideo(): flash 9 required for video. Exiting.',2); 238 return false; 239 } 240 if (!_s.useMovieStar) { 241 _s._wD('soundManager.createVideo(): MovieStar mode not enabled. Exiting.',2); 242 } 243 return _s.createSound(oOptions); 244 }; 245 246 this.destroySound = function(sID,bFromSound) { 247 // explicitly destroy a sound before normal page unload, etc. 248 if (!_s._idCheck(sID)) { 249 return false; 250 } 251 for (var i=0; i<_s.soundIDs.length; i++) { 252 if (_s.soundIDs[i] == sID) { 253 _s.soundIDs.splice(i,1); 254 continue; 255 } 256 } 257 // conservative option: avoid crash with ze flash 8 258 // calling destroySound() within a sound onload() might crash firefox, certain flavours of winXP + flash 8?? 259 // if (_s.flashVersion != 8) { 260 _s.sounds[sID].unload(); 261 // } 262 if (!bFromSound) { 263 // ignore if being called from SMSound instance 264 _s.sounds[sID].destruct(); 265 } 266 delete _s.sounds[sID]; 267 }; 268 269 this.destroyVideo = this.destroySound; 270 271 this.load = function(sID,oOptions) { 272 if (!_s._idCheck(sID)) { 273 return false; 274 } 275 _s.sounds[sID].load(oOptions); 276 }; 277 278 this.unload = function(sID) { 279 if (!_s._idCheck(sID)) { 280 return false; 281 } 282 _s.sounds[sID].unload(); 283 }; 284 285 this.play = function(sID,oOptions) { 286 if (!_s._idCheck(sID)) { 287 if (typeof oOptions != 'Object') { 288 oOptions = {url:oOptions}; // overloading use case: play('mySound','/path/to/some.mp3'); 289 } 290 if (oOptions && oOptions.url) { 291 // overloading use case, creation + playing of sound: .play('someID',{url:'/path/to.mp3'}); 292 _s._wD('soundController.play(): attempting to create "'+sID+'"',1); 293 oOptions.id = sID; 294 _s.createSound(oOptions); 295 } else { 296 return false; 297 } 298 } 299 _s.sounds[sID].play(oOptions); 300 }; 301 302 this.start = this.play; // just for convenience 303 304 this.setPosition = function(sID,nMsecOffset) { 305 if (!_s._idCheck(sID)) { 306 return false; 307 } 308 _s.sounds[sID].setPosition(nMsecOffset); 309 }; 310 311 this.stop = function(sID) { 312 if (!_s._idCheck(sID)) { 313 return false; 314 } 315 _s._wD('soundManager.stop('+sID+')',1); 316 _s.sounds[sID].stop(); 317 }; 318 319 this.stopAll = function() { 320 _s._wD('soundManager.stopAll()',1); 321 for (var oSound in _s.sounds) { 322 if (_s.sounds[oSound] instanceof SMSound) { 323 _s.sounds[oSound].stop(); // apply only to sound objects 324 } 325 } 326 }; 327 328 this.pause = function(sID) { 329 if (!_s._idCheck(sID)) { 330 return false; 331 } 332 _s.sounds[sID].pause(); 333 }; 334 335 this.pauseAll = function() { 336 for (var i=_s.soundIDs.length; i--;) { 337 _s.sounds[_s.soundIDs[i]].pause(); 338 } 339 }; 340 341 this.resume = function(sID) { 342 if (!_s._idCheck(sID)) { 343 return false; 344 } 345 _s.sounds[sID].resume(); 346 }; 347 348 this.resumeAll = function() { 349 for (var i=_s.soundIDs.length; i--;) { 350 _s.sounds[_s.soundIDs[i]].resume(); 351 } 352 }; 353 354 this.togglePause = function(sID) { 355 if (!_s._idCheck(sID)) { 356 return false; 357 } 358 _s.sounds[sID].togglePause(); 359 }; 360 361 this.setPan = function(sID,nPan) { 362 if (!_s._idCheck(sID)) { 363 return false;
364 } 365 _s.sounds[sID].setPan(nPan); 366 }; 367 368 this.setVolume = function(sID,nVol) { 369 if (!_s._idCheck(sID)) { 370 return false; 371 } 372 _s.sounds[sID].setVolume(nVol); 373 }; 374 375 this.mute = function(sID) { 376 if (typeof sID != 'string') { 377 sID = null; 378 } 379 if (!sID) { 380 _s._wD('soundManager.mute(): Muting all sounds'); 381 for (var i=_s.soundIDs.length; i--;) { 382 _s.sounds[_s.soundIDs[i]].mute(); 383 } 384 _s.muted = true; 385 } else { 386 if (!_s._idCheck(sID)) { 387 return false; 388 } 389 _s._wD('soundManager.mute(): Muting "'+sID+'"'); 390 _s.sounds[sID].mute(); 391 } 392 }; 393 394 this.muteAll = function() { 395 _s.mute(); 396 }; 397 398 this.unmute = function(sID) { 399 if (typeof sID != 'string') { 400 sID = null; 401 } 402 if (!sID) { 403 _s._wD('soundManager.unmute(): Unmuting all sounds'); 404 for (var i=_s.soundIDs.length; i--;) { 405 _s.sounds[_s.soundIDs[i]].unmute(); 406 } 407 _s.muted = false; 408 } else { 409 if (!_s._idCheck(sID)) { 410 return false; 411 } 412 _s._wD('soundManager.unmute(): Unmuting "'+sID+'"'); 413 _s.sounds[sID].unmute(); 414 } 415 }; 416 417 this.unmuteAll = function() { 418 _s.unmute(); 419 }; 420 421 this.getMemoryUse = function() { 422 if (_s.flashVersion == 8) { 423 // not supported in Flash 8 424 return 0; 425 } 426 if (_s.o) { 427 return parseInt(_s.o._getMemoryUse(),10); 428 } 429 }; 430 431 this.setPolling = function(bPolling) { 432 if (!_s.o || !_s.allowPolling) { 433 return false; 434 } 435 // _s._wD('soundManager.setPolling('+bPolling+')'); 436 _s.o._setPolling(bPolling); 437 }; 438 439 this.disable = function(bUnload) { 440 // destroy all functions 441 if (_s._disabled) { 442 return false; 443 } 444 _s._disabled = true; 445 _s._wD('soundManager.disable(): Disabling all functions - future calls will return false.',1); 446 for (var i=_s.soundIDs.length; i--;) { 447 _s._disableObject(_s.sounds[_s.soundIDs[i]]); 448 } 449 _s.initComplete(); // fire "complete", despite fail 450 _s._disableObject(_s); 451 }; 452 453 this.canPlayURL = function(sURL) { 454 return (sURL?(sURL.match(_s.filePattern)?true:false):null); 455 }; 456 457 this.getSoundById = function(sID,suppressDebug) { 458 if (!sID) { 459 throw new Error('SoundManager.getSoundById(): sID is null/undefined'); 460 } 461 var result = _s.sounds[sID]; 462 if (!result && !suppressDebug) { 463 _s._wD('"'+sID+'" is an invalid sound ID.',2); 464 // soundManager._wD('trace: '+arguments.callee.caller); 465 } 466 return result; 467 }; 468 469 this.onload = function() { 470 // window.onload() equivalent for SM2, ready to create sounds etc. 471 // this is a stub - you can override this in your own external script, eg. soundManager.onload = function() {} 472 soundManager._wD('<em>Warning</em>: soundManager.onload() is undefined.',2); 473 }; 474 475 this.onerror = function() { 476 // stub for user handler, called when SM2 fails to load/init 477 }; 478 479 // --- "private" methods --- 480 481 this._idCheck = this.getSoundById; 482 483 var _doNothing = function() { 484 return false; 485 }; 486 _doNothing._protected = true; 487 488 this._disableObject = function(o) { 489 for (var oProp in o) { 490 if (typeof o[oProp] == 'function' && typeof o[oProp]._protected == 'undefined') { 491 o[oProp] = _doNothing; 492 } 493 } 494 oProp = null; 495 }; 496 497 this._failSafely = function() { 498 // exception handler for "object doesn't support this property or method" or general failure 499 if (!_s._disabled) { 500 _s._wD('soundManager: Failed to initialise.',2); 501 _s.disable(); 502 } 503 }; 504 505 this._normalizeMovieURL = function(smURL) { 506 var urlParams = null; 507 if (smURL) { 508 if (smURL.match(/\.swf(\?.*)?$/i)) { 509 urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?')+4); 510 if (urlParams) { 511 return smURL; // assume user knows what they're doing 512 } 513 } else if (smURL.lastIndexOf('/') != smURL.length-1) { 514 smURL = smURL+'/'; 515 } 516 } 517 return(smURL && smURL.lastIndexOf('/')!=-1?smURL.substr(0,smURL.lastIndexOf('/')+1):'./')+_s.movieURL; 518 }; 519 520 this._getDocument = function() { 521 return (document.body?document.body:(document.documentElement?document.documentElement:document.getElementsByTagName('div')[0])); 522 }; 523 524 this._getDocument._protected = true; 525 526 this._createMovie = function(smID,smURL) { 527 if (_s._didAppend && _s._appendSuccess) { 528 return false; // ignore if already succeeded 529 } 530 if (window.location.href.indexOf('debug=1')+1) { 531 _s.debugMode = true; // allow force of debug mode via URL 532 } 533 _s._didAppend = true; 534 535 // safety check for legacy (change to Flash 9 URL) 536 _s._setVersionInfo(); 537 var remoteURL = (smURL?smURL:_s.url); 538 var localURL = (_s.altURL?_s.altURL:remoteURL); 539 _s.url = _s._normalizeMovieURL(_s._overHTTP?remoteURL:localURL); 540 smURL = _s.url; 541 542 var specialCase = null; 543 if (_s.useHighPerformance && _s.useHighPerformance != 'always' && navigator.platform.match(/win32/i) && navigator.userAgent.match(/firefox/i)) { 544 specialCase = 'Note: disabling highPerformance, known issues with this browser/OS combo.'; 545 _s.useHighPerformance = false;
546 } 547 548 if (_s.useHighPerformance && _s.useMovieStar) { 549 specialCase = 'Note: disabling highPerformance, not applicable with movieStar mode on'; 550 _s.useHighPerformance = false; 551 } 552 553 var oEmbed = { 554 name: smID, 555 id: smID, 556 src: smURL, 557 width: '100%', 558 height: '100%', 559 quality: 'high', 560 allowScriptAccess: 'always', 561 bgcolor: _s.bgColor, 562 pluginspage: 'http://www.macromedia.com/go/getflashplayer', 563 type: 'application/x-shockwave-flash' 564 }; 565 566 var oObject = { 567 id: smID, 568 data: smURL, 569 type: 'application/x-shockwave-flash', 570 width: '100%', 571 height: '100%' 572 }; 573 574 var oObjectParams = { 575 movie: smURL, 576 AllowScriptAccess: 'always', 577 quality: 'high', 578 bgcolor: _s.bgColor 579 }; 580 581 if (_s.useHighPerformance && !_s.useMovieStar) { 582 oEmbed.wmode = 'transparent'; 583 oObjectParams.wmode = 'transparent'; 584 } 585 586 var oMovie = null; 587 var tmp = null; 588 589 if (_s.isIE) { 590 // IE is "special". 591 oMovie = document.createElement('div'); 592 var movieHTML = '<object id="'+smID+'" data="'+smURL+'" type="application/x-shockwave-flash" width="100%" height="100%"><param name="movie" value="'+smURL+'" /><param name="AllowScriptAccess" value="always" /><param name="quality" value="high" />'+(_s.useHighPerformance && !_s.useMovieStar?'<param name="wmode" value="transparent" /> ':'')+'<param name="bgcolor" value="'+_s.bgColor+'" /><!-- --></object>'; 593 } else { 594 oMovie = document.createElement('embed'); 595 for (tmp in oEmbed) { 596 if (oEmbed.hasOwnProperty(tmp)) { 597 oMovie.setAttribute(tmp,oEmbed[tmp]); 598 } 599 } 600 } 601 602 var oD = document.createElement('div'); 603 oD.id = _s.debugID+'-toggle'; 604 var oToggle = { 605 position: 'fixed', 606 bottom: '0px', 607 right: '0px', 608 width: '1.2em', 609 height: '1.2em', 610 lineHeight: '1.2em', 611 margin: '2px', 612 textAlign: 'center', 613 border: '1px solid #999', 614 cursor: 'pointer', 615 background: '#fff', 616 color: '#333', 617 zIndex: 10001 618 }; 619 620 oD.appendChild(document.createTextNode('-')); 621 oD.onclick = _s._toggleDebug; 622 oD.title = 'Toggle SM2 debug console'; 623 624 if (navigator.userAgent.match(/msie 6/i)) { 625 oD.style.position = 'absolute'; 626 oD.style.cursor = 'hand'; 627 } 628 629 for (tmp in oToggle) { 630 if (oToggle.hasOwnProperty(tmp)) { 631 oD.style[tmp] = oToggle[tmp]; 632 } 633 } 634 635 var appXHTML = 'soundManager._createMovie(): appendChild/innerHTML set failed. May be app/xhtml+xml DOM-related.'; 636 637 var oTarget = _s._getDocument(); 638 639 if (oTarget) { 640 641 _s.oMC = document.getElementById('sm2-container')?document.getElementById('sm2-container'):document.createElement('div'); 642 643 if (!_s.oMC.id) { 644 _s.oMC.id = 'sm2-container'; 645 _s.oMC.className = 'movieContainer'; 646 // "hide" flash movie 647 var s = null; 648 var oEl = null; 649 if (_s.useHighPerformance) { 650 s = { 651 position: 'fixed', 652 width: '8px', 653 height: '8px', // must be at least 6px for flash to run fast. odd? yes. 654 bottom: '0px', 655 left: '0px', 656 zIndex:-1 // sit behind everything else 657 }; 658 } else { 659 s = { 660 position: 'absolute', 661 width: '1px', 662 height: '1px', 663 bottom: '0px', 664 left: '0px' 665 }; 666 } 667 var x = null; 668 for (x in s) { 669 if (s.hasOwnProperty(x)) { 670 _s.oMC.style[x] = s[x]; 671 } 672 } 673 try { 674 if (!_s.isIE) { 675 _s.oMC.appendChild(oMovie); 676 } 677 oTarget.appendChild(_s.oMC); 678 if (_s.isIE) { 679 oEl = _s.oMC.appendChild(document.createElement('div')); 680 oEl.className = 'sm2-object-box'; 681 oEl.innerHTML = movieHTML; 682 } 683 _s._appendSuccess = true; 684 } catch(e) { 685 throw new Error(appXHTML); 686 } 687 } else { 688 // it's already in the document. 689 _s.oMC.appendChild(oMovie); 690 if (_s.isIE) { 691 oEl = _s.oMC.appendChild(document.createElement('div')); 692 oEl.className = 'sm2-object-box'; 693 oEl.innerHTML = movieHTML; 694 } 695 _s._appendSuccess = true; 696 } 697 698 if (!document.getElementById(_s.debugID) && ((!_s._hasConsole||!_s.useConsole)||(_s.useConsole && _s._hasConsole && !_s.consoleOnly))) { 699 var oDebug = document.createElement('div'); 700 oDebug.id = _s.debugID; 701 oDebug.style.display = (_s.debugMode?'block':'none'); 702 if (_s.debugMode) { 703 try { 704 oTarget.appendChild(oD); 705 } catch(e2) { 706 throw new Error(appXHTML); 707 } 708 } 709 oTarget.appendChild(oDebug); 710 } 711 oTarget = null; 712 } 713 714 if (specialCase) { 715 _s._wD(specialCase); 716 } 717 718 _s._wD('-- SoundManager 2 '+_s.version+(_s.useMovieStar?', MovieStar mode':'')+(_s.useHighPerformance?', high performance mode':'')+' --',1); 719 _s._wD('soundManager._createMovie(): Trying to load '+smURL+(!_s._overHTTP && _s.altURL?'(alternate URL)':''),1); 720 }; 721 722 // aliased to this._wD() 723 this._writeDebug = function(sText,sType,bTimestamp) { 724 if (!_s.debugMode) { 725 return false;
726 } 727 if (typeof bTimestamp != 'undefined' && bTimestamp) { 728 sText = sText + ' | '+new Date().getTime(); 729 } 730 if (_s._hasConsole && _s.useConsole) { 731 var sMethod = _s._debugLevels[sType]; 732 if (typeof console[sMethod] != 'undefined') { 733 console[sMethod].apply(console,[sText]); // apply() fix for firebug 1.3, so "this" == console 734 } else { 735 console.log(sText); 736 } 737 if (_s.useConsoleOnly) { 738 return true; 739 } 740 } 741 var sDID = 'soundmanager-debug'; 742 try { 743 var o = document.getElementById(sDID); 744 if (!o) { 745 return false; 746 } 747 var oItem = document.createElement('div'); 748 // sText = sText.replace(/\n/g,'<br />'); 749 if (typeof sType == 'undefined') { 750 sType = 0; 751 } else { 752 sType = parseInt(sType,10); 753 } 754 oItem.appendChild(document.createTextNode(sText)); 755 if (sType) { 756 if (sType >= 2) { 757 oItem.style.fontWeight = 'bold'; 758 } 759 if (sType == 3) { 760 oItem.style.color = '#ff3333'; 761 } 762 } 763 // o.appendChild(oItem); // top-to-bottom 764 o.insertBefore(oItem,o.firstChild); // bottom-to-top 765 } catch(e) { 766 // oh well 767 } 768 o = null; 769 }; 770 this._writeDebug._protected = true; 771 this._wD = this._writeDebug; 772 773 this._wDAlert = function(sText) { alert(sText); }; 774 775 if (window.location.href.indexOf('debug=alert')+1 && _s.debugMode) { 776 _s._wD = _s._wDAlert; 777 } 778 779 this._toggleDebug = function() { 780 var o = document.getElementById(_s.debugID); 781 var oT = document.getElementById(_s.debugID+'-toggle'); 782 if (!o) { 783 return false; 784 } 785 if (_s._debugOpen) { 786 // minimize 787 oT.innerHTML = '+'; 788 o.style.display = 'none'; 789 } else { 790 oT.innerHTML = '-'; 791 o.style.display = 'block'; 792 } 793 _s._debugOpen = !_s._debugOpen; 794 }; 795 796 this._toggleDebug._protected = true; 797 798 this._debug = function() { 799 _s._wD('--- soundManager._debug(): Current sound objects ---',1); 800 for (var i=0,j=_s.soundIDs.length; i<j; i++) { 801 _s.sounds[_s.soundIDs[i]]._debug(); 802 } 803 }; 804 805 this._debugTS = function(sEventType,bSuccess,sMessage) { 806 // troubleshooter debug hooks 807 if (typeof sm2Debugger != 'undefined') { 808 try { 809 sm2Debugger.handleEvent(sEventType,bSuccess,sMessage); 810 } catch(e) { 811 // oh well 812 } 813 } 814 }; 815 816 this._debugTS._protected = true; 817 818 this._mergeObjects = function(oMain,oAdd) { 819 // non-destructive merge 820 var o1 = {}; // clone o1 821 for (var i in oMain) { 822 if (oMain.hasOwnProperty(i)) { 823 o1[i] = oMain[i]; 824 } 825 } 826 var o2 = (typeof oAdd == 'undefined'?_s.defaultOptions:oAdd); 827 for (var o in o2) { 828 if (o2.hasOwnProperty(o) && typeof o1[o] == 'undefined') { 829 o1[o] = o2[o]; 830 } 831 } 832 return o1; 833 }; 834 835 this.createMovie = function(sURL) { 836 if (sURL) { 837 _s.url = sURL; 838 } 839 _s._initMovie(); 840 }; 841 842 this.go = this.createMovie; // nice alias 843 844 this._initMovie = function() { 845 // attempt to get, or create, movie 846 if (_s.o) { 847 return false; // pre-init may have fired this function before window.onload(), may already exist 848 } 849 _s.o = _s.getMovie(_s.id); // try to get flash movie (inline markup) 850 if (!_s.o) { 851 // try to create 852 _s._createMovie(_s.id,_s.url); 853 _s.o = _s.getMovie(_s.id); 854 } 855 if (_s.o) { 856 _s._wD('soundManager._initMovie(): Got '+_s.o.nodeName+' element ('+(_s._didAppend?'created via JS':'static HTML')+')',1); 857 _s._wD('soundManager._initMovie(): Waiting for ExternalInterface call from Flash..'); 858 } 859 }; 860 861 this.waitForExternalInterface = function() { 862 if (_s._waitingForEI) { 863 return false; 864 } 865 _s._waitingForEI = true; 866 if (_s._tryInitOnFocus && !_s._isFocused) { 867 _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..'); 868 return false; 869 } 870 if (!_s._didInit) { 871 _s._wD('soundManager: Getting impatient, still waiting for Flash.. ;)'); 872 } 873 setTimeout(function() { 874 if (!_s._didInit) { 875 _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); 876 if (!_s._overHTTP) { 877 _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); 878 }
879 _s._debugTS('flashtojs',false,': Timed out'+(_s._overHTTP)?' (Check flash security)':' (No plugin/missing SWF?)'); 880 } 881 // if still not initialized and no other options, give up 882 if (!_s._didInit && _s._okToDisable) { 883 _s._failSafely(); 884 } 885 },750); 886 }; 887 888 this.handleFocus = function() { 889 if (_s._isFocused || !_s._tryInitOnFocus) { 890 return true; 891 } 892 _s._okToDisable = true; 893 _s._isFocused = true; 894 _s._wD('soundManager.handleFocus()'); 895 if (_s._tryInitOnFocus) { 896 // giant Safari 3.1 hack - assume window in focus if mouse is moving, since document.hasFocus() not currently implemented. 897 window.removeEventListener('mousemove',_s.handleFocus,false); 898 } 899 // allow init to restart 900 _s._waitingForEI = false; 901 setTimeout(_s.waitForExternalInterface,500); 902 // detach event 903 if (window.removeEventListener) { 904 window.removeEventListener('focus',_s.handleFocus,false); 905 } else if (window.detachEvent) { 906 window.detachEvent('onfocus',_s.handleFocus); 907 } 908 }; 909 910 this.initComplete = function() { 911 if (_s._didInit) { 912 return false; 913 } 914 _s._didInit = true; 915 _s._wD('-- SoundManager 2 '+(_s._disabled?'failed to load':'loaded')+' ('+(_s._disabled?'security/load error':'OK')+') --',1); 916 if (_s._disabled) { 917 _s._wD('soundManager.initComplete(): calling soundManager.onerror()',1); 918 _s._debugTS('onload',false); 919 _s.onerror.apply(window); 920 return false; 921 } else { 922 _s._debugTS('onload',true); 923 } 924 if (_s.waitForWindowLoad && !_s._windowLoaded) { 925 _s._wD('soundManager: Waiting for window.onload()'); 926 if (window.addEventListener) { 927 window.addEventListener('load',_s.initUserOnload,false); 928 } else if (window.attachEvent) { 929 window.attachEvent('onload',_s.initUserOnload); 930 } 931 return false; 932 } else { 933 if (_s.waitForWindowLoad && _s._windowLoaded) { 934 _s._wD('soundManager: Document already loaded'); 935 } 936 _s.initUserOnload(); 937 } 938 }; 939 940 this.initUserOnload = function() { 941 _s._wD('soundManager.initComplete(): calling soundManager.onload()',1); 942 // call user-defined "onload", scoped to window 943 _s.onload.apply(window); 944 _s._wD('soundManager.onload() complete',1); 945 }; 946 947 this.init = function() { 948 _s._wD('-- soundManager.init() --'); 949 // called after onload() 950 _s._initMovie(); 951 if (_s._didInit) { 952 _s._wD('soundManager.init(): Already called?'); 953 return false; 954 } 955 // event cleanup 956 if (window.removeEventListener) { 957 window.removeEventListener('load',_s.beginDelayedInit,false); 958 } else if (window.detachEvent) { 959 window.detachEvent('onload',_s.beginDelayedInit); 960 } 961 try { 962 _s._wD('Attempting to call Flash from JS..'); 963 _s.o._externalInterfaceTest(false); // attempt to talk to Flash 964 // _s._wD('Flash ExternalInterface call (JS-Flash) OK',1); 965 if (!_s.allowPolling) { 966 _s._wD('Polling (whileloading/whileplaying support) is disabled.',1); 967 } 968 _s.setPolling(true); 969 if (!_s.debugMode) { 970 _s.o._disableDebug(); 971 } 972 _s.enabled = true; 973 _s._debugTS('jstoflash',true); 974 } catch(e) { 975 _s._debugTS('jstoflash',false); 976 _s._failSafely(); 977 _s.initComplete(); 978 return false; 979 } 980 _s.initComplete(); 981 }; 982 983 this.beginDelayedInit = function() { 984 _s._wD('soundManager.beginDelayedInit(): Document loaded'); 985 _s._windowLoaded = true; 986 setTimeout(_s.waitForExternalInterface,500); 987 setTimeout(_s.beginInit,20); 988 }; 989 990 this.beginInit = function() { 991 if (_s._initPending) { 992 return false; 993 } 994 _s.createMovie(); // ensure creation if not already done 995 _s._initMovie(); 996 _s._initPending = true; 997 return true; 998 }; 999 1000 this.domContentLoaded = function() { 1001 _s._wD('soundManager.domContentLoaded()'); 1002 if (document.removeEventListener) { 1003 document.removeEventListener('DOMContentLoaded',_s.domContentLoaded,false); 1004 } 1005 _s.go(); 1006 }; 1007 1008 this._externalInterfaceOK = function() { 1009 // callback from flash for confirming that movie loaded, EI is working etc. 1010 if (_s.swfLoaded) { 1011 return false;
1012 } 1013 _s._wD('soundManager._externalInterfaceOK()'); 1014 _s._debugTS('swf',true); 1015 _s._debugTS('flashtojs',true); 1016 _s.swfLoaded = true; 1017 _s._tryInitOnFocus = false; 1018 if (_s.isIE) { 1019 // IE needs a timeout OR delay until window.onload - may need TODO: investigating 1020 setTimeout(_s.init,100); 1021 } else { 1022 _s.init(); 1023 } 1024 }; 1025 1026 this._setSandboxType = function(sandboxType) { 1027 var sb = _s.sandbox; 1028 sb.type = sandboxType; 1029 sb.description = sb.types[(typeof sb.types[sandboxType] != 'undefined'?sandboxType:'unknown')]; 1030 _s._wD('Flash security sandbox type: '+sb.type); 1031 if (sb.type == 'localWithFile') { 1032 sb.noRemote = true; 1033 sb.noLocal = false; 1034 _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); 1035 } else if (sb.type == 'localWithNetwork') { 1036 sb.noRemote = false; 1037 sb.noLocal = true; 1038 } else if (sb.type == 'localTrusted') { 1039 sb.noRemote = false; 1040 sb.noLocal = false;
1041 } 1042 }; 1043 1044 this.destruct = function() { 1045 _s._wD('soundManager.destruct()'); 1046 _s.disable(true); 1047 }; 1048 1049 // SMSound (sound object) 1050 1051 SMSound = function(oOptions) { 1052 var _t = this; 1053 this.sID = oOptions.id; 1054 this.url = oOptions.url; 1055 this.options = _s._mergeObjects(oOptions); 1056 this.instanceOptions = this.options; // per-play-instance-specific options 1057 this._iO = this.instanceOptions; // short alias 1058 1059 // assign property defaults (volume, pan etc.) 1060 this.pan = this.options.pan; 1061 this.volume = this.options.volume; 1062 1063 this._debug = function() { 1064 if (_s.debugMode) { 1065 var stuff = null; 1066 var msg = []; 1067 var sF = null; 1068 var sfBracket = null; 1069 var maxLength = 64; // # of characters of function code to show before truncating 1070 for (stuff in _t.options) { 1071 if (_t.options[stuff] !== null) { 1072 if (_t.options[stuff] instanceof Function) { 1073 // handle functions specially 1074 sF = _t.options[stuff].toString(); 1075 sF = sF.replace(/\s\s+/g,' '); // normalize spaces 1076 sfBracket = sF.indexOf('{'); 1077 msg[msg.length] = ' '+stuff+': {'+sF.substr(sfBracket+1,(Math.min(Math.max(sF.indexOf('\n')-1,maxLength),maxLength))).replace(/\n/g,'')+'... }'; 1078 } else { 1079 msg[msg.length] = ' '+stuff+': '+_t.options[stuff]; 1080 } 1081 } 1082 } 1083 _s._wD('SMSound() merged options: {\n'+msg.join(', \n')+'\n}'); 1084 } 1085 }; 1086 1087 this._debug(); 1088 1089 this.id3 = { 1090 /* 1091 Name/value pairs set via Flash when available - see reference for names: 1092 http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001567.html 1093 (eg., this.id3.songname or this.id3['songname']) 1094 */ 1095 }; 1096 1097 this.resetProperties = function(bLoaded) { 1098 _t.bytesLoaded = null; 1099 _t.bytesTotal = null; 1100 _t.position = null; 1101 _t.duration = null; 1102 _t.durationEstimate = null; 1103 _t.loaded = false; 1104 _t.playState = 0; 1105 _t.paused = false; 1106 _t.readyState = 0; // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success 1107 _t.muted = false; 1108 _t.didBeforeFinish = false; 1109 _t.didJustBeforeFinish = false; 1110 _t.instanceOptions = {}; 1111 _t.instanceCount = 0; 1112 _t.peakData = { 1113 left: 0, 1114 right: 0 1115 }; 1116 _t.waveformData = []; 1117 _t.eqData = []; 1118 }; 1119 1120 _t.resetProperties(); 1121 1122 // --- public methods --- 1123 1124 this.load = function(oOptions) { 1125 if (typeof oOptions != 'undefined') { 1126 _t._iO = _s._mergeObjects(oOptions); 1127 _t.instanceOptions = _t._iO; 1128 } else { 1129 oOptions = _t.options; 1130 _t._iO = oOptions; 1131 _t.instanceOptions = _t._iO; 1132 } 1133 if (typeof _t._iO.url == 'undefined') { 1134 _t._iO.url = _t.url; 1135 } 1136 _s._wD('soundManager.load(): '+_t._iO.url,1); 1137 if (_t._iO.url == _t.url && _t.readyState !== 0 && _t.readyState != 2) { 1138 _s._wD('soundManager.load(): current URL already assigned.',1); 1139 return false; 1140 } 1141 _t.loaded = false; 1142 _t.readyState = 1; 1143 _t.playState = 0; // (oOptions.autoPlay?1:0); // if autoPlay, assume "playing" is true (no way to detect when it actually starts in Flash unless onPlay is watched?) 1144 try { 1145 if (_s.flashVersion==8) { 1146 _s.o._load(_t.sID,_t._iO.url,_t._iO.stream,_t._iO.autoPlay,(_t._iO.whileloading?1:0)); 1147 } else { 1148 _s.o._load(_t.sID,_t._iO.url,_t._iO.stream?true:false,_t._iO.autoPlay?true:false); // ,(_tO.whileloading?true:false) 1149 if (_t._iO.isMovieStar && _t._iO.autoLoad && !_t._iO.autoPlay) { 1150 // special case: MPEG4 content must start playing to load, then pause to prevent playing. 1151 _t.pause(); 1152 } 1153 } 1154 } catch(e) { 1155 _s._wD('SMSound.load(): Exception: JS-Flash communication failed, or JS error.',2); 1156 _s._debugTS('onload',false); 1157 _s.onerror(); 1158 _s.disable(); 1159 } 1160 1161 }; 1162 1163 this.unload = function() { 1164 // Flash 8/AS2 can't "close" a stream - fake it by loading an empty MP3 1165 // Flash 9/AS3: Close stream, preventing further load 1166 if (_t.readyState !== 0) { 1167 _s._wD('SMSound.unload(): "'+_t.sID+'"'); 1168 if (_t.readyState != 2) { // reset if not error 1169 _t.setPosition(0,true); // reset current sound positioning 1170 } 1171 _s.o._unload(_t.sID,_s.nullURL); 1172 // reset load/status flags 1173 _t.resetProperties(); 1174 } 1175 }; 1176 1177 this.destruct = function() { 1178 // kill sound within Flash 1179 _s._wD('SMSound.destruct(): "'+_t.sID+'"'); 1180 _s.o._destroySound(_t.sID); 1181 _s.destroySound(_t.sID,true);
1181 // ensure deletion from controller 1182 }; 1183 1184 this.play = function(oOptions) { 1185 if (!oOptions) { 1186 oOptions = {}; 1187 } 1188 _t._iO = _s._mergeObjects(oOptions,_t._iO); 1189 _t._iO = _s._mergeObjects(_t._iO,_t.options); 1190 _t.instanceOptions = _t._iO; 1191 if (_t.playState == 1) { 1192 var allowMulti = _t._iO.multiShot; 1193 if (!allowMulti) { 1194 _s._wD('SMSound.play(): "'+_t.sID+'" already playing (one-shot)',1); 1195 return false; 1196 } else { 1197 _s._wD('SMSound.play(): "'+_t.sID+'" already playing (multi-shot)',1); 1198 } 1199 } 1200 if (!_t.loaded) { 1201 if (_t.readyState === 0) { 1202 _s._wD('SMSound.play(): Attempting to load "'+_t.sID+'"',1); 1203 // try to get this sound playing ASAP 1204 _t._iO.stream = true; 1205 _t._iO.autoPlay = true; 1206 // TODO: need to investigate when false, double-playing 1207 // if (typeof oOptions.autoPlay=='undefined') _tO.autoPlay = true; // only set autoPlay if unspecified here 1208 _t.load(_t._iO); // try to get this sound playing ASAP 1209 } else if (_t.readyState == 2) { 1210 _s._wD('SMSound.play(): Could not load "'+_t.sID+'" - exiting',2); 1211 return false; 1212 } else { 1213 _s._wD('SMSound.play(): "'+_t.sID+'" is loading - attempting to play..',1); 1214 } 1215 } else { 1216 _s._wD('SMSound.play(): "'+_t.sID+'"'); 1217 } 1218 if (_t.paused) { 1219 _t.resume(); 1220 } else { 1221 _t.playState = 1; 1222 if (!_t.instanceCount || _s.flashVersion == 9) { 1223 _t.instanceCount++; 1224 } 1225 _t.position = (typeof _t._iO.position != 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0); 1226 if (_t._iO.onplay) { 1227 _t._iO.onplay.apply(_t); 1228 } 1229 _t.setVolume(_t._iO.volume,true); // restrict volume to instance options only 1230 _t.setPan(_t._iO.pan,true); 1231 _s.o._start(_t.sID,_t._iO.loop||1,(_s.flashVersion==9?_t.position:_t.position/1000)); 1232 } 1233 }; 1234 1235 this.start = this.play; // just for convenience 1236 1237 this.stop = function(bAll) { 1238 if (_t.playState == 1) { 1239 _t.playState = 0; 1240 _t.paused = false; 1241 // if (_s.defaultOptions.onstop) _s.defaultOptions.onstop.apply(_s); 1242 if (_t._iO.onstop) { 1243 _t._iO.onstop.apply(_t); 1244 } 1245 _s.o._stop(_t.sID,bAll); 1246 _t.instanceCount = 0; 1247 _t._iO = {}; 1248 // _t.instanceOptions = _t._iO; 1249 } 1250 }; 1251 1252 this.setPosition = function(nMsecOffset,bNoDebug) { 1253 if (typeof nMsecOffset == 'undefined') { 1254 nMsecOffset = 0; 1255 } 1256 var offset = Math.min(_t.duration,Math.max(nMsecOffset,0)); // position >= 0 and <= current available (loaded) duration 1257 _t._iO.position = offset; 1258 if (!bNoDebug) { 1259 _s._wD('SMSound.setPosition('+nMsecOffset+')'+(nMsecOffset != offset?', corrected value: '+offset:'')); 1260 } 1261 _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) 1262 }; 1263 1264 this.pause = function() { 1265 if (_t.paused || _t.playState === 0) { 1266 return false; 1267 } 1268 _s._wD('SMSound.pause()'); 1269 _t.paused = true; 1270 _s.o._pause(_t.sID); 1271 if (_t._iO.onpause) { 1272 _t._iO.onpause.apply(_t); 1273 } 1274 }; 1275 1276 this.resume = function() { 1277 if (!_t.paused || _t.playState === 0) { 1278 return false; 1279 } 1280 _s._wD('SMSound.resume()'); 1281 _t.paused = false; 1282 _s.o._pause(_t.sID); // flash method is toggle-based (pause/resume) 1283 if (_t._iO.onresume) { 1284 _t._iO.onresume.apply(_t); 1285 } 1286 }; 1287 1288 this.togglePause = function() { 1289 _s._wD('SMSound.togglePause()'); 1290 if (!_t.playState) { 1291 _t.play({position:(_s.flashVersion==9?_t.position:_t.position/1000)}); 1292 return false; 1293 } 1294 if (_t.paused) { 1295 _t.resume(); 1296 } else { 1297 _t.pause(); 1298 } 1299 }; 1300 1301 this.setPan = function(nPan,bInstanceOnly) { 1302 if (typeof nPan == 'undefined') { 1303 nPan = 0; 1304 } 1305 if (typeof bInstanceOnly == 'undefined') { 1306 bInstanceOnly = false; 1307 } 1308 _s.o._setPan(_t.sID,nPan); 1309 _t._iO.pan = nPan; 1310 if (!bInstanceOnly) { 1311 _t.pan = nPan; 1312 } 1313 }; 1314 1315 this.setVolume = function(nVol,bInstanceOnly) { 1316 if (typeof nVol == 'undefined') { 1317 nVol = 100; 1318 } 1319 if (typeof bInstanceOnly == 'undefined') { 1320 bInstanceOnly = false;
1321 } 1322 _s.o._setVolume(_t.sID,(_s.muted&&!_t.muted)||_t.muted?0:nVol); 1323 _t._iO.volume = nVol; 1324 if (!bInstanceOnly) { 1325 _t.volume = nVol; 1326 } 1327 }; 1328 1329 this.mute = function() { 1330 _t.muted = true; 1331 _s.o._setVolume(_t.sID,0); 1332 }; 1333 1334 this.unmute = function() { 1335 _t.muted = false; 1336 var hasIO = typeof _t._iO.volume != 'undefined'; 1337 _s.o._setVolume(_t.sID,hasIO?_t._iO.volume:_t.options.volume,hasIO?false:true); 1338 }; 1339 1340 // --- "private" methods called by Flash --- 1341 1342 this._whileloading = function(nBytesLoaded,nBytesTotal,nDuration) { 1343 if (!_t._iO.isMovieStar) { 1344 _t.bytesLoaded = nBytesLoaded; 1345 _t.bytesTotal = nBytesTotal; 1346 _t.duration = Math.floor(nDuration); 1347 _t.durationEstimate = parseInt((_t.bytesTotal/_t.bytesLoaded)*_t.duration,10); // estimate total time (will only be accurate with CBR MP3s.) 1348 if (_t.readyState != 3 && _t._iO.whileloading) { 1349 _t._iO.whileloading.apply(_t); 1350 } 1351 } else { 1352 _t.bytesLoaded = nBytesLoaded; 1353 _t.bytesTotal = nBytesTotal; 1354 _t.duration = Math.floor(nDuration); 1355 _t.durationEstimate = _t.duration; 1356 if (_t.readyState != 3 && _t._iO.whileloading) { 1357 _t._iO.whileloading.apply(_t); 1358 } 1359 } 1360 }; 1361 1362 this._onid3 = function(oID3PropNames,oID3Data) { 1363 // oID3PropNames: string array (names) 1364 // ID3Data: string array (data) 1365 _s._wD('SMSound._onid3(): "'+this.sID+'" ID3 data received.'); 1366 var oData = []; 1367 for (var i=0,j=oID3PropNames.length; i<j; i++) { 1368 oData[oID3PropNames[i]] = oID3Data[i]; 1369 // _s._wD(oID3PropNames[i]+': '+oID3Data[i]); 1370 } 1371 _t.id3 = _s._mergeObjects(_t.id3,oData); 1372 if (_t._iO.onid3) { 1373 _t._iO.onid3.apply(_t); 1374 } 1375 }; 1376 1377 this._whileplaying = function(nPosition,oPeakData,oWaveformData,oEQData) { 1378 if (isNaN(nPosition) || nPosition === null) { 1379 return false; // Flash may return NaN at times 1380 } 1381 _t.position = nPosition; 1382 if (_t._iO.usePeakData && typeof oPeakData != 'undefined' && oPeakData) { 1383 _t.peakData = { 1384 left: oPeakData.leftPeak, 1385 right: oPeakData.rightPeak 1386 }; 1387 } 1388 if (_t._iO.useWaveformData && typeof oWaveformData != 'undefined' && oWaveformData) { 1389 _t.waveformData = oWaveformData; 1390 /* 1391 _t.spectrumData = { 1392 left: oSpectrumData.left.split(','), 1393 right: oSpectrumData.right.split(',') 1394 } 1395 */ 1396 } 1397 if (_t._iO.useEQData && typeof oEQData != 'undefined' && oEQData) { 1398 _t.eqData = oEQData; 1399 } 1400 if (_t.playState == 1) { 1401 if (_t._iO.whileplaying) { 1402 _t._iO.whileplaying.apply(_t); // flash may call after actual finish 1403 } 1404 if (_t.loaded && _t._iO.onbeforefinish && _t._iO.onbeforefinishtime && !_t.didBeforeFinish && _t.duration-_t.position <= _t._iO.onbeforefinishtime) { 1405 _s._wD('duration-position <= onbeforefinishtime: '+_t.duration+' - '+_t.position+' <= '+_t._iO.onbeforefinishtime+' ('+(_t.duration-_t.position)+')'); 1406 _t._onbeforefinish(); 1407 } 1408 } 1409 }; 1410 1411 this._onload = function(bSuccess) { 1412 bSuccess = (bSuccess==1?true:false); 1413 _s._wD('SMSound._onload(): "'+_t.sID+'"'+(bSuccess?' loaded.':' failed to load? - '+_t.url)); 1414 if (!bSuccess) { 1415 if (_s.sandbox.noRemote === true) { 1416 _s._wD('SMSound._onload(): Reminder: Flash security is denying network/internet access',1); 1417 } 1418 if (_s.sandbox.noLocal === true) { 1419 _s._wD('SMSound._onload(): Reminder: Flash security is denying local access',1); 1420 } 1421 } 1422 _t.loaded = bSuccess; 1423 _t.readyState = bSuccess?3:2; 1424 if (_t._iO.onload) { 1425 _t._iO.onload.apply(_t); 1426 } 1427 }; 1428 1429 this._onbeforefinish = function() { 1430 if (!_t.didBeforeFinish) { 1431 _t.didBeforeFinish = true; 1432 if (_t._iO.onbeforefinish) { 1433 _s._wD('SMSound._onbeforefinish(): "'+_t.sID+'"'); 1434 _t._iO.onbeforefinish.apply(_t); 1435 } 1436 } 1437 }; 1438 1439 this._onjustbeforefinish = function(msOffset) { 1440 // msOffset: "end of sound" delay actual value (eg. 200 msec, value at event fire time was 187) 1441 if (!_t.didJustBeforeFinish) { 1442 _t.didJustBeforeFinish = true; 1443 if (_t._iO.onjustbeforefinish) { 1444 _s._wD('SMSound._onjustbeforefinish(): "'+_t.sID+'"'); 1445 _t._iO.onjustbeforefinish.apply(_t); 1446 } 1447 } 1448 }; 1449 1450 this._onfinish = function() { 1451 // sound has finished playing 1452 1453 // TODO: calling user-defined onfinish() should happen after setPosition(0) 1454 // OR: onfinish() and then setPosition(0) is bad. 1455 1456 if (_t._iO.onbeforefinishcomplete) { 1457 _t._iO.onbeforefinishcomplete.apply(_t); 1458 } 1459 // reset some state items 1460 _t.didBeforeFinish = false;
1461 _t.didJustBeforeFinish = false; 1462 if (_t.instanceCount) { 1463 _t.instanceCount--; 1464 if (!_t.instanceCount) { 1465 // reset instance options 1466 // _t.setPosition(0); 1467 _t.playState = 0; 1468 _t.paused = false; 1469 _t.instanceCount = 0; 1470 _t.instanceOptions = {}; 1471 if (_t._iO.onfinish) { 1472 _s._wD('SMSound._onfinish(): "'+_t.sID+'"'); 1473 _t._iO.onfinish.apply(_t); 1474 } 1475 } 1476 } else { 1477 // _t.setPosition(0); 1478 } 1479 }; 1480 1481 this._onmetadata = function(oMetaData) { 1482 // movieStar mode only 1483 _s._wD('SMSound.onmetadata()'); 1484 // Contains a subset of metadata. Note that files may have their own unique metadata. 1485 // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html 1486 if (!oMetaData.width && !oMetaData.height) { 1487 _s._wD('No width/height given, assuming defaults'); 1488 oMetaData.width = 320; 1489 oMetaData.height = 240; 1490 } 1491 _t.metadata = oMetaData; // potentially-large object from flash 1492 _t.width = oMetaData.width; 1493 _t.height = oMetaData.height; 1494 if (_t._iO.onmetadata) { 1495 _s._wD('SMSound._onmetadata(): "'+_t.sID+'"'); 1496 _t._iO.onmetadata.apply(_t); 1497 } 1498 _s._wD('SMSound.onmetadata() complete'); 1499 }; 1500 1501 }; // SMSound() 1502 1503 // register a few event handlers 1504 if (window.addEventListener) { 1505 window.addEventListener('focus',_s.handleFocus,false); 1506 window.addEventListener('load',_s.beginDelayedInit,false); 1507 window.addEventListener('unload',_s.destruct,false); 1508 if (_s._tryInitOnFocus) { 1509 window.addEventListener('mousemove',_s.handleFocus,false); // massive Safari focus hack 1510 } 1511 } else if (window.attachEvent) { 1512 window.attachEvent('onfocus',_s.handleFocus); 1513 window.attachEvent('onload',_s.beginDelayedInit); 1514 window.attachEvent('unload',_s.destruct); 1515 } else { 1516 // no add/attachevent support - safe to assume no JS -> Flash either. 1517 _s._debugTS('onload',false); 1518 soundManager.onerror(); 1519 soundManager.disable(); 1520 } 1521 1522 if (document.addEventListener) { 1523 document.addEventListener('DOMContentLoaded',_s.domContentLoaded,false); 1524 } 1525 1526} // SoundManager() 1527 1528soundManager = new SoundManager(); 1529
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.