soundmanager-rails 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,11 +8,11 @@
8
8
  * Code provided under the BSD License:
9
9
  * http://schillmania.com/projects/soundmanager2/license.txt
10
10
  *
11
- * V2.97a.20130101
11
+ * V2.97a.20130512
12
12
  */
13
13
 
14
14
  /*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
15
- /*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */
15
+ /*jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true, todo: true */
16
16
 
17
17
  (function(window, _undefined) {
18
18
  "use strict";
@@ -37,7 +37,8 @@ function SoundManager(smURL, smID) {
37
37
  'useHTML5Audio': true,
38
38
  'html5Test': /^(probably|maybe)$/i,
39
39
  'preferFlash': true,
40
- 'noSWFCache': false
40
+ 'noSWFCache': false,
41
+ 'idPrefix': 'sound'
41
42
  };
42
43
  this.defaultOptions = {
43
44
  'autoLoad': false,
@@ -93,6 +94,10 @@ function SoundManager(smURL, smID) {
93
94
  'type': ['audio/ogg; codecs=vorbis'],
94
95
  'required': false
95
96
  },
97
+ 'opus': {
98
+ 'type': ['audio/ogg; codecs=opus', 'audio/opus'],
99
+ 'required': false
100
+ },
96
101
  'wav': {
97
102
  'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],
98
103
  'required': false
@@ -102,7 +107,7 @@ function SoundManager(smURL, smID) {
102
107
  this.id = (smID || 'sm2movie');
103
108
  this.debugID = 'soundmanager-debug';
104
109
  this.debugURLParam = /([#?&])debug=1/i;
105
- this.versionNumber = 'V2.97a.20130101';
110
+ this.versionNumber = 'V2.97a.20130512';
106
111
  this.version = null;
107
112
  this.movieURL = null;
108
113
  this.altURL = null;
@@ -135,11 +140,11 @@ function SoundManager(smURL, smID) {
135
140
  this.ignoreFlash = false;
136
141
  var SMSound,
137
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 = [],
138
- needsFlash = null, featureCheck, html5OK, html5CanPlay, html5Ext, html5Unload, domContentLoadedIE, testHTML5, event, slice = Array.prototype.slice, useGlobalHTML5Audio = false, lastGlobalHTML5URL, hasFlash, detectFlash, badSafariFix, html5_events, showSupport, flushMessages,
139
- 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)),
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)),
140
145
  mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
141
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)),
142
- 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,
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,
143
148
  emptyURL = 'about:blank',
144
149
  overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
145
150
  http = (!overHTTP ? 'http:/'+'/' : ''),
@@ -169,19 +174,20 @@ function SoundManager(smURL, smID) {
169
174
  this.setup = function(options) {
170
175
  var noURL = (!sm2.url);
171
176
  if (options !== _undefined && didInit && needsFlash && sm2.ok() && (options.flashVersion !== _undefined || options.url !== _undefined || options.html5Test !== _undefined)) {
172
- complain(str('setupLate'));
173
177
  }
174
178
  assign(options);
175
- if (noURL && didDCLoaded && options.url !== _undefined) {
176
- sm2.beginDelayedInit();
177
- }
178
- if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
179
- setTimeout(domContentLoaded, 1);
179
+ if (options) {
180
+ if (noURL && didDCLoaded && options.url !== _undefined) {
181
+ sm2.beginDelayedInit();
182
+ }
183
+ if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
184
+ setTimeout(domContentLoaded, 1);
185
+ }
180
186
  }
181
187
  return sm2;
182
188
  };
183
189
  this.ok = function() {
184
- return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5));
190
+ return (needsFlash ? (didInit && !disabled) : (sm2.useHTML5Audio && sm2.hasHTML5));
185
191
  };
186
192
  this.supported = this.ok;
187
193
  this.getMovie = function(smID) {
@@ -190,7 +196,6 @@ function SoundManager(smURL, smID) {
190
196
  this.createSound = function(oOptions, _url) {
191
197
  var cs, cs_string, options, oSound = null;
192
198
  if (!didInit || !sm2.ok()) {
193
- complain(cs_string);
194
199
  return false;
195
200
  }
196
201
  if (_url !== _undefined) {
@@ -201,6 +206,9 @@ function SoundManager(smURL, smID) {
201
206
  }
202
207
  options = mixin(oOptions);
203
208
  options.url = parseURL(options.url);
209
+ if (options.id === undefined) {
210
+ options.id = sm2.setupOptions.idPrefix + (idCounter++);
211
+ }
204
212
  if (idCheck(options.id, true)) {
205
213
  return sm2.sounds[options.id];
206
214
  }
@@ -214,9 +222,15 @@ function SoundManager(smURL, smID) {
214
222
  oSound = make();
215
223
  oSound._setup_html5(options);
216
224
  } else {
225
+ if (sm2.html5Only) {
226
+ return make();
227
+ }
228
+ if (sm2.html5.usingFlash && options.url && options.url.match(/data\:/i)) {
229
+ return make();
230
+ }
217
231
  if (fV > 8) {
218
232
  if (options.isMovieStar === null) {
219
- options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern));
233
+ options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || (options.url && options.url.match(netStreamPattern)));
220
234
  }
221
235
  }
222
236
  options = policyFix(options, cs);
@@ -288,13 +302,16 @@ function SoundManager(smURL, smID) {
288
302
  return sm2.sounds[sID].clearOnPosition(nPosition, oMethod);
289
303
  };
290
304
  this.play = function(sID, oOptions) {
291
- var result = false;
305
+ var result = null,
306
+ overloaded = (oOptions && !(oOptions instanceof Object));
292
307
  if (!didInit || !sm2.ok()) {
293
- complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK'));
294
- return result;
308
+ return false;
295
309
  }
296
- if (!idCheck(sID)) {
297
- if (!(oOptions instanceof Object)) {
310
+ if (!idCheck(sID, overloaded)) {
311
+ if (!overloaded) {
312
+ return false;
313
+ }
314
+ if (overloaded) {
298
315
  oOptions = {
299
316
  url: oOptions
300
317
  };
@@ -303,9 +320,15 @@ function SoundManager(smURL, smID) {
303
320
  oOptions.id = sID;
304
321
  result = sm2.createSound(oOptions).play();
305
322
  }
306
- return result;
323
+ } else if (overloaded) {
324
+ oOptions = {
325
+ url: oOptions
326
+ };
307
327
  }
308
- return sm2.sounds[sID].play(oOptions);
328
+ if (result === null) {
329
+ result = sm2.sounds[sID].play(oOptions);
330
+ }
331
+ return result;
309
332
  };
310
333
  this.start = this.play;
311
334
  this.setPosition = function(sID, nMsecOffset) {
@@ -471,7 +494,7 @@ function SoundManager(smURL, smID) {
471
494
  };
472
495
  this.getSoundById = function(sID, _suppressDebug) {
473
496
  if (!sID) {
474
- throw new Error(sm + '.getSoundById(): sID is null/_undefined');
497
+ return null;
475
498
  }
476
499
  var result = sm2.sounds[sID];
477
500
  return result;
@@ -506,7 +529,7 @@ function SoundManager(smURL, smID) {
506
529
  }
507
530
  return result;
508
531
  };
509
- this._writeDebug = function(sText, sType) {
532
+ this._writeDebug = function(sText, sTypeOrObject) {
510
533
  return true;
511
534
  };
512
535
  this._wD = this._writeDebug;
@@ -530,6 +553,7 @@ function SoundManager(smURL, smID) {
530
553
  sm2.enabled = didDCLoaded = didInit = waitingForEI = initPending = didAppend = appendSuccess = disabled = useGlobalHTML5Audio = sm2.swfLoaded = false;
531
554
  sm2.soundIDs = [];
532
555
  sm2.sounds = {};
556
+ idCounter = 0;
533
557
  if (!resetEvents) {
534
558
  for (i in on_queue) {
535
559
  if (on_queue.hasOwnProperty(i)) {
@@ -579,7 +603,7 @@ function SoundManager(smURL, smID) {
579
603
  sm2.disable(true);
580
604
  };
581
605
  SMSound = function(oOptions) {
582
- var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State;
606
+ var s = this, resetProperties, add_html5_events, remove_html5_events, stop_html5_timer, start_html5_timer, attachOnPosition, onplay_called = false, onPositionItems = [], onPositionFired = 0, detachOnPosition, applyFromTo, lastURL = null, lastHTML5State, urlOmitted;
583
607
  lastHTML5State = {
584
608
  duration: null,
585
609
  time: null
@@ -594,6 +618,7 @@ function SoundManager(smURL, smID) {
594
618
  this.volume = this.options.volume;
595
619
  this.isHTML5 = false;
596
620
  this._a = null;
621
+ urlOmitted = (this.url ? false : true);
597
622
  this.id3 = {};
598
623
  this._debug = function() {
599
624
  };
@@ -615,9 +640,14 @@ function SoundManager(smURL, smID) {
615
640
  s._iO.url = parseURL(s._iO.url);
616
641
  s.instanceOptions = s._iO;
617
642
  instanceOptions = s._iO;
643
+ if (!instanceOptions.url && !s.url) {
644
+ return s;
645
+ }
618
646
  if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) {
619
647
  if (s.readyState === 3 && instanceOptions.onload) {
620
- instanceOptions.onload.apply(s, [(!!s.duration)]);
648
+ wrapCallback(s, function() {
649
+ instanceOptions.onload.apply(s, [(!!s.duration)]);
650
+ });
621
651
  }
622
652
  return s;
623
653
  }
@@ -642,6 +672,12 @@ function SoundManager(smURL, smID) {
642
672
  } else {
643
673
  }
644
674
  } else {
675
+ if (sm2.html5Only) {
676
+ return s;
677
+ }
678
+ if (s._iO.url && s._iO.url.match(/data\:/i)) {
679
+ return s;
680
+ }
645
681
  try {
646
682
  s.isHTML5 = false;
647
683
  s._iO = policyFix(loopFix(instanceOptions));
@@ -670,8 +706,7 @@ function SoundManager(smURL, smID) {
670
706
  stop_html5_timer();
671
707
  if (s._a) {
672
708
  s._a.pause();
673
- html5Unload(s._a, emptyURL);
674
- lastURL = emptyURL;
709
+ lastURL = html5Unload(s._a);
675
710
  }
676
711
  }
677
712
  resetProperties();
@@ -699,7 +734,9 @@ function SoundManager(smURL, smID) {
699
734
  }
700
735
  };
701
736
  this.play = function(oOptions, _updatePlayState) {
702
- var fN, allowMulti, a, onready, startOK = true,
737
+ var fN, allowMulti, a, onready,
738
+ audioClone, onended, oncanplay,
739
+ startOK = true,
703
740
  exit = null;
704
741
  _updatePlayState = (_updatePlayState === _undefined ? true : _updatePlayState);
705
742
  if (!oOptions) {
@@ -712,7 +749,7 @@ function SoundManager(smURL, smID) {
712
749
  s._iO = mixin(oOptions, s._iO);
713
750
  s._iO.url = parseURL(s._iO.url);
714
751
  s.instanceOptions = s._iO;
715
- if (s._iO.serverURL && !s.connected) {
752
+ if (!s.isHTML5 && s._iO.serverURL && !s.connected) {
716
753
  if (!s.getAutoPlay()) {
717
754
  s.setAutoPlay(true);
718
755
  }
@@ -725,6 +762,9 @@ function SoundManager(smURL, smID) {
725
762
  if (s.playState === 1 && !s.paused) {
726
763
  allowMulti = s._iO.multiShot;
727
764
  if (!allowMulti) {
765
+ if (s.isHTML5) {
766
+ s.setPosition(s._iO.position);
767
+ }
728
768
  exit = s;
729
769
  } else {
730
770
  }
@@ -733,15 +773,21 @@ function SoundManager(smURL, smID) {
733
773
  return exit;
734
774
  }
735
775
  if (oOptions.url && oOptions.url !== s.url) {
736
- s.load(s._iO);
776
+ if (!s.readyState && !s.isHTML5 && fV === 8 && urlOmitted) {
777
+ urlOmitted = false;
778
+ } else {
779
+ s.load(s._iO);
780
+ }
737
781
  }
738
782
  if (!s.loaded) {
739
783
  if (s.readyState === 0) {
740
- if (!s.isHTML5) {
784
+ if (!s.isHTML5 && !sm2.html5Only) {
741
785
  s._iO.autoPlay = true;
742
786
  s.load(s._iO);
743
- } else {
787
+ } else if (s.isHTML5) {
744
788
  s.load(s._iO);
789
+ } else {
790
+ exit = s;
745
791
  }
746
792
  s.instanceOptions = s._iO;
747
793
  } else if (s.readyState === 2) {
@@ -781,7 +827,7 @@ function SoundManager(smURL, smID) {
781
827
  }
782
828
  s._iO = applyFromTo();
783
829
  }
784
- if (!s.instanceCount || s._iO.multiShotEvents || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) {
830
+ if (!s.instanceCount || s._iO.multiShotEvents || (s.isHTML5 && s._iO.multiShot && !useGlobalHTML5Audio) || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) {
785
831
  s.instanceCount++;
786
832
  }
787
833
  if (s._iO.onposition && s.playState === 0) {
@@ -800,17 +846,41 @@ function SoundManager(smURL, smID) {
800
846
  s.setVolume(s._iO.volume, true);
801
847
  s.setPan(s._iO.pan, true);
802
848
  if (!s.isHTML5) {
803
- startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s._iO.position : s._iO.position / 1000), s._iO.multiShot);
849
+ startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s.position : s.position / msecScale), s._iO.multiShot || false);
804
850
  if (fV === 9 && !startOK) {
805
851
  if (s._iO.onplayerror) {
806
852
  s._iO.onplayerror.apply(s);
807
853
  }
808
854
  }
809
855
  } else {
810
- start_html5_timer();
811
- a = s._setup_html5();
812
- s.setPosition(s._iO.position);
813
- a.play();
856
+ if (s.instanceCount < 2) {
857
+ start_html5_timer();
858
+ a = s._setup_html5();
859
+ s.setPosition(s._iO.position);
860
+ a.play();
861
+ } else {
862
+ audioClone = new Audio(s._iO.url);
863
+ onended = function() {
864
+ event.remove(audioClone, 'onended', onended);
865
+ s._onfinish(s);
866
+ html5Unload(audioClone);
867
+ audioClone = null;
868
+ };
869
+ oncanplay = function() {
870
+ event.remove(audioClone, 'canplay', oncanplay);
871
+ try {
872
+ audioClone.currentTime = s._iO.position/msecScale;
873
+ } catch(err) {
874
+ }
875
+ audioClone.play();
876
+ };
877
+ event.add(audioClone, 'ended', onended);
878
+ if (s._iO.position) {
879
+ event.add(audioClone, 'canplay', oncanplay);
880
+ } else {
881
+ audioClone.play();
882
+ }
883
+ }
814
884
  }
815
885
  }
816
886
  return s;
@@ -872,12 +942,10 @@ function SoundManager(smURL, smID) {
872
942
  if (nMsecOffset === _undefined) {
873
943
  nMsecOffset = 0;
874
944
  }
875
- var original_pos,
876
- position, position1K,
945
+ var position, position1K,
877
946
  offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0)));
878
- original_pos = s.position;
879
947
  s.position = offset;
880
- position1K = s.position/1000;
948
+ position1K = s.position/msecScale;
881
949
  s._resetOnPosition(s.position);
882
950
  s._iO.position = offset;
883
951
  if (!s.isHTML5) {
@@ -896,10 +964,9 @@ function SoundManager(smURL, smID) {
896
964
  } catch(e) {
897
965
  }
898
966
  }
899
- } else {
967
+ } else if (position1K) {
968
+ return s;
900
969
  }
901
- }
902
- if (s.isHTML5) {
903
970
  if (s.paused) {
904
971
  s._onTimer(true);
905
972
  }
@@ -951,7 +1018,7 @@ function SoundManager(smURL, smID) {
951
1018
  this.togglePause = function() {
952
1019
  if (s.playState === 0) {
953
1020
  s.play({
954
- position: (fV === 9 && !s.isHTML5 ? s.position : s.position / 1000)
1021
+ position: (fV === 9 && !s.isHTML5 ? s.position : s.position / msecScale)
955
1022
  });
956
1023
  return s;
957
1024
  }
@@ -1179,7 +1246,7 @@ function SoundManager(smURL, smID) {
1179
1246
  isNew = true;
1180
1247
  }
1181
1248
  s.durationEstimate = s.duration;
1182
- time = (s._a.currentTime * 1000 || 0);
1249
+ time = (s._a.currentTime * msecScale || 0);
1183
1250
  if (time !== lastHTML5State.time) {
1184
1251
  lastHTML5State.time = time;
1185
1252
  isNew = true;
@@ -1193,7 +1260,7 @@ function SoundManager(smURL, smID) {
1193
1260
  };
1194
1261
  this._get_html5_duration = function() {
1195
1262
  var instanceOptions = s._iO,
1196
- d = (s._a && s._a.duration ? s._a.duration*1000 : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)),
1263
+ d = (s._a && s._a.duration ? s._a.duration*msecScale : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)),
1197
1264
  result = (d && !isNaN(d) && d !== Infinity ? d : null);
1198
1265
  return result;
1199
1266
  };
@@ -1201,15 +1268,15 @@ function SoundManager(smURL, smID) {
1201
1268
  a.loop = (nLoops > 1 ? 'loop' : '');
1202
1269
  };
1203
1270
  this._setup_html5 = function(oOptions) {
1204
- var instanceOptions = mixin(s._iO, oOptions), d = decodeURI,
1205
- a = useGlobalHTML5Audio ? globalHTML5Audio : s._a,
1206
- dURL = d(instanceOptions.url),
1271
+ var instanceOptions = mixin(s._iO, oOptions),
1272
+ a = useGlobalHTML5Audio ? globalHTML5Audio : s._a,
1273
+ dURL = decodeURI(instanceOptions.url),
1207
1274
  sameURL;
1208
1275
  if (useGlobalHTML5Audio) {
1209
- if (dURL === lastGlobalHTML5URL) {
1276
+ if (dURL === decodeURI(lastGlobalHTML5URL)) {
1210
1277
  sameURL = true;
1211
1278
  }
1212
- } else if (dURL === lastURL) {
1279
+ } else if (dURL === decodeURI(lastURL)) {
1213
1280
  sameURL = true;
1214
1281
  }
1215
1282
  if (a) {
@@ -1218,7 +1285,7 @@ function SoundManager(smURL, smID) {
1218
1285
  if (a._s && a._s.playState && !sameURL) {
1219
1286
  a._s.stop();
1220
1287
  }
1221
- } else if (!useGlobalHTML5Audio && dURL === d(lastURL)) {
1288
+ } else if (!useGlobalHTML5Audio && dURL === decodeURI(lastURL)) {
1222
1289
  s._apply_loop(a, instanceOptions.loops);
1223
1290
  return a;
1224
1291
  }
@@ -1291,7 +1358,9 @@ function SoundManager(smURL, smID) {
1291
1358
  s.readyState = loadOK?3:2;
1292
1359
  s._onbufferchange(0);
1293
1360
  if (s._iO.onload) {
1294
- s._iO.onload.apply(s, [loadOK]);
1361
+ wrapCallback(s, function() {
1362
+ s._iO.onload.apply(s, [loadOK]);
1363
+ });
1295
1364
  }
1296
1365
  return true;
1297
1366
  };
@@ -1341,7 +1410,9 @@ function SoundManager(smURL, smID) {
1341
1410
  }
1342
1411
  if (!s.instanceCount || s._iO.multiShotEvents) {
1343
1412
  if (io_onfinish) {
1344
- io_onfinish.apply(s);
1413
+ wrapCallback(s, function() {
1414
+ io_onfinish.apply(s);
1415
+ });
1345
1416
  }
1346
1417
  }
1347
1418
  }
@@ -1484,6 +1555,13 @@ function SoundManager(smURL, smID) {
1484
1555
  }
1485
1556
  return o1;
1486
1557
  };
1558
+ wrapCallback = function(oSound, callback) {
1559
+ if (!oSound.isHTML5 && fV === 8) {
1560
+ window.setTimeout(callback, 0);
1561
+ } else {
1562
+ callback();
1563
+ }
1564
+ };
1487
1565
  extraOptions = {
1488
1566
  'onready': 1,
1489
1567
  'ontimeout': 1,
@@ -1506,7 +1584,6 @@ function SoundManager(smURL, smID) {
1506
1584
  sm2.setupOptions[i] = o[i];
1507
1585
  sm2[i] = o[i];
1508
1586
  } else if (bonusOptions[i] === _undefined) {
1509
- complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
1510
1587
  result = false;
1511
1588
  } else {
1512
1589
  if (sm2[i] instanceof Function) {
@@ -1517,7 +1594,6 @@ function SoundManager(smURL, smID) {
1517
1594
  }
1518
1595
  } else {
1519
1596
  if (bonusOptions[i] === _undefined) {
1520
- complain(str((sm2[i] === _undefined ? 'setupUndef' : 'setupError'), i), 2);
1521
1597
  result = false;
1522
1598
  } else {
1523
1599
  return assign(o[i], i);
@@ -1592,7 +1668,7 @@ function SoundManager(smURL, smID) {
1592
1668
  }
1593
1669
  s._html5_canplay = true;
1594
1670
  s._onbufferchange(0);
1595
- position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/1000:null);
1671
+ position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/msecScale:null);
1596
1672
  if (s.position && this.currentTime !== position1K) {
1597
1673
  try {
1598
1674
  this.currentTime = position1K;
@@ -1641,18 +1717,17 @@ function SoundManager(smURL, smID) {
1641
1717
  isProgress = (e.type === 'progress'),
1642
1718
  ranges = e.target.buffered,
1643
1719
  loaded = (e.loaded||0),
1644
- total = (e.total||1),
1645
- scale = 1000;
1720
+ total = (e.total||1);
1646
1721
  s.buffered = [];
1647
1722
  if (ranges && ranges.length) {
1648
1723
  for (i=0, j=ranges.length; i<j; i++) {
1649
1724
  s.buffered.push({
1650
- 'start': ranges.start(i) * scale,
1651
- 'end': ranges.end(i) * scale
1725
+ 'start': ranges.start(i) * msecScale,
1726
+ 'end': ranges.end(i) * msecScale
1652
1727
  });
1653
1728
  }
1654
- buffered = (ranges.end(0) - ranges.start(0)) * scale;
1655
- loaded = buffered/(e.target.duration*scale);
1729
+ buffered = (ranges.end(0) - ranges.start(0)) * msecScale;
1730
+ loaded = Math.min(1, buffered/(e.target.duration*msecScale));
1656
1731
  }
1657
1732
  if (!isNaN(loaded)) {
1658
1733
  s._onbufferchange(0);
@@ -1681,21 +1756,28 @@ function SoundManager(smURL, smID) {
1681
1756
  };
1682
1757
  html5OK = function(iO) {
1683
1758
  var result;
1684
- if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) {
1759
+ if (!iO || (!iO.type && !iO.url && !iO.serverURL)) {
1760
+ result = false;
1761
+ } else if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) {
1685
1762
  result = false;
1686
1763
  } else {
1687
- result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only));
1764
+ result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only || iO.url.match(/data\:/i)));
1688
1765
  }
1689
1766
  return result;
1690
1767
  };
1691
- html5Unload = function(oAudio, url) {
1768
+ html5Unload = function(oAudio) {
1769
+ var url;
1692
1770
  if (oAudio) {
1771
+ url = (isSafari && !is_iDevice ? null : (isFirefox ? emptyURL : null));
1693
1772
  oAudio.src = url;
1694
- oAudio._called_load = false;
1773
+ if (oAudio._called_unload !== undefined) {
1774
+ oAudio._called_load = false;
1775
+ }
1695
1776
  }
1696
1777
  if (useGlobalHTML5Audio) {
1697
1778
  lastGlobalHTML5URL = null;
1698
1779
  }
1780
+ return url;
1699
1781
  };
1700
1782
  html5CanPlay = function(o) {
1701
1783
  if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
@@ -1746,6 +1828,8 @@ function SoundManager(smURL, smID) {
1746
1828
  };
1747
1829
  testHTML5 = function() {
1748
1830
  if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
1831
+ sm2.html5.usingFlash = true;
1832
+ needsFlash = true;
1749
1833
  return false;
1750
1834
  }
1751
1835
  var a = (Audio !== _undefined ? (isOpera && opera.version() < 10 ? new Audio(null) : new Audio()) : null),
@@ -1796,6 +1880,8 @@ function SoundManager(smURL, smID) {
1796
1880
  }
1797
1881
  support.canPlayType = (a?cp:null);
1798
1882
  sm2.html5 = mixin(sm2.html5, support);
1883
+ sm2.html5.usingFlash = featureCheck();
1884
+ needsFlash = sm2.html5.usingFlash;
1799
1885
  return true;
1800
1886
  };
1801
1887
  strings = {
@@ -1884,9 +1970,6 @@ function SoundManager(smURL, smID) {
1884
1970
  flash._setPolling(bPolling, bHighPerformance);
1885
1971
  };
1886
1972
  initDebug = function() {
1887
- if (sm2.debugURLParam.test(wl)) {
1888
- sm2.debugMode = true;
1889
- }
1890
1973
  };
1891
1974
  idCheck = this.getSoundById;
1892
1975
  getSWFCSS = function() {
@@ -2003,6 +2086,7 @@ function SoundManager(smURL, smID) {
2003
2086
  try {
2004
2087
  obj = new AX('ShockwaveFlash.ShockwaveFlash');
2005
2088
  } catch(e) {
2089
+ obj = null;
2006
2090
  }
2007
2091
  hasPlugin = (!!obj);
2008
2092
  obj = null;
@@ -2011,9 +2095,8 @@ function SoundManager(smURL, smID) {
2011
2095
  return hasPlugin;
2012
2096
  };
2013
2097
  featureCheck = function() {
2014
- var needsFlash,
2098
+ var flashNeeded,
2015
2099
  item,
2016
- result = true,
2017
2100
  formats = sm2.audioFormats,
2018
2101
  isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i)));
2019
2102
  if (isSpecial) {
@@ -2022,7 +2105,6 @@ function SoundManager(smURL, smID) {
2022
2105
  if (sm2.oMC) {
2023
2106
  sm2.oMC.style.display = 'none';
2024
2107
  }
2025
- result = false;
2026
2108
  } else {
2027
2109
  if (sm2.useHTML5Audio) {
2028
2110
  if (!sm2.html5 || !sm2.html5.canPlayType) {
@@ -2031,18 +2113,25 @@ function SoundManager(smURL, smID) {
2031
2113
  }
2032
2114
  }
2033
2115
  if (sm2.useHTML5Audio && sm2.hasHTML5) {
2116
+ canIgnoreFlash = true;
2034
2117
  for (item in formats) {
2035
2118
  if (formats.hasOwnProperty(item)) {
2036
- if ((formats[item].required && !sm2.html5.canPlayType(formats[item].type)) || (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type]))) {
2037
- needsFlash = true;
2119
+ if (formats[item].required) {
2120
+ if (!sm2.html5.canPlayType(formats[item].type)) {
2121
+ canIgnoreFlash = false;
2122
+ flashNeeded = true;
2123
+ } else if (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type])) {
2124
+ flashNeeded = true;
2125
+ }
2038
2126
  }
2039
2127
  }
2040
2128
  }
2041
2129
  }
2042
2130
  if (sm2.ignoreFlash) {
2043
- needsFlash = false;
2131
+ flashNeeded = false;
2132
+ canIgnoreFlash = true;
2044
2133
  }
2045
- sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !needsFlash);
2134
+ sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !flashNeeded);
2046
2135
  return (!sm2.html5Only);
2047
2136
  };
2048
2137
  parseURL = function(url) {
@@ -2073,7 +2162,7 @@ function SoundManager(smURL, smID) {
2073
2162
  oSound._hasTimer = true;
2074
2163
  if (!mobileHTML5 && sm2.html5PollingInterval) {
2075
2164
  if (h5IntervalTimer === null && h5TimerCount === 0) {
2076
- h5IntervalTimer = window.setInterval(timerExecute, sm2.html5PollingInterval);
2165
+ h5IntervalTimer = setInterval(timerExecute, sm2.html5PollingInterval);
2077
2166
  }
2078
2167
  h5TimerCount++;
2079
2168
  }
@@ -2090,7 +2179,7 @@ function SoundManager(smURL, smID) {
2090
2179
  timerExecute = function() {
2091
2180
  var i;
2092
2181
  if (h5IntervalTimer !== null && !h5TimerCount) {
2093
- window.clearInterval(h5IntervalTimer);
2182
+ clearInterval(h5IntervalTimer);
2094
2183
  h5IntervalTimer = null;
2095
2184
  return false;
2096
2185
  }
@@ -2129,7 +2218,7 @@ function SoundManager(smURL, smID) {
2129
2218
  };
2130
2219
  this._setSandboxType = function(sandboxType) {
2131
2220
  };
2132
- this._externalInterfaceOK = function(flashDate, swfVersion) {
2221
+ this._externalInterfaceOK = function(swfVersion) {
2133
2222
  if (sm2.swfLoaded) {
2134
2223
  return false;
2135
2224
  }
@@ -2358,7 +2447,17 @@ function SoundManager(smURL, smID) {
2358
2447
  flashBlockHandler();
2359
2448
  }
2360
2449
  } else {
2361
- processOnEvents({type:'ontimeout', ignoreInit: true});
2450
+ 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);
2458
+ } else {
2459
+ processOnEvents({type:'ontimeout', ignoreInit: true});
2460
+ }
2362
2461
  }
2363
2462
  } else {
2364
2463
  if (sm2.flashLoadTimeout === 0) {
@@ -2487,8 +2586,6 @@ function SoundManager(smURL, smID) {
2487
2586
  });
2488
2587
  }
2489
2588
  testHTML5();
2490
- sm2.html5.usingFlash = featureCheck();
2491
- needsFlash = sm2.html5.usingFlash;
2492
2589
  if (!hasFlash && needsFlash) {
2493
2590
  messages.push(strings.needFlash);
2494
2591
  sm2.setup({