soundmanager-rails 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,7 +8,7 @@
8
8
  * Code provided under the BSD License:
9
9
  * http://schillmania.com/projects/soundmanager2/license.txt
10
10
  *
11
- * V2.97a.20130512
11
+ * V2.97a.20131201
12
12
  */
13
13
 
14
14
  /*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
@@ -36,7 +36,7 @@ function SoundManager(smURL, smID) {
36
36
  'useFlashBlock': false,
37
37
  'useHTML5Audio': true,
38
38
  'html5Test': /^(probably|maybe)$/i,
39
- 'preferFlash': true,
39
+ 'preferFlash': false,
40
40
  'noSWFCache': false,
41
41
  'idPrefix': 'sound'
42
42
  };
@@ -107,7 +107,7 @@ function SoundManager(smURL, smID) {
107
107
  this.id = (smID || 'sm2movie');
108
108
  this.debugID = 'soundmanager-debug';
109
109
  this.debugURLParam = /([#?&])debug=1/i;
110
- this.versionNumber = 'V2.97a.20130512';
110
+ this.versionNumber = 'V2.97a.20131201';
111
111
  this.version = null;
112
112
  this.movieURL = null;
113
113
  this.altURL = null;
@@ -139,13 +139,14 @@ function SoundManager(smURL, smID) {
139
139
  this.html5Only = false;
140
140
  this.ignoreFlash = false;
141
141
  var SMSound,
142
- sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
142
+ sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, rebootIntoHTML5, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
143
143
  canIgnoreFlash, needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages, wrapCallback, idCounter = 0,
144
- is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)), isFirefox = (ua.match(/firefox/i)),
144
+ is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)),
145
145
  mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
146
146
  isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)),
147
147
  hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, msecScale = 1000,
148
148
  emptyURL = 'about:blank',
149
+ emptyWAV = 'data:audio/wave;base64,/UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQIAAAD//w==',
149
150
  overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
150
151
  http = (!overHTTP ? 'http:/'+'/' : ''),
151
152
  netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,
@@ -666,9 +667,6 @@ function SoundManager(smURL, smID) {
666
667
  s._a.autobuffer = 'auto';
667
668
  s._a.preload = 'auto';
668
669
  s._a._called_load = true;
669
- if (instanceOptions.autoPlay) {
670
- s.play();
671
- }
672
670
  } else {
673
671
  }
674
672
  } else {
@@ -813,7 +811,7 @@ function SoundManager(smURL, smID) {
813
811
  };
814
812
  if (s.isHTML5 && !s._html5_canplay) {
815
813
  s.load({
816
- oncanplay: onready
814
+ _oncanplay: onready
817
815
  });
818
816
  exit = false;
819
817
  } else if (!s.isHTML5 && !s.loaded && (!s.readyState || s.readyState !== 2)) {
@@ -861,7 +859,7 @@ function SoundManager(smURL, smID) {
861
859
  } else {
862
860
  audioClone = new Audio(s._iO.url);
863
861
  onended = function() {
864
- event.remove(audioClone, 'onended', onended);
862
+ event.remove(audioClone, 'ended', onended);
865
863
  s._onfinish(s);
866
864
  html5Unload(audioClone);
867
865
  audioClone = null;
@@ -875,6 +873,12 @@ function SoundManager(smURL, smID) {
875
873
  audioClone.play();
876
874
  };
877
875
  event.add(audioClone, 'ended', onended);
876
+ if (s._iO.volume !== undefined) {
877
+ audioClone.volume = Math.max(0, Math.min(1, s._iO.volume/100));
878
+ }
879
+ if (s.muted) {
880
+ audioClone.muted = true;
881
+ }
878
882
  if (s._iO.position) {
879
883
  event.add(audioClone, 'canplay', oncanplay);
880
884
  } else {
@@ -1056,6 +1060,10 @@ function SoundManager(smURL, smID) {
1056
1060
  if (!s.isHTML5) {
1057
1061
  flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol);
1058
1062
  } else if (s._a) {
1063
+ if (sm2.muted && !s.muted) {
1064
+ s.muted = true;
1065
+ s._a.muted = true;
1066
+ }
1059
1067
  s._a.volume = Math.max(0, Math.min(1, nVol/100));
1060
1068
  }
1061
1069
  s._iO.volume = nVol;
@@ -1125,6 +1133,7 @@ function SoundManager(smURL, smID) {
1125
1133
  item.fired = true;
1126
1134
  onPositionFired++;
1127
1135
  item.method.apply(item.scope, [item.position]);
1136
+ j = onPositionItems.length;
1128
1137
  }
1129
1138
  }
1130
1139
  return true;
@@ -1291,7 +1300,9 @@ function SoundManager(smURL, smID) {
1291
1300
  }
1292
1301
  }
1293
1302
  if (!sameURL) {
1294
- resetProperties(false);
1303
+ if (lastURL) {
1304
+ resetProperties(false);
1305
+ }
1295
1306
  a.src = instanceOptions.url;
1296
1307
  s.url = instanceOptions.url;
1297
1308
  lastURL = instanceOptions.url;
@@ -1301,6 +1312,7 @@ function SoundManager(smURL, smID) {
1301
1312
  } else {
1302
1313
  if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
1303
1314
  s._a = new Audio(instanceOptions.url);
1315
+ s._a.load();
1304
1316
  } else {
1305
1317
  s._a = (isOpera && opera.version() < 10 ? new Audio(null) : new Audio());
1306
1318
  }
@@ -1536,7 +1548,7 @@ function SoundManager(smURL, smID) {
1536
1548
  };
1537
1549
  };
1538
1550
  getDocument = function() {
1539
- return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]);
1551
+ return (doc.body || doc.getElementsByTagName('div')[0]);
1540
1552
  };
1541
1553
  id = function(sID) {
1542
1554
  return doc.getElementById(sID);
@@ -1713,7 +1725,7 @@ function SoundManager(smURL, smID) {
1713
1725
  }),
1714
1726
  progress: html5_event(function(e) {
1715
1727
  var s = this._s,
1716
- i, j, str, buffered = 0,
1728
+ i, j, progStr, buffered = 0,
1717
1729
  isProgress = (e.type === 'progress'),
1718
1730
  ranges = e.target.buffered,
1719
1731
  loaded = (e.loaded||0),
@@ -1768,7 +1780,7 @@ function SoundManager(smURL, smID) {
1768
1780
  html5Unload = function(oAudio) {
1769
1781
  var url;
1770
1782
  if (oAudio) {
1771
- url = (isSafari && !is_iDevice ? null : (isFirefox ? emptyURL : null));
1783
+ url = (isSafari ? emptyURL : (sm2.html5.canPlayType('audio/wav') ? emptyWAV : emptyURL));
1772
1784
  oAudio.src = url;
1773
1785
  if (oAudio._called_unload !== undefined) {
1774
1786
  oAudio._called_load = false;
@@ -1835,7 +1847,7 @@ function SoundManager(smURL, smID) {
1835
1847
  var a = (Audio !== _undefined ? (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null),
1836
1848
  item, lookup, support = {}, aF, i;
1837
1849
  function cp(m) {
1838
- var canPlay, i, j,
1850
+ var canPlay, j,
1839
1851
  result = false,
1840
1852
  isOK = false;
1841
1853
  if (!a || typeof a.canPlayType !== 'function') {
@@ -2413,6 +2425,15 @@ function SoundManager(smURL, smID) {
2413
2425
  delayWaitForEI = function() {
2414
2426
  setTimeout(waitForEI, 1000);
2415
2427
  };
2428
+ rebootIntoHTML5 = function() {
2429
+ window.setTimeout(function() {
2430
+ sm2.setup({
2431
+ preferFlash: false
2432
+ }).reboot();
2433
+ sm2.didFlashBlock = true;
2434
+ sm2.beginDelayedInit();
2435
+ }, 1);
2436
+ };
2416
2437
  waitForEI = function() {
2417
2438
  var p,
2418
2439
  loadIncomplete = false;
@@ -2424,7 +2445,7 @@ function SoundManager(smURL, smID) {
2424
2445
  }
2425
2446
  waitingForEI = true;
2426
2447
  event.remove(window, 'load', delayWaitForEI);
2427
- if (tryInitOnFocus && !isFocused) {
2448
+ if (hasFlash && tryInitOnFocus && !isFocused) {
2428
2449
  return false;
2429
2450
  }
2430
2451
  if (!didInit) {
@@ -2448,21 +2469,19 @@ function SoundManager(smURL, smID) {
2448
2469
  }
2449
2470
  } else {
2450
2471
  if (!sm2.useFlashBlock && canIgnoreFlash) {
2451
- window.setTimeout(function() {
2452
- sm2.setup({
2453
- preferFlash: false
2454
- }).reboot();
2455
- sm2.didFlashBlock = true;
2456
- sm2.beginDelayedInit();
2457
- }, 1);
2472
+ rebootIntoHTML5();
2458
2473
  } else {
2459
- processOnEvents({type:'ontimeout', ignoreInit: true});
2474
+ processOnEvents({type:'ontimeout', ignoreInit: true, error: {type: 'INIT_FLASHBLOCK'}});
2460
2475
  }
2461
2476
  }
2462
2477
  } else {
2463
2478
  if (sm2.flashLoadTimeout === 0) {
2464
2479
  } else {
2465
- failSafely(true);
2480
+ if (!sm2.useFlashBlock && canIgnoreFlash) {
2481
+ rebootIntoHTML5();
2482
+ } else {
2483
+ failSafely(true);
2484
+ }
2466
2485
  }
2467
2486
  }
2468
2487
  }
@@ -2501,10 +2520,8 @@ function SoundManager(smURL, smID) {
2501
2520
  error;
2502
2521
  if (!wasTimeout) {
2503
2522
  didInit = true;
2504
- if (disabled) {
2505
- error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
2506
- }
2507
2523
  }
2524
+ error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
2508
2525
  if (disabled || bNoDisable) {
2509
2526
  if (sm2.useFlashBlock && sm2.oMC) {
2510
2527
  sm2.oMC.className = getSWFCSS() + ' ' + (sm2.getMoviePercent() === null?swfCSS.swfTimedout:swfCSS.swfError);
@@ -2640,4 +2657,4 @@ if (window.SM2_DEFER === undefined || !SM2_DEFER) {
2640
2657
  }
2641
2658
  window.SoundManager = SoundManager;
2642
2659
  window.soundManager = soundManager;
2643
- }(window));
2660
+ }(window));
@@ -8,7 +8,7 @@
8
8
  * Code provided under the BSD License:
9
9
  * http://schillmania.com/projects/soundmanager2/license.txt
10
10
  *
11
- * V2.97a.20130512
11
+ * V2.97a.20131201
12
12
  */
13
13
 
14
14
  /*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
@@ -73,7 +73,7 @@ function SoundManager(smURL, smID) {
73
73
  'useFlashBlock': false, // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable.
74
74
  'useHTML5Audio': true, // use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible.
75
75
  'html5Test': /^(probably|maybe)$/i, // HTML5 Audio() format support test. Use /^probably$/i; if you want to be more conservative.
76
- 'preferFlash': true, // overrides useHTML5audio. if true and flash support present, will try to use flash for MP3/MP4 as needed since HTML5 audio support is still quirky in browsers.
76
+ 'preferFlash': false, // overrides useHTML5audio, will use Flash for MP3/MP4/AAC if present. Potential option if HTML5 playback with these formats is quirky.
77
77
  'noSWFCache': false, // if true, appends ?ts={date} to break aggressive SWF caching.
78
78
  'idPrefix': 'sound' // if an id is not provided to createSound(), this prefix is used for generated IDs - 'sound0', 'sound1' etc.
79
79
 
@@ -189,7 +189,7 @@ function SoundManager(smURL, smID) {
189
189
 
190
190
  // dynamic attributes
191
191
 
192
- this.versionNumber = 'V2.97a.20130512';
192
+ this.versionNumber = 'V2.97a.20131201';
193
193
  this.version = null;
194
194
  this.movieURL = null;
195
195
  this.altURL = null;
@@ -265,13 +265,14 @@ function SoundManager(smURL, smID) {
265
265
  */
266
266
 
267
267
  var SMSound,
268
- sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
268
+ sm2 = this, globalHTML5Audio = null, flash = null, sm = 'soundManager', smc = sm + ': ', h5 = 'HTML5::', id, ua = navigator.userAgent, wl = window.location.href.toString(), doc = document, doNothing, setProperties, init, fV, on_queue = [], debugOpen = true, debugTS, didAppend = false, appendSuccess = false, didInit = false, disabled = false, windowLoaded = false, _wDS, wdCount = 0, initComplete, mixin, assign, extraOptions, addOnEvent, processOnEvents, initUserOnload, delayWaitForEI, waitForEI, rebootIntoHTML5, setVersionInfo, handleFocus, strings, initMovie, preInit, domContentLoaded, winOnLoad, didDCLoaded, getDocument, createMovie, catchError, setPolling, initDebug, debugLevels = ['log', 'info', 'warn', 'error'], defaultFlashVersion = 8, disableObject, failSafely, normalizeMovieURL, oRemoved = null, oRemovedHTML = null, str, flashBlockHandler, getSWFCSS, swfCSS, toggleDebug, loopFix, policyFix, complain, idCheck, waitingForEI = false, initPending = false, startTimer, stopTimer, timerExecute, h5TimerCount = 0, h5IntervalTimer = null, parseURL, messages = [],
269
269
  canIgnoreFlash, needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages, wrapCallback, idCounter = 0,
270
- is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)), isFirefox = (ua.match(/firefox/i)),
270
+ is_iDevice = ua.match(/(ipad|iphone|ipod)/i), isAndroid = ua.match(/android/i), isIE = ua.match(/msie/i), isWebkit = ua.match(/webkit/i), isSafari = (ua.match(/safari/i) && !ua.match(/chrome/i)), isOpera = (ua.match(/opera/i)),
271
271
  mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
272
272
  isBadSafari = (!wl.match(/usehtml5audio/i) && !wl.match(/sm2\-ignorebadua/i) && isSafari && !ua.match(/silk/i) && ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 (excluding Kindle Fire, "Silk") occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159
273
273
  hasConsole = (window.console !== _undefined && console.log !== _undefined), isFocused = (doc.hasFocus !== _undefined?doc.hasFocus():null), tryInitOnFocus = (isSafari && (doc.hasFocus === _undefined || !doc.hasFocus())), okToDisable = !tryInitOnFocus, flashMIME = /(mp3|mp4|mpa|m4a|m4b)/i, msecScale = 1000,
274
274
  emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)
275
+ emptyWAV = 'data:audio/wave;base64,/UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQIAAAD//w==', // tiny WAV for HTML5 unloading
275
276
  overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
276
277
  http = (!overHTTP ? 'http:/'+'/' : ''),
277
278
  // mp3, mp4, aac etc.
@@ -1009,7 +1010,7 @@ function SoundManager(smURL, smID) {
1009
1010
 
1010
1011
  if (!result && needsFlash) {
1011
1012
  // if flash 9, test netStream (movieStar) types as well.
1012
- result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null);
1013
+ result = (sMIME && sm2.ok() ? !!((fV > 8 ? sMIME.match(netStreamMimeTypes) : null) || sMIME.match(sm2.mimePattern)) : null); // TODO: make less "weird" (per JSLint)
1013
1014
  }
1014
1015
 
1015
1016
  return result;
@@ -1612,10 +1613,6 @@ function SoundManager(smURL, smID) {
1612
1613
 
1613
1614
  s._a._called_load = true;
1614
1615
 
1615
- if (instanceOptions.autoPlay) {
1616
- s.play();
1617
- }
1618
-
1619
1616
  } else {
1620
1617
 
1621
1618
  sm2._wD(s.id + ': Ignoring request to load again');
@@ -1929,8 +1926,8 @@ function SoundManager(smURL, smID) {
1929
1926
  sm2._wD(fN + 'Beginning load for from/to case');
1930
1927
 
1931
1928
  s.load({
1932
- // TODO: was _oncanplay. Sounds wrong.
1933
- oncanplay: onready
1929
+ // note: custom HTML5-only event added for from/to implementation.
1930
+ _oncanplay: onready
1934
1931
  });
1935
1932
 
1936
1933
  exit = false;
@@ -2026,7 +2023,7 @@ function SoundManager(smURL, smID) {
2026
2023
  audioClone = new Audio(s._iO.url);
2027
2024
 
2028
2025
  onended = function() {
2029
- event.remove(audioClone, 'onended', onended);
2026
+ event.remove(audioClone, 'ended', onended);
2030
2027
  s._onfinish(s);
2031
2028
  // cleanup
2032
2029
  html5Unload(audioClone);
@@ -2045,6 +2042,16 @@ function SoundManager(smURL, smID) {
2045
2042
 
2046
2043
  event.add(audioClone, 'ended', onended);
2047
2044
 
2045
+ // apply volume to clones, too
2046
+ if (s._iO.volume !== undefined) {
2047
+ audioClone.volume = Math.max(0, Math.min(1, s._iO.volume/100));
2048
+ }
2049
+
2050
+ // playing multiple muted sounds? if you do this, you're weird ;) - but let's cover it.
2051
+ if (s.muted) {
2052
+ audioClone.muted = true;
2053
+ }
2054
+
2048
2055
  if (s._iO.position) {
2049
2056
  // HTML5 audio can't seek before onplay() event has fired.
2050
2057
  // wait for canplay, then seek to position and start playback.
@@ -2431,6 +2438,10 @@ function SoundManager(smURL, smID) {
2431
2438
  if (!s.isHTML5) {
2432
2439
  flash._setVolume(s.id, (sm2.muted && !s.muted) || s.muted?0:nVol);
2433
2440
  } else if (s._a) {
2441
+ if (sm2.muted && !s.muted) {
2442
+ s.muted = true;
2443
+ s._a.muted = true;
2444
+ }
2434
2445
  // valid range: 0-1
2435
2446
  s._a.volume = Math.max(0, Math.min(1, nVol/100));
2436
2447
  }
@@ -2565,7 +2576,7 @@ function SoundManager(smURL, smID) {
2565
2576
  this._processOnPosition = function() {
2566
2577
 
2567
2578
  var i, item, j = onPositionItems.length;
2568
-
2579
+
2569
2580
  if (!j || !s.playState || onPositionFired >= j) {
2570
2581
  return false;
2571
2582
  }
@@ -2576,9 +2587,10 @@ function SoundManager(smURL, smID) {
2576
2587
  item.fired = true;
2577
2588
  onPositionFired++;
2578
2589
  item.method.apply(item.scope, [item.position]);
2590
+ j = onPositionItems.length; // reset j -- onPositionItems.length can be changed in the item callback above... occasionally breaking the loop.
2579
2591
  }
2580
2592
  }
2581
-
2593
+
2582
2594
  return true;
2583
2595
 
2584
2596
  };
@@ -2668,7 +2680,7 @@ function SoundManager(smURL, smID) {
2668
2680
 
2669
2681
  for (item in op) {
2670
2682
  if (op.hasOwnProperty(item)) {
2671
- s.onPosition(parseInt(item, 10), op[item]);
2683
+ s.onPosition(parseInt(item, 10), op[item]);
2672
2684
  }
2673
2685
  }
2674
2686
 
@@ -2911,9 +2923,11 @@ function SoundManager(smURL, smID) {
2911
2923
 
2912
2924
  if (!sameURL) {
2913
2925
 
2914
- // don't retain onPosition() stuff with new URL.
2926
+ // don't retain onPosition() stuff with new URLs.
2915
2927
 
2916
- resetProperties(false);
2928
+ if (lastURL) {
2929
+ resetProperties(false);
2930
+ }
2917
2931
 
2918
2932
  // assign new HTML5 URL
2919
2933
 
@@ -2934,6 +2948,7 @@ function SoundManager(smURL, smID) {
2934
2948
  if (instanceOptions.autoLoad || instanceOptions.autoPlay) {
2935
2949
 
2936
2950
  s._a = new Audio(instanceOptions.url);
2951
+ s._a.load();
2937
2952
 
2938
2953
  } else {
2939
2954
 
@@ -3275,7 +3290,7 @@ function SoundManager(smURL, smID) {
3275
3290
 
3276
3291
  /**
3277
3292
  * internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
3278
- *
3293
+ *
3279
3294
  * @param {object} oData
3280
3295
  */
3281
3296
 
@@ -3294,7 +3309,7 @@ function SoundManager(smURL, smID) {
3294
3309
  /**
3295
3310
  * internal: flash 9 + NetStream (MovieStar/RTMP-only) feature
3296
3311
  * RTMP may include song title, MovieStar content may include encoding info
3297
- *
3312
+ *
3298
3313
  * @param {array} oMDProps (names)
3299
3314
  * @param {array} oMDData (values)
3300
3315
  */
@@ -3319,7 +3334,7 @@ function SoundManager(smURL, smID) {
3319
3334
  /**
3320
3335
  * internal: flash 8 + flash 9 ID3 feature
3321
3336
  * may include artist, song title etc.
3322
- *
3337
+ *
3323
3338
  * @param {array} oID3Props (names)
3324
3339
  * @param {array} oID3Data (values)
3325
3340
  */
@@ -3394,7 +3409,7 @@ function SoundManager(smURL, smID) {
3394
3409
 
3395
3410
  getDocument = function() {
3396
3411
 
3397
- return (doc.body || doc._docElement || doc.getElementsByTagName('div')[0]);
3412
+ return (doc.body || doc.getElementsByTagName('div')[0]);
3398
3413
 
3399
3414
  };
3400
3415
 
@@ -3851,7 +3866,7 @@ function SoundManager(smURL, smID) {
3851
3866
  // note: can fire repeatedly after "loaded" event, due to use of HTTP range/partials
3852
3867
 
3853
3868
  var s = this._s,
3854
- i, j, str, buffered = 0,
3869
+ i, j, progStr, buffered = 0,
3855
3870
  isProgress = (e.type === 'progress'),
3856
3871
  ranges = e.target.buffered,
3857
3872
  // firefox 3.6 implements e.loaded/total (bytes)
@@ -3883,12 +3898,12 @@ function SoundManager(smURL, smID) {
3883
3898
 
3884
3899
  // <d>
3885
3900
  if (isProgress && ranges.length > 1) {
3886
- str = [];
3901
+ progStr = [];
3887
3902
  j = ranges.length;
3888
3903
  for (i=0; i<j; i++) {
3889
- str.push(e.target.buffered.start(i)*msecScale +'-'+ e.target.buffered.end(i)*msecScale);
3904
+ progStr.push(e.target.buffered.start(i)*msecScale +'-'+ e.target.buffered.end(i)*msecScale);
3890
3905
  }
3891
- sm2._wD(this._s.id + ': progress, timeRanges: ' + str.join(', '));
3906
+ sm2._wD(this._s.id + ': progress, timeRanges: ' + progStr.join(', '));
3892
3907
  }
3893
3908
 
3894
3909
  if (isProgress && !isNaN(loaded)) {
@@ -3997,8 +4012,9 @@ function SoundManager(smURL, smID) {
3997
4012
 
3998
4013
  if (oAudio) {
3999
4014
 
4000
- // Firefox likes '' for unload (used to work, but no longer?) - however, may request hosting page URL (bad.) Most other UAs dislike '' and fail to unload.
4001
- url = (isSafari && !is_iDevice ? null : (isFirefox ? emptyURL : null));
4015
+ // Firefox and Chrome accept short WAVe data: URIs. Chome dislikes audio/wav, but accepts audio/wav for data: MIME.
4016
+ // Desktop Safari complains / fails on data: URI, so it gets about:blank.
4017
+ url = (isSafari ? emptyURL : (sm2.html5.canPlayType('audio/wav') ? emptyWAV : emptyURL));
4002
4018
 
4003
4019
  oAudio.src = url;
4004
4020
 
@@ -4113,7 +4129,7 @@ function SoundManager(smURL, smID) {
4113
4129
 
4114
4130
  function cp(m) {
4115
4131
 
4116
- var canPlay, i, j,
4132
+ var canPlay, j,
4117
4133
  result = false,
4118
4134
  isOK = false;
4119
4135
 
@@ -4257,20 +4273,25 @@ function SoundManager(smURL, smID) {
4257
4273
  // arguments: o [,items to replace]
4258
4274
  // <d>
4259
4275
 
4276
+ var args,
4277
+ i, j, o,
4278
+ sstr;
4279
+
4260
4280
  // real array, please
4261
- var args = slice.call(arguments),
4281
+ args = slice.call(arguments);
4282
+
4283
+ // first argument
4284
+ o = args.shift();
4262
4285
 
4263
- // first arg
4264
- o = args.shift(),
4286
+ sstr = (strings && strings[o] ? strings[o] : '');
4265
4287
 
4266
- str = (strings && strings[o]?strings[o]:''), i, j;
4267
- if (str && args && args.length) {
4288
+ if (sstr && args && args.length) {
4268
4289
  for (i = 0, j = args.length; i < j; i++) {
4269
- str = str.replace('%s', args[i]);
4290
+ sstr = sstr.replace('%s', args[i]);
4270
4291
  }
4271
4292
  }
4272
4293
 
4273
- return str;
4294
+ return sstr;
4274
4295
  // </d>
4275
4296
 
4276
4297
  };
@@ -4889,7 +4910,7 @@ function SoundManager(smURL, smID) {
4889
4910
  if (h5IntervalTimer === null && h5TimerCount === 0) {
4890
4911
 
4891
4912
  h5IntervalTimer = setInterval(timerExecute, sm2.html5PollingInterval);
4892
-
4913
+
4893
4914
  }
4894
4915
 
4895
4916
  h5TimerCount++;
@@ -5089,7 +5110,10 @@ function SoundManager(smURL, smID) {
5089
5110
 
5090
5111
  // <d>
5091
5112
 
5092
- var options = [], title, str = [], delimiter = ' + ';
5113
+ var options = [],
5114
+ title,
5115
+ msg = [],
5116
+ delimiter = ' + ';
5093
5117
 
5094
5118
  title = 'SoundManager ' + sm2.version + (!sm2.html5Only && sm2.useHTML5Audio ? (sm2.hasHTML5 ? ' + HTML5 audio' : ', no HTML5 audio support') : '');
5095
5119
 
@@ -5132,10 +5156,10 @@ function SoundManager(smURL, smID) {
5132
5156
  }
5133
5157
 
5134
5158
  if (options.length) {
5135
- str = str.concat([options.join(delimiter)]);
5159
+ msg = msg.concat([options.join(delimiter)]);
5136
5160
  }
5137
5161
 
5138
- sm2._wD(title + (str.length ? delimiter + str.join(', ') : ''), 1);
5162
+ sm2._wD(title + (msg.length ? delimiter + msg.join(', ') : ''), 1);
5139
5163
 
5140
5164
  showSupport();
5141
5165
 
@@ -5404,6 +5428,27 @@ function SoundManager(smURL, smID) {
5404
5428
 
5405
5429
  };
5406
5430
 
5431
+ rebootIntoHTML5 = function() {
5432
+
5433
+ // special case: try for a reboot with preferFlash: false, if 100% HTML5 mode is possible and useFlashBlock is not enabled.
5434
+
5435
+ window.setTimeout(function() {
5436
+
5437
+ complain(smc + 'useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false...');
5438
+
5439
+ sm2.setup({
5440
+ preferFlash: false
5441
+ }).reboot();
5442
+
5443
+ // if for some reason you want to detect this case, use an ontimeout() callback and look for html5Only and didFlashBlock == true.
5444
+ sm2.didFlashBlock = true;
5445
+
5446
+ sm2.beginDelayedInit();
5447
+
5448
+ }, 1);
5449
+
5450
+ };
5451
+
5407
5452
  waitForEI = function() {
5408
5453
 
5409
5454
  var p,
@@ -5421,7 +5466,7 @@ function SoundManager(smURL, smID) {
5421
5466
  waitingForEI = true;
5422
5467
  event.remove(window, 'load', delayWaitForEI);
5423
5468
 
5424
- if (tryInitOnFocus && !isFocused) {
5469
+ if (hasFlash && tryInitOnFocus && !isFocused) {
5425
5470
  // Safari won't load flash in background tabs, only when focused.
5426
5471
  _wDS('waitFocus');
5427
5472
  return false;
@@ -5448,18 +5493,28 @@ function SoundManager(smURL, smID) {
5448
5493
 
5449
5494
  // <d>
5450
5495
  if (!didInit) {
5496
+
5451
5497
  sm2._wD(sm + ': No Flash response within expected time. Likely causes: ' + (p === 0 ? 'SWF load failed, ':'') + 'Flash blocked or JS-Flash security error.' + (sm2.debugFlash?' ' + str('checkSWF'):''), 2);
5498
+
5452
5499
  if (!overHTTP && p) {
5500
+
5453
5501
  _wDS('localFail', 2);
5502
+
5454
5503
  if (!sm2.debugFlash) {
5455
5504
  _wDS('tryDebug', 2);
5456
5505
  }
5506
+
5457
5507
  }
5508
+
5458
5509
  if (p === 0) {
5510
+
5459
5511
  // if 0 (not null), probably a 404.
5460
5512
  sm2._wD(str('swf404', sm2.url), 1);
5513
+
5461
5514
  }
5515
+
5462
5516
  debugTS('flashtojs', false, ': Timed out' + overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');
5517
+
5463
5518
  }
5464
5519
  // </d>
5465
5520
 
@@ -5469,7 +5524,7 @@ function SoundManager(smURL, smID) {
5469
5524
 
5470
5525
  if (p === null) {
5471
5526
 
5472
- // SWF failed. Maybe blocked.
5527
+ // SWF failed to report load progress. Possibly blocked.
5473
5528
 
5474
5529
  if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) {
5475
5530
 
@@ -5487,29 +5542,14 @@ function SoundManager(smURL, smID) {
5487
5542
 
5488
5543
  if (!sm2.useFlashBlock && canIgnoreFlash) {
5489
5544
 
5490
- // special case: try for a reboot with preferFlash: false, if 100% HTML5 mode is possible and useFlashBlock is not enabled.
5491
-
5492
- window.setTimeout(function() {
5493
-
5494
- complain(smc + 'useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false...');
5495
-
5496
- sm2.setup({
5497
- preferFlash: false
5498
- }).reboot();
5499
-
5500
- // if for some reason you want to detect this case, use an ontimeout() callback and look for html5Only and didFlashBlock == true.
5501
- sm2.didFlashBlock = true;
5502
-
5503
- sm2.beginDelayedInit();
5504
-
5505
- }, 1);
5545
+ rebootIntoHTML5();
5506
5546
 
5507
5547
  } else {
5508
5548
 
5509
5549
  _wDS('waitForever');
5510
5550
 
5511
5551
  // fire any regular registered ontimeout() listeners.
5512
- processOnEvents({type:'ontimeout', ignoreInit: true});
5552
+ processOnEvents({type:'ontimeout', ignoreInit: true, error: {type: 'INIT_FLASHBLOCK'}});
5513
5553
 
5514
5554
  }
5515
5555
 
@@ -5517,7 +5557,7 @@ function SoundManager(smURL, smID) {
5517
5557
 
5518
5558
  } else {
5519
5559
 
5520
- // flash loaded? Shouldn't be a blocking issue, then.
5560
+ // SWF loaded? Shouldn't be a blocking issue, then.
5521
5561
 
5522
5562
  if (sm2.flashLoadTimeout === 0) {
5523
5563
 
@@ -5525,11 +5565,20 @@ function SoundManager(smURL, smID) {
5525
5565
 
5526
5566
  } else {
5527
5567
 
5528
- failSafely(true);
5568
+ if (!sm2.useFlashBlock && canIgnoreFlash) {
5569
+
5570
+ rebootIntoHTML5();
5571
+
5572
+ } else {
5573
+
5574
+ failSafely(true);
5575
+
5576
+ }
5529
5577
 
5530
5578
  }
5531
5579
 
5532
5580
  }
5581
+
5533
5582
  }
5534
5583
 
5535
5584
  }, sm2.flashLoadTimeout);
@@ -5619,11 +5668,10 @@ function SoundManager(smURL, smID) {
5619
5668
 
5620
5669
  if (!wasTimeout) {
5621
5670
  didInit = true;
5622
- if (disabled) {
5623
- error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
5624
- }
5625
5671
  }
5626
5672
 
5673
+ error = {type: (!hasFlash && needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};
5674
+
5627
5675
  sm2._wD('SoundManager 2 ' + (disabled ? 'failed to load' : 'loaded') + ' (' + (disabled ? 'Flash security/load error' : 'OK') + ')', disabled ? 2: 1);
5628
5676
 
5629
5677
  if (disabled || bNoDisable) {
@@ -5783,7 +5831,7 @@ function SoundManager(smURL, smID) {
5783
5831
 
5784
5832
  var a = 'sm2-usehtml5audio=',
5785
5833
  a2 = 'sm2-preferflash=',
5786
- b = null,
5834
+ b = null,
5787
5835
  b2 = null,
5788
5836
  l = wl.toLowerCase();
5789
5837
 
@@ -5811,7 +5859,7 @@ function SoundManager(smURL, smID) {
5811
5859
  // </d>
5812
5860
 
5813
5861
  if (!hasFlash && sm2.hasHTML5) {
5814
- sm2._wD('SoundManager: No Flash detected' + (!sm2.useHTML5Audio ? ', enabling HTML5.' : '. Trying HTML5-only mode.'), 1);
5862
+ sm2._wD('SoundManager 2: No Flash detected' + (!sm2.useHTML5Audio ? ', enabling HTML5.' : '. Trying HTML5-only mode.'), 1);
5815
5863
  sm2.setup({
5816
5864
  'useHTML5Audio': true,
5817
5865
  // make sure we aren't preferring flash, either
@@ -5938,4 +5986,4 @@ if (window.SM2_DEFER === undefined || !SM2_DEFER) {
5938
5986
  window.SoundManager = SoundManager; // constructor
5939
5987
  window.soundManager = soundManager; // public API, flash callbacks etc.
5940
5988
 
5941
- }(window));
5989
+ }(window));