soundmanager2-rails 2.97.20130324 → 2.97.20130512
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/Gemfile.lock +37 -5
- data/README.md +11 -1
- data/VERSION +1 -1
- data/soundmanager2-rails.gemspec +3 -3
- data/vendor/assets/javascripts/soundmanager2-jsmin.js +97 -94
- data/vendor/assets/javascripts/soundmanager2-nodebug-jsmin.js +70 -68
- data/vendor/assets/javascripts/soundmanager2-nodebug.js +154 -74
- data/vendor/assets/javascripts/soundmanager2.js +329 -106
- data/vendor/assets/javascripts/soundmanager2.swf +0 -0
- data/vendor/assets/javascripts/soundmanager2_debug.swf +0 -0
- data/vendor/assets/javascripts/soundmanager2_flash9.swf +0 -0
- data/vendor/assets/javascripts/soundmanager2_flash9_debug.swf +0 -0
- metadata +10 -10
@@ -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.
|
11
|
+
* V2.97a.20130512
|
12
12
|
*/
|
13
13
|
|
14
14
|
/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio, opera */
|
@@ -74,7 +74,8 @@ function SoundManager(smURL, smID) {
|
|
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
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.
|
77
|
-
'noSWFCache': false
|
77
|
+
'noSWFCache': false, // if true, appends ?ts={date} to break aggressive SWF caching.
|
78
|
+
'idPrefix': 'sound' // if an id is not provided to createSound(), this prefix is used for generated IDs - 'sound0', 'sound1' etc.
|
78
79
|
|
79
80
|
};
|
80
81
|
|
@@ -188,7 +189,7 @@ function SoundManager(smURL, smID) {
|
|
188
189
|
|
189
190
|
// dynamic attributes
|
190
191
|
|
191
|
-
this.versionNumber = 'V2.97a.
|
192
|
+
this.versionNumber = 'V2.97a.20130512';
|
192
193
|
this.version = null;
|
193
194
|
this.movieURL = null;
|
194
195
|
this.altURL = null;
|
@@ -265,11 +266,11 @@ function SoundManager(smURL, smID) {
|
|
265
266
|
|
266
267
|
var SMSound,
|
267
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
|
-
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,
|
269
|
-
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)),
|
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
271
|
mobileHTML5 = (ua.match(/(mobile|pre\/|xoom)/i) || is_iDevice || isAndroid),
|
271
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
|
272
|
-
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,
|
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,
|
273
274
|
emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)
|
274
275
|
overHTTP = (doc.location?doc.location.protocol.match(/http/i):null),
|
275
276
|
http = (!overHTTP ? 'http:/'+'/' : ''),
|
@@ -341,14 +342,18 @@ function SoundManager(smURL, smID) {
|
|
341
342
|
|
342
343
|
// special case 1: "Late setup". SM2 loaded normally, but user didn't assign flash URL eg., setup({url:...}) before SM2 init. Treat as delayed init.
|
343
344
|
|
344
|
-
if (
|
345
|
-
|
346
|
-
|
345
|
+
if (options) {
|
346
|
+
|
347
|
+
if (noURL && didDCLoaded && options.url !== _undefined) {
|
348
|
+
sm2.beginDelayedInit();
|
349
|
+
}
|
350
|
+
|
351
|
+
// special case 2: If lazy-loading SM2 (DOMContentLoaded has already happened) and user calls setup() with url: parameter, try to init ASAP.
|
347
352
|
|
348
|
-
|
353
|
+
if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
|
354
|
+
setTimeout(domContentLoaded, 1);
|
355
|
+
}
|
349
356
|
|
350
|
-
if (!didDCLoaded && options.url !== _undefined && doc.readyState === 'complete') {
|
351
|
-
setTimeout(domContentLoaded, 1);
|
352
357
|
}
|
353
358
|
|
354
359
|
return sm2;
|
@@ -357,7 +362,7 @@ function SoundManager(smURL, smID) {
|
|
357
362
|
|
358
363
|
this.ok = function() {
|
359
364
|
|
360
|
-
return (needsFlash?(didInit && !disabled):(sm2.useHTML5Audio && sm2.hasHTML5));
|
365
|
+
return (needsFlash ? (didInit && !disabled) : (sm2.useHTML5Audio && sm2.hasHTML5));
|
361
366
|
|
362
367
|
};
|
363
368
|
|
@@ -392,7 +397,7 @@ function SoundManager(smURL, smID) {
|
|
392
397
|
}
|
393
398
|
|
394
399
|
if (_url !== _undefined) {
|
395
|
-
// function overloading in JS! :) ..assume simple createSound(id,url) use case
|
400
|
+
// function overloading in JS! :) ..assume simple createSound(id, url) use case
|
396
401
|
oOptions = {
|
397
402
|
'id': oOptions,
|
398
403
|
'url': _url
|
@@ -404,12 +409,17 @@ function SoundManager(smURL, smID) {
|
|
404
409
|
|
405
410
|
options.url = parseURL(options.url);
|
406
411
|
|
412
|
+
// generate an id, if needed.
|
413
|
+
if (options.id === undefined) {
|
414
|
+
options.id = sm2.setupOptions.idPrefix + (idCounter++);
|
415
|
+
}
|
416
|
+
|
407
417
|
// <d>
|
408
418
|
if (options.id.toString().charAt(0).match(/^[0-9]$/)) {
|
409
419
|
sm2._wD(cs + str('badID', options.id), 2);
|
410
420
|
}
|
411
421
|
|
412
|
-
sm2._wD(cs + options.id + ' (' + options.url + ')', 1);
|
422
|
+
sm2._wD(cs + options.id + (options.url ? ' (' + options.url + ')' : ''), 1);
|
413
423
|
// </d>
|
414
424
|
|
415
425
|
if (idCheck(options.id, true)) {
|
@@ -434,10 +444,23 @@ function SoundManager(smURL, smID) {
|
|
434
444
|
|
435
445
|
} else {
|
436
446
|
|
447
|
+
if (sm2.html5Only) {
|
448
|
+
sm2._wD(options.id + ': No HTML5 support for this sound, and no Flash. Exiting.');
|
449
|
+
return make();
|
450
|
+
}
|
451
|
+
|
452
|
+
// TODO: Move HTML5/flash checks into generic URL parsing/handling function.
|
453
|
+
|
454
|
+
if (sm2.html5.usingFlash && options.url && options.url.match(/data\:/i)) {
|
455
|
+
// data: URIs not supported by Flash, either.
|
456
|
+
sm2._wD(options.id + ': data: URIs not supported via Flash. Exiting.');
|
457
|
+
return make();
|
458
|
+
}
|
459
|
+
|
437
460
|
if (fV > 8) {
|
438
461
|
if (options.isMovieStar === null) {
|
439
462
|
// attempt to detect MPEG-4 formats
|
440
|
-
options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || options.url.match(netStreamPattern));
|
463
|
+
options.isMovieStar = !!(options.serverURL || (options.type ? options.type.match(netStreamMimeTypes) : false) || (options.url && options.url.match(netStreamPattern)));
|
441
464
|
}
|
442
465
|
// <d>
|
443
466
|
if (options.isMovieStar) {
|
@@ -603,30 +626,50 @@ function SoundManager(smURL, smID) {
|
|
603
626
|
|
604
627
|
this.play = function(sID, oOptions) {
|
605
628
|
|
606
|
-
var result =
|
629
|
+
var result = null,
|
630
|
+
// legacy function-overloading use case: play('mySound', '/path/to/some.mp3');
|
631
|
+
overloaded = (oOptions && !(oOptions instanceof Object));
|
607
632
|
|
608
633
|
if (!didInit || !sm2.ok()) {
|
609
634
|
complain(sm + '.play(): ' + str(!didInit?'notReady':'notOK'));
|
610
|
-
return
|
635
|
+
return false;
|
611
636
|
}
|
612
637
|
|
613
|
-
if (!idCheck(sID)) {
|
614
|
-
|
615
|
-
|
638
|
+
if (!idCheck(sID, overloaded)) {
|
639
|
+
|
640
|
+
if (!overloaded) {
|
641
|
+
// no sound found for the given ID. Bail.
|
642
|
+
return false;
|
643
|
+
}
|
644
|
+
|
645
|
+
if (overloaded) {
|
616
646
|
oOptions = {
|
617
647
|
url: oOptions
|
618
648
|
};
|
619
649
|
}
|
650
|
+
|
620
651
|
if (oOptions && oOptions.url) {
|
621
|
-
// overloading use case, create+play: .play('someID',{url:'/path/to.mp3'});
|
622
|
-
sm2._wD(sm + '.play():
|
652
|
+
// overloading use case, create+play: .play('someID', {url:'/path/to.mp3'});
|
653
|
+
sm2._wD(sm + '.play(): Attempting to create "' + sID + '"', 1);
|
623
654
|
oOptions.id = sID;
|
624
655
|
result = sm2.createSound(oOptions).play();
|
625
656
|
}
|
626
|
-
|
657
|
+
|
658
|
+
} else if (overloaded) {
|
659
|
+
|
660
|
+
// existing sound object case
|
661
|
+
oOptions = {
|
662
|
+
url: oOptions
|
663
|
+
};
|
664
|
+
|
627
665
|
}
|
628
666
|
|
629
|
-
|
667
|
+
if (result === null) {
|
668
|
+
// default case
|
669
|
+
result = sm2.sounds[sID].play(oOptions);
|
670
|
+
}
|
671
|
+
|
672
|
+
return result;
|
630
673
|
|
631
674
|
};
|
632
675
|
|
@@ -1025,14 +1068,14 @@ function SoundManager(smURL, smID) {
|
|
1025
1068
|
this.getSoundById = function(sID, _suppressDebug) {
|
1026
1069
|
|
1027
1070
|
if (!sID) {
|
1028
|
-
|
1071
|
+
return null;
|
1029
1072
|
}
|
1030
1073
|
|
1031
1074
|
var result = sm2.sounds[sID];
|
1032
1075
|
|
1033
1076
|
// <d>
|
1034
1077
|
if (!result && !_suppressDebug) {
|
1035
|
-
sm2._wD('"' + sID + '"
|
1078
|
+
sm2._wD(sm + '.getSoundById(): Sound "' + sID + '" not found.', 2);
|
1036
1079
|
}
|
1037
1080
|
// </d>
|
1038
1081
|
|
@@ -1236,7 +1279,7 @@ function SoundManager(smURL, smID) {
|
|
1236
1279
|
|
1237
1280
|
// <d>
|
1238
1281
|
if (sm2.soundIDs.length) {
|
1239
|
-
sm2._wD('Destroying ' + sm2.soundIDs.length + ' SMSound
|
1282
|
+
sm2._wD('Destroying ' + sm2.soundIDs.length + ' SMSound object' + (sm2.soundIDs.length !== 1 ? 's' : '') + '...');
|
1240
1283
|
}
|
1241
1284
|
// </d>
|
1242
1285
|
|
@@ -1246,7 +1289,7 @@ function SoundManager(smURL, smID) {
|
|
1246
1289
|
sm2.sounds[sm2.soundIDs[i]].destruct();
|
1247
1290
|
}
|
1248
1291
|
|
1249
|
-
// trash ze flash
|
1292
|
+
// trash ze flash (remove from the DOM)
|
1250
1293
|
|
1251
1294
|
if (flash) {
|
1252
1295
|
|
@@ -1258,8 +1301,6 @@ function SoundManager(smURL, smID) {
|
|
1258
1301
|
|
1259
1302
|
oRemoved = flash.parentNode.removeChild(flash);
|
1260
1303
|
|
1261
|
-
_wDS('flRemoved');
|
1262
|
-
|
1263
1304
|
} catch(e) {
|
1264
1305
|
|
1265
1306
|
// Remove failed? May be due to flash blockers silently removing the SWF object/embed node from the DOM. Warn and continue.
|
@@ -1279,6 +1320,8 @@ function SoundManager(smURL, smID) {
|
|
1279
1320
|
sm2.soundIDs = [];
|
1280
1321
|
sm2.sounds = {};
|
1281
1322
|
|
1323
|
+
idCounter = 0;
|
1324
|
+
|
1282
1325
|
if (!resetEvents) {
|
1283
1326
|
// reset callbacks for onready, ontimeout etc. so that they will fire again on re-init
|
1284
1327
|
for (i in on_queue) {
|
@@ -1409,7 +1452,7 @@ function SoundManager(smURL, smID) {
|
|
1409
1452
|
|
1410
1453
|
SMSound = function(oOptions) {
|
1411
1454
|
|
1412
|
-
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;
|
1455
|
+
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;
|
1413
1456
|
|
1414
1457
|
lastHTML5State = {
|
1415
1458
|
// tracks duration + position (time)
|
@@ -1441,6 +1484,9 @@ function SoundManager(smURL, smID) {
|
|
1441
1484
|
// internal HTML5 Audio() object reference
|
1442
1485
|
this._a = null;
|
1443
1486
|
|
1487
|
+
// for flash 8 special-case createSound() without url, followed by load/play with url case
|
1488
|
+
urlOmitted = (this.url ? false : true);
|
1489
|
+
|
1444
1490
|
/**
|
1445
1491
|
* SMSound() public methods
|
1446
1492
|
* ------------------------
|
@@ -1497,6 +1543,18 @@ function SoundManager(smURL, smID) {
|
|
1497
1543
|
|
1498
1544
|
sm2._wD(s.id + ': load (' + instanceOptions.url + ')');
|
1499
1545
|
|
1546
|
+
if (!instanceOptions.url && !s.url) {
|
1547
|
+
sm2._wD(s.id + ': load(): url is unassigned. Exiting.', 2);
|
1548
|
+
return s;
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
// <d>
|
1552
|
+
if (!s.isHTML5 && fV === 8 && !s.url && !instanceOptions.autoPlay) {
|
1553
|
+
// flash 8 load() -> play() won't work before onload has fired.
|
1554
|
+
sm2._wD(s.id + ': Flash 8 load() limitation: Wait for onload() before calling play().', 1);
|
1555
|
+
}
|
1556
|
+
// </d>
|
1557
|
+
|
1500
1558
|
if (instanceOptions.url === s.url && s.readyState !== 0 && s.readyState !== 2) {
|
1501
1559
|
_wDS('onURL', 1);
|
1502
1560
|
// if loaded and an onload() exists, fire immediately.
|
@@ -1548,7 +1606,8 @@ function SoundManager(smURL, smID) {
|
|
1548
1606
|
// early HTML5 implementation (non-standard)
|
1549
1607
|
s._a.autobuffer = 'auto';
|
1550
1608
|
|
1551
|
-
// standard
|
1609
|
+
// standard property, values: none / metadata / auto
|
1610
|
+
// reference: http://msdn.microsoft.com/en-us/library/ie/ff974759%28v=vs.85%29.aspx
|
1552
1611
|
s._a.preload = 'auto';
|
1553
1612
|
|
1554
1613
|
s._a._called_load = true;
|
@@ -1565,6 +1624,17 @@ function SoundManager(smURL, smID) {
|
|
1565
1624
|
|
1566
1625
|
} else {
|
1567
1626
|
|
1627
|
+
if (sm2.html5Only) {
|
1628
|
+
sm2._wD(s.id + ': No flash support. Exiting.');
|
1629
|
+
return s;
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
if (s._iO.url && s._iO.url.match(/data\:/i)) {
|
1633
|
+
// data: URIs not supported by Flash, either.
|
1634
|
+
sm2._wD(s.id + ': data: URIs not supported via Flash. Exiting.');
|
1635
|
+
return s;
|
1636
|
+
}
|
1637
|
+
|
1568
1638
|
try {
|
1569
1639
|
s.isHTML5 = false;
|
1570
1640
|
s._iO = policyFix(loopFix(instanceOptions));
|
@@ -1621,10 +1691,9 @@ function SoundManager(smURL, smID) {
|
|
1621
1691
|
if (s._a) {
|
1622
1692
|
|
1623
1693
|
s._a.pause();
|
1624
|
-
html5Unload(s._a, emptyURL);
|
1625
1694
|
|
1626
1695
|
// update empty URL, too
|
1627
|
-
lastURL =
|
1696
|
+
lastURL = html5Unload(s._a);
|
1628
1697
|
|
1629
1698
|
}
|
1630
1699
|
|
@@ -1674,7 +1743,6 @@ function SoundManager(smURL, smID) {
|
|
1674
1743
|
if (!_bFromSM) {
|
1675
1744
|
// ensure deletion from controller
|
1676
1745
|
sm2.destroySound(s.id, true);
|
1677
|
-
|
1678
1746
|
}
|
1679
1747
|
|
1680
1748
|
};
|
@@ -1688,7 +1756,9 @@ function SoundManager(smURL, smID) {
|
|
1688
1756
|
|
1689
1757
|
this.play = function(oOptions, _updatePlayState) {
|
1690
1758
|
|
1691
|
-
var fN, allowMulti, a, onready,
|
1759
|
+
var fN, allowMulti, a, onready,
|
1760
|
+
audioClone, onended, oncanplay,
|
1761
|
+
startOK = true,
|
1692
1762
|
exit = null;
|
1693
1763
|
|
1694
1764
|
// <d>
|
@@ -1718,7 +1788,7 @@ function SoundManager(smURL, smID) {
|
|
1718
1788
|
s.instanceOptions = s._iO;
|
1719
1789
|
|
1720
1790
|
// RTMP-only
|
1721
|
-
if (s._iO.serverURL && !s.connected) {
|
1791
|
+
if (!s.isHTML5 && s._iO.serverURL && !s.connected) {
|
1722
1792
|
if (!s.getAutoPlay()) {
|
1723
1793
|
sm2._wD(fN +' Netstream not connected yet - setting autoPlay');
|
1724
1794
|
s.setAutoPlay(true);
|
@@ -1736,6 +1806,10 @@ function SoundManager(smURL, smID) {
|
|
1736
1806
|
allowMulti = s._iO.multiShot;
|
1737
1807
|
if (!allowMulti) {
|
1738
1808
|
sm2._wD(fN + 'Already playing (one-shot)', 1);
|
1809
|
+
if (s.isHTML5) {
|
1810
|
+
// go back to original position.
|
1811
|
+
s.setPosition(s._iO.position);
|
1812
|
+
}
|
1739
1813
|
exit = s;
|
1740
1814
|
} else {
|
1741
1815
|
sm2._wD(fN + 'Already playing (multi-shot)', 1);
|
@@ -1748,8 +1822,19 @@ function SoundManager(smURL, smID) {
|
|
1748
1822
|
|
1749
1823
|
// edge case: play() with explicit URL parameter
|
1750
1824
|
if (oOptions.url && oOptions.url !== s.url) {
|
1751
|
-
|
1752
|
-
|
1825
|
+
|
1826
|
+
// special case for createSound() followed by load() / play() with url; avoid double-load case.
|
1827
|
+
if (!s.readyState && !s.isHTML5 && fV === 8 && urlOmitted) {
|
1828
|
+
|
1829
|
+
urlOmitted = false;
|
1830
|
+
|
1831
|
+
} else {
|
1832
|
+
|
1833
|
+
// load using merged options
|
1834
|
+
s.load(s._iO);
|
1835
|
+
|
1836
|
+
}
|
1837
|
+
|
1753
1838
|
}
|
1754
1839
|
|
1755
1840
|
if (!s.loaded) {
|
@@ -1759,13 +1844,22 @@ function SoundManager(smURL, smID) {
|
|
1759
1844
|
sm2._wD(fN + 'Attempting to load');
|
1760
1845
|
|
1761
1846
|
// try to get this sound playing ASAP
|
1762
|
-
if (!s.isHTML5) {
|
1763
|
-
|
1847
|
+
if (!s.isHTML5 && !sm2.html5Only) {
|
1848
|
+
|
1849
|
+
// flash: assign directly because setAutoPlay() increments the instanceCount
|
1764
1850
|
s._iO.autoPlay = true;
|
1765
1851
|
s.load(s._iO);
|
1766
|
-
|
1852
|
+
|
1853
|
+
} else if (s.isHTML5) {
|
1854
|
+
|
1767
1855
|
// iOS needs this when recycling sounds, loading a new URL on an existing object.
|
1768
1856
|
s.load(s._iO);
|
1857
|
+
|
1858
|
+
} else {
|
1859
|
+
|
1860
|
+
sm2._wD(fN + 'Unsupported type. Exiting.');
|
1861
|
+
exit = s;
|
1862
|
+
|
1769
1863
|
}
|
1770
1864
|
|
1771
1865
|
// HTML5 hack - re-set instanceOptions?
|
@@ -1865,9 +1959,10 @@ function SoundManager(smURL, smID) {
|
|
1865
1959
|
|
1866
1960
|
}
|
1867
1961
|
|
1868
|
-
sm2._wD(fN + 'Starting to play');
|
1962
|
+
// sm2._wD(fN + 'Starting to play');
|
1869
1963
|
|
1870
|
-
|
1964
|
+
// increment instance counter, where enabled + supported
|
1965
|
+
if (!s.instanceCount || s._iO.multiShotEvents || (s.isHTML5 && s._iO.multiShot && !useGlobalHTML5Audio) || (!s.isHTML5 && fV > 8 && !s.getAutoPlay())) {
|
1871
1966
|
s.instanceCount++;
|
1872
1967
|
}
|
1873
1968
|
|
@@ -1895,13 +1990,13 @@ function SoundManager(smURL, smID) {
|
|
1895
1990
|
|
1896
1991
|
if (!s.isHTML5) {
|
1897
1992
|
|
1898
|
-
startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s.position : s.position /
|
1993
|
+
startOK = flash._start(s.id, s._iO.loops || 1, (fV === 9 ? s.position : s.position / msecScale), s._iO.multiShot || false);
|
1899
1994
|
|
1900
1995
|
if (fV === 9 && !startOK) {
|
1901
1996
|
// edge case: no sound hardware, or 32-channel flash ceiling hit.
|
1902
1997
|
// applies only to Flash 9, non-NetStream/MovieStar sounds.
|
1903
1998
|
// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#play%28%29
|
1904
|
-
sm2._wD(fN + 'No sound hardware, or 32-sound ceiling hit');
|
1999
|
+
sm2._wD(fN + 'No sound hardware, or 32-sound ceiling hit', 2);
|
1905
2000
|
if (s._iO.onplayerror) {
|
1906
2001
|
s._iO.onplayerror.apply(s);
|
1907
2002
|
}
|
@@ -1910,13 +2005,56 @@ function SoundManager(smURL, smID) {
|
|
1910
2005
|
|
1911
2006
|
} else {
|
1912
2007
|
|
1913
|
-
|
2008
|
+
if (s.instanceCount < 2) {
|
1914
2009
|
|
1915
|
-
|
2010
|
+
// HTML5 single-instance case
|
1916
2011
|
|
1917
|
-
|
2012
|
+
start_html5_timer();
|
2013
|
+
|
2014
|
+
a = s._setup_html5();
|
2015
|
+
|
2016
|
+
s.setPosition(s._iO.position);
|
2017
|
+
|
2018
|
+
a.play();
|
2019
|
+
|
2020
|
+
} else {
|
1918
2021
|
|
1919
|
-
|
2022
|
+
// HTML5 multi-shot case
|
2023
|
+
|
2024
|
+
sm2._wD(s.id + ': Cloning Audio() for instance #' + s.instanceCount + '...');
|
2025
|
+
|
2026
|
+
audioClone = new Audio(s._iO.url);
|
2027
|
+
|
2028
|
+
onended = function() {
|
2029
|
+
event.remove(audioClone, 'onended', onended);
|
2030
|
+
s._onfinish(s);
|
2031
|
+
// cleanup
|
2032
|
+
html5Unload(audioClone);
|
2033
|
+
audioClone = null;
|
2034
|
+
};
|
2035
|
+
|
2036
|
+
oncanplay = function() {
|
2037
|
+
event.remove(audioClone, 'canplay', oncanplay);
|
2038
|
+
try {
|
2039
|
+
audioClone.currentTime = s._iO.position/msecScale;
|
2040
|
+
} catch(err) {
|
2041
|
+
complain(s.id + ': multiShot play() failed to apply position of ' + (s._iO.position/msecScale));
|
2042
|
+
}
|
2043
|
+
audioClone.play();
|
2044
|
+
};
|
2045
|
+
|
2046
|
+
event.add(audioClone, 'ended', onended);
|
2047
|
+
|
2048
|
+
if (s._iO.position) {
|
2049
|
+
// HTML5 audio can't seek before onplay() event has fired.
|
2050
|
+
// wait for canplay, then seek to position and start playback.
|
2051
|
+
event.add(audioClone, 'canplay', oncanplay);
|
2052
|
+
} else {
|
2053
|
+
// begin playback at currentTime: 0
|
2054
|
+
audioClone.play();
|
2055
|
+
}
|
2056
|
+
|
2057
|
+
}
|
1920
2058
|
|
1921
2059
|
}
|
1922
2060
|
|
@@ -2059,21 +2197,20 @@ function SoundManager(smURL, smID) {
|
|
2059
2197
|
nMsecOffset = 0;
|
2060
2198
|
}
|
2061
2199
|
|
2062
|
-
var
|
2063
|
-
position, position1K,
|
2200
|
+
var position, position1K,
|
2064
2201
|
// Use the duration from the instance options, if we don't have a track duration yet.
|
2065
2202
|
// position >= 0 and <= current available (loaded) duration
|
2066
2203
|
offset = (s.isHTML5 ? Math.max(nMsecOffset, 0) : Math.min(s.duration || s._iO.duration, Math.max(nMsecOffset, 0)));
|
2067
2204
|
|
2068
|
-
original_pos = s.position;
|
2069
2205
|
s.position = offset;
|
2070
|
-
position1K = s.position/
|
2206
|
+
position1K = s.position/msecScale;
|
2071
2207
|
s._resetOnPosition(s.position);
|
2072
2208
|
s._iO.position = offset;
|
2073
2209
|
|
2074
2210
|
if (!s.isHTML5) {
|
2075
2211
|
|
2076
2212
|
position = (fV === 9 ? s.position : position1K);
|
2213
|
+
|
2077
2214
|
if (s.readyState && s.readyState !== 2) {
|
2078
2215
|
// if paused or not playing, will not resume (by playing)
|
2079
2216
|
flash._setPosition(s.id, position, (s.paused || !s.playState), s._iO.multiShot);
|
@@ -2083,13 +2220,16 @@ function SoundManager(smURL, smID) {
|
|
2083
2220
|
|
2084
2221
|
// Set the position in the canplay handler if the sound is not ready yet
|
2085
2222
|
if (s._html5_canplay) {
|
2223
|
+
|
2086
2224
|
if (s._a.currentTime !== position1K) {
|
2225
|
+
|
2087
2226
|
/**
|
2088
2227
|
* DOM/JS errors/exceptions to watch out for:
|
2089
2228
|
* if seek is beyond (loaded?) position, "DOM exception 11"
|
2090
2229
|
* "INDEX_SIZE_ERR": DOM exception 1
|
2091
2230
|
*/
|
2092
2231
|
sm2._wD(s.id + ': setPosition('+position1K+')');
|
2232
|
+
|
2093
2233
|
try {
|
2094
2234
|
s._a.currentTime = position1K;
|
2095
2235
|
if (s.playState === 0 || s.paused) {
|
@@ -2099,19 +2239,25 @@ function SoundManager(smURL, smID) {
|
|
2099
2239
|
} catch(e) {
|
2100
2240
|
sm2._wD(s.id + ': setPosition(' + position1K + ') failed: ' + e.message, 2);
|
2101
2241
|
}
|
2242
|
+
|
2102
2243
|
}
|
2103
|
-
} else {
|
2104
|
-
sm2._wD(s.id + ': setPosition(' + position1K + '): Cannot seek yet, sound not ready');
|
2105
|
-
}
|
2106
2244
|
|
2107
|
-
|
2245
|
+
} else if (position1K) {
|
2246
|
+
|
2247
|
+
// warn on non-zero seek attempts
|
2248
|
+
sm2._wD(s.id + ': setPosition(' + position1K + '): Cannot seek yet, sound not ready', 2);
|
2249
|
+
return s;
|
2250
|
+
|
2251
|
+
}
|
2108
2252
|
|
2109
|
-
if (s.isHTML5) {
|
2110
2253
|
if (s.paused) {
|
2254
|
+
|
2111
2255
|
// if paused, refresh UI right away
|
2112
2256
|
// force update
|
2113
2257
|
s._onTimer(true);
|
2258
|
+
|
2114
2259
|
}
|
2260
|
+
|
2115
2261
|
}
|
2116
2262
|
|
2117
2263
|
return s;
|
@@ -2211,7 +2357,7 @@ function SoundManager(smURL, smID) {
|
|
2211
2357
|
|
2212
2358
|
if (s.playState === 0) {
|
2213
2359
|
s.play({
|
2214
|
-
position: (fV === 9 && !s.isHTML5 ? s.position : s.position /
|
2360
|
+
position: (fV === 9 && !s.isHTML5 ? s.position : s.position / msecScale)
|
2215
2361
|
});
|
2216
2362
|
return s;
|
2217
2363
|
}
|
@@ -2655,7 +2801,7 @@ function SoundManager(smURL, smID) {
|
|
2655
2801
|
// TODO: investigate why this goes wack if not set/re-set each time.
|
2656
2802
|
s.durationEstimate = s.duration;
|
2657
2803
|
|
2658
|
-
time = (s._a.currentTime *
|
2804
|
+
time = (s._a.currentTime * msecScale || 0);
|
2659
2805
|
|
2660
2806
|
if (time !== lastHTML5State.time) {
|
2661
2807
|
|
@@ -2688,7 +2834,7 @@ function SoundManager(smURL, smID) {
|
|
2688
2834
|
|
2689
2835
|
var instanceOptions = s._iO,
|
2690
2836
|
// if audio object exists, use its duration - else, instance option duration (if provided - it's a hack, really, and should be retired) OR null
|
2691
|
-
d = (s._a && s._a.duration ? s._a.duration*
|
2837
|
+
d = (s._a && s._a.duration ? s._a.duration*msecScale : (instanceOptions && instanceOptions.duration ? instanceOptions.duration : null)),
|
2692
2838
|
result = (d && !isNaN(d) && d !== Infinity ? d : null);
|
2693
2839
|
|
2694
2840
|
return result;
|
@@ -2897,7 +3043,7 @@ function SoundManager(smURL, smID) {
|
|
2897
3043
|
|
2898
3044
|
// <d>
|
2899
3045
|
fN = s.id + ': ';
|
2900
|
-
sm2._wD(fN + (loadOK ? 'onload()' : 'Failed to load? - ' + s.url), (loadOK ? 1 : 2));
|
3046
|
+
sm2._wD(fN + (loadOK ? 'onload()' : 'Failed to load / invalid sound?' + (!s.duration ? ' Zero-length duration reported.' : ' -') + ' (' + s.url + ')'), (loadOK ? 1 : 2));
|
2901
3047
|
if (!loadOK && !s.isHTML5) {
|
2902
3048
|
if (sm2.sandbox.noRemote === true) {
|
2903
3049
|
sm2._wD(fN + str('noNet'), 1);
|
@@ -3591,7 +3737,7 @@ function SoundManager(smURL, smID) {
|
|
3591
3737
|
s._onbufferchange(0);
|
3592
3738
|
|
3593
3739
|
// position according to instance options
|
3594
|
-
position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/
|
3740
|
+
position1K = (s._iO.position !== _undefined && !isNaN(s._iO.position)?s._iO.position/msecScale:null);
|
3595
3741
|
|
3596
3742
|
// set the position if position was set before the sound loaded
|
3597
3743
|
if (s.position && this.currentTime !== position1K) {
|
@@ -3644,6 +3790,14 @@ function SoundManager(smURL, smID) {
|
|
3644
3790
|
error: html5_event(function() {
|
3645
3791
|
|
3646
3792
|
sm2._wD(this._s.id + ': HTML5 error, code ' + this.error.code);
|
3793
|
+
/**
|
3794
|
+
* HTML5 error codes, per W3C
|
3795
|
+
* Error 1: Client aborted download at user's request.
|
3796
|
+
* Error 2: Network error after load started.
|
3797
|
+
* Error 3: Decoding issue.
|
3798
|
+
* Error 4: Media (audio file) not supported.
|
3799
|
+
* Reference: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#error-codes
|
3800
|
+
*/
|
3647
3801
|
// call load with error state?
|
3648
3802
|
this._s._onload(false);
|
3649
3803
|
|
@@ -3678,7 +3832,7 @@ function SoundManager(smURL, smID) {
|
|
3678
3832
|
|
3679
3833
|
play: html5_event(function() {
|
3680
3834
|
|
3681
|
-
sm2._wD(this._s.id + ': play()');
|
3835
|
+
// sm2._wD(this._s.id + ': play()');
|
3682
3836
|
// once play starts, no buffering
|
3683
3837
|
this._s._onbufferchange(0);
|
3684
3838
|
|
@@ -3702,9 +3856,7 @@ function SoundManager(smURL, smID) {
|
|
3702
3856
|
ranges = e.target.buffered,
|
3703
3857
|
// firefox 3.6 implements e.loaded/total (bytes)
|
3704
3858
|
loaded = (e.loaded||0),
|
3705
|
-
total = (e.total||1)
|
3706
|
-
// HTML5 returns msec. SM2 API uses seconds for setPosition() etc., whether Flash or HTML5.
|
3707
|
-
scale = 1000;
|
3859
|
+
total = (e.total||1);
|
3708
3860
|
|
3709
3861
|
// reset the "buffered" (loaded byte ranges) array
|
3710
3862
|
s.buffered = [];
|
@@ -3715,25 +3867,26 @@ function SoundManager(smURL, smID) {
|
|
3715
3867
|
// https://developer.mozilla.org/en/DOM/TimeRanges
|
3716
3868
|
|
3717
3869
|
// re-build "buffered" array
|
3870
|
+
// HTML5 returns seconds. SM2 API uses msec for setPosition() etc., whether Flash or HTML5.
|
3718
3871
|
for (i=0, j=ranges.length; i<j; i++) {
|
3719
3872
|
s.buffered.push({
|
3720
|
-
'start': ranges.start(i) *
|
3721
|
-
'end': ranges.end(i) *
|
3873
|
+
'start': ranges.start(i) * msecScale,
|
3874
|
+
'end': ranges.end(i) * msecScale
|
3722
3875
|
});
|
3723
3876
|
}
|
3724
3877
|
|
3725
3878
|
// use the last value locally
|
3726
|
-
buffered = (ranges.end(0) - ranges.start(0)) *
|
3879
|
+
buffered = (ranges.end(0) - ranges.start(0)) * msecScale;
|
3727
3880
|
|
3728
3881
|
// linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges
|
3729
|
-
loaded = buffered/(e.target.duration*
|
3882
|
+
loaded = Math.min(1, buffered/(e.target.duration*msecScale));
|
3730
3883
|
|
3731
3884
|
// <d>
|
3732
3885
|
if (isProgress && ranges.length > 1) {
|
3733
3886
|
str = [];
|
3734
3887
|
j = ranges.length;
|
3735
3888
|
for (i=0; i<j; i++) {
|
3736
|
-
str.push(e.target.buffered.start(i)*
|
3889
|
+
str.push(e.target.buffered.start(i)*msecScale +'-'+ e.target.buffered.end(i)*msecScale);
|
3737
3890
|
}
|
3738
3891
|
sm2._wD(this._s.id + ': progress, timeRanges: ' + str.join(', '));
|
3739
3892
|
}
|
@@ -3809,15 +3962,20 @@ function SoundManager(smURL, smID) {
|
|
3809
3962
|
|
3810
3963
|
var result;
|
3811
3964
|
|
3812
|
-
if (iO
|
3965
|
+
if (!iO || (!iO.type && !iO.url && !iO.serverURL)) {
|
3966
|
+
|
3967
|
+
// nothing to check
|
3968
|
+
result = false;
|
3969
|
+
|
3970
|
+
} else if (iO.serverURL || (iO.type && preferFlashCheck(iO.type))) {
|
3813
3971
|
|
3814
3972
|
// RTMP, or preferring flash
|
3815
3973
|
result = false;
|
3816
3974
|
|
3817
3975
|
} else {
|
3818
3976
|
|
3819
|
-
// Use type, if specified. If HTML5-only mode, no other options, so just give 'er
|
3820
|
-
result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only));
|
3977
|
+
// Use type, if specified. Pass data: URIs to HTML5. If HTML5-only mode, no other options, so just give 'er
|
3978
|
+
result = ((iO.type ? html5CanPlay({type:iO.type}) : html5CanPlay({url:iO.url}) || sm2.html5Only || iO.url.match(/data\:/i)));
|
3821
3979
|
|
3822
3980
|
}
|
3823
3981
|
|
@@ -3825,7 +3983,7 @@ function SoundManager(smURL, smID) {
|
|
3825
3983
|
|
3826
3984
|
};
|
3827
3985
|
|
3828
|
-
html5Unload = function(oAudio
|
3986
|
+
html5Unload = function(oAudio) {
|
3829
3987
|
|
3830
3988
|
/**
|
3831
3989
|
* Internal method: Unload media, and cancel any current/pending network requests.
|
@@ -3835,13 +3993,19 @@ function SoundManager(smURL, smID) {
|
|
3835
3993
|
* Other UA behaviour is unclear, so everyone else gets an about:blank-style URL.
|
3836
3994
|
*/
|
3837
3995
|
|
3996
|
+
var url;
|
3997
|
+
|
3838
3998
|
if (oAudio) {
|
3839
3999
|
|
3840
|
-
// Firefox likes '' for unload (used to work?) - however, may request hosting page URL (bad.) Most other UAs dislike '' and fail to unload.
|
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));
|
4002
|
+
|
3841
4003
|
oAudio.src = url;
|
3842
4004
|
|
3843
4005
|
// reset some state, too
|
3844
|
-
oAudio.
|
4006
|
+
if (oAudio._called_unload !== undefined) {
|
4007
|
+
oAudio._called_load = false;
|
4008
|
+
}
|
3845
4009
|
|
3846
4010
|
}
|
3847
4011
|
|
@@ -3852,6 +4016,8 @@ function SoundManager(smURL, smID) {
|
|
3852
4016
|
|
3853
4017
|
}
|
3854
4018
|
|
4019
|
+
return url;
|
4020
|
+
|
3855
4021
|
};
|
3856
4022
|
|
3857
4023
|
html5CanPlay = function(o) {
|
@@ -3935,6 +4101,9 @@ function SoundManager(smURL, smID) {
|
|
3935
4101
|
*/
|
3936
4102
|
|
3937
4103
|
if (!sm2.useHTML5Audio || !sm2.hasHTML5) {
|
4104
|
+
// without HTML5, we need Flash.
|
4105
|
+
sm2.html5.usingFlash = true;
|
4106
|
+
needsFlash = true;
|
3938
4107
|
return false;
|
3939
4108
|
}
|
3940
4109
|
|
@@ -4022,6 +4191,9 @@ function SoundManager(smURL, smID) {
|
|
4022
4191
|
support.canPlayType = (a?cp:null);
|
4023
4192
|
sm2.html5 = mixin(sm2.html5, support);
|
4024
4193
|
|
4194
|
+
sm2.html5.usingFlash = featureCheck();
|
4195
|
+
needsFlash = sm2.html5.usingFlash;
|
4196
|
+
|
4025
4197
|
return true;
|
4026
4198
|
|
4027
4199
|
};
|
@@ -4041,7 +4213,7 @@ function SoundManager(smURL, smID) {
|
|
4041
4213
|
waitForever: smc + 'Waiting indefinitely for Flash (will recover if unblocked)...',
|
4042
4214
|
waitSWF: smc + 'Waiting for 100% SWF load...',
|
4043
4215
|
needFunction: smc + 'Function object expected for %s',
|
4044
|
-
badID: '
|
4216
|
+
badID: 'Sound ID "%s" should be a string, starting with a non-numeric character',
|
4045
4217
|
currentObj: smc + '_debug(): Current sound objects',
|
4046
4218
|
waitOnload: smc + 'Waiting for window.onload()',
|
4047
4219
|
docLoaded: smc + 'Document already loaded',
|
@@ -4055,7 +4227,6 @@ function SoundManager(smURL, smID) {
|
|
4055
4227
|
smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',
|
4056
4228
|
fbTimeout: 'No flash response, applying .'+swfCSS.swfTimedout+' CSS...',
|
4057
4229
|
fbLoaded: 'Flash loaded',
|
4058
|
-
flRemoved: smc + 'Flash movie removed.',
|
4059
4230
|
fbHandler: smc + 'flashBlockHandler()',
|
4060
4231
|
manURL: 'SMSound.load(): Using manually-assigned URL',
|
4061
4232
|
onURL: sm + '.load(): current URL already assigned.',
|
@@ -4130,7 +4301,7 @@ function SoundManager(smURL, smID) {
|
|
4130
4301
|
complain = function(sMsg) {
|
4131
4302
|
|
4132
4303
|
// <d>
|
4133
|
-
if (
|
4304
|
+
if (hasConsole && console.warn !== _undefined) {
|
4134
4305
|
console.warn(sMsg);
|
4135
4306
|
} else {
|
4136
4307
|
sm2._wD(sMsg);
|
@@ -4260,11 +4431,11 @@ function SoundManager(smURL, smID) {
|
|
4260
4431
|
// starts debug mode, creating output <div> for UAs without console object
|
4261
4432
|
|
4262
4433
|
// allow force of debug mode via URL
|
4434
|
+
// <d>
|
4263
4435
|
if (sm2.debugURLParam.test(wl)) {
|
4264
4436
|
sm2.debugMode = true;
|
4265
4437
|
}
|
4266
4438
|
|
4267
|
-
// <d>
|
4268
4439
|
if (id(sm2.debugID)) {
|
4269
4440
|
return false;
|
4270
4441
|
}
|
@@ -4368,6 +4539,7 @@ function SoundManager(smURL, smID) {
|
|
4368
4539
|
sm2Debugger.handleEvent(sEventType, bSuccess, sMessage);
|
4369
4540
|
} catch(e) {
|
4370
4541
|
// oh well
|
4542
|
+
return false;
|
4371
4543
|
}
|
4372
4544
|
}
|
4373
4545
|
|
@@ -4406,6 +4578,7 @@ function SoundManager(smURL, smID) {
|
|
4406
4578
|
error = {type:'FLASHBLOCK'};
|
4407
4579
|
|
4408
4580
|
if (sm2.html5Only) {
|
4581
|
+
// no flash, or unused
|
4409
4582
|
return false;
|
4410
4583
|
}
|
4411
4584
|
|
@@ -4564,6 +4737,7 @@ function SoundManager(smURL, smID) {
|
|
4564
4737
|
obj = new AX('ShockwaveFlash.ShockwaveFlash');
|
4565
4738
|
} catch(e) {
|
4566
4739
|
// oh well
|
4740
|
+
obj = null;
|
4567
4741
|
}
|
4568
4742
|
hasPlugin = (!!obj);
|
4569
4743
|
// cleanup, because it is ActiveX after all
|
@@ -4578,9 +4752,8 @@ function SoundManager(smURL, smID) {
|
|
4578
4752
|
|
4579
4753
|
featureCheck = function() {
|
4580
4754
|
|
4581
|
-
var
|
4755
|
+
var flashNeeded,
|
4582
4756
|
item,
|
4583
|
-
result = true,
|
4584
4757
|
formats = sm2.audioFormats,
|
4585
4758
|
// iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (original iPad) + iOS4 works.
|
4586
4759
|
isSpecial = (is_iDevice && !!(ua.match(/os (1|2|3_0|3_1)/i)));
|
@@ -4593,12 +4766,11 @@ function SoundManager(smURL, smID) {
|
|
4593
4766
|
// ignore flash case, however
|
4594
4767
|
sm2.html5Only = true;
|
4595
4768
|
|
4769
|
+
// hide the SWF, if present
|
4596
4770
|
if (sm2.oMC) {
|
4597
4771
|
sm2.oMC.style.display = 'none';
|
4598
4772
|
}
|
4599
4773
|
|
4600
|
-
result = false;
|
4601
|
-
|
4602
4774
|
} else {
|
4603
4775
|
|
4604
4776
|
if (sm2.useHTML5Audio) {
|
@@ -4620,11 +4792,22 @@ function SoundManager(smURL, smID) {
|
|
4620
4792
|
|
4621
4793
|
if (sm2.useHTML5Audio && sm2.hasHTML5) {
|
4622
4794
|
|
4795
|
+
// sort out whether flash is optional, required or can be ignored.
|
4796
|
+
|
4797
|
+
// innocent until proven guilty.
|
4798
|
+
canIgnoreFlash = true;
|
4799
|
+
|
4623
4800
|
for (item in formats) {
|
4624
4801
|
if (formats.hasOwnProperty(item)) {
|
4625
|
-
if (
|
4626
|
-
|
4627
|
-
|
4802
|
+
if (formats[item].required) {
|
4803
|
+
if (!sm2.html5.canPlayType(formats[item].type)) {
|
4804
|
+
// 100% HTML5 mode is not possible.
|
4805
|
+
canIgnoreFlash = false;
|
4806
|
+
flashNeeded = true;
|
4807
|
+
} else if (sm2.preferFlash && (sm2.flash[item] || sm2.flash[formats[item].type])) {
|
4808
|
+
// flash may be required, or preferred for this format.
|
4809
|
+
flashNeeded = true;
|
4810
|
+
}
|
4628
4811
|
}
|
4629
4812
|
}
|
4630
4813
|
}
|
@@ -4633,10 +4816,11 @@ function SoundManager(smURL, smID) {
|
|
4633
4816
|
|
4634
4817
|
// sanity check...
|
4635
4818
|
if (sm2.ignoreFlash) {
|
4636
|
-
|
4819
|
+
flashNeeded = false;
|
4820
|
+
canIgnoreFlash = true;
|
4637
4821
|
}
|
4638
4822
|
|
4639
|
-
sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !
|
4823
|
+
sm2.html5Only = (sm2.hasHTML5 && sm2.useHTML5Audio && !flashNeeded);
|
4640
4824
|
|
4641
4825
|
return (!sm2.html5Only);
|
4642
4826
|
|
@@ -4847,10 +5031,9 @@ function SoundManager(smURL, smID) {
|
|
4847
5031
|
|
4848
5032
|
};
|
4849
5033
|
|
4850
|
-
this._externalInterfaceOK = function(
|
5034
|
+
this._externalInterfaceOK = function(swfVersion) {
|
4851
5035
|
|
4852
5036
|
// flash callback confirming flash loaded, EI working etc.
|
4853
|
-
// flashDate = approx. timing/delay info for JS/flash bridge
|
4854
5037
|
// swfVersion: SWF build string
|
4855
5038
|
|
4856
5039
|
if (sm2.swfLoaded) {
|
@@ -4885,7 +5068,7 @@ function SoundManager(smURL, smID) {
|
|
4885
5068
|
}
|
4886
5069
|
// </d>
|
4887
5070
|
|
4888
|
-
//
|
5071
|
+
// IE needs a larger timeout
|
4889
5072
|
setTimeout(init, isIE ? 100 : 1);
|
4890
5073
|
|
4891
5074
|
};
|
@@ -5283,26 +5466,69 @@ function SoundManager(smURL, smID) {
|
|
5283
5466
|
// give up / time-out, depending
|
5284
5467
|
|
5285
5468
|
if (!didInit && okToDisable) {
|
5469
|
+
|
5286
5470
|
if (p === null) {
|
5471
|
+
|
5287
5472
|
// SWF failed. Maybe blocked.
|
5473
|
+
|
5288
5474
|
if (sm2.useFlashBlock || sm2.flashLoadTimeout === 0) {
|
5475
|
+
|
5289
5476
|
if (sm2.useFlashBlock) {
|
5477
|
+
|
5290
5478
|
flashBlockHandler();
|
5479
|
+
|
5291
5480
|
}
|
5481
|
+
|
5292
5482
|
_wDS('waitForever');
|
5483
|
+
|
5293
5484
|
} else {
|
5485
|
+
|
5294
5486
|
// no custom flash block handling, but SWF has timed out. Will recover if user unblocks / allows SWF load.
|
5295
|
-
|
5296
|
-
|
5297
|
-
|
5487
|
+
|
5488
|
+
if (!sm2.useFlashBlock && canIgnoreFlash) {
|
5489
|
+
|
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);
|
5506
|
+
|
5507
|
+
} else {
|
5508
|
+
|
5509
|
+
_wDS('waitForever');
|
5510
|
+
|
5511
|
+
// fire any regular registered ontimeout() listeners.
|
5512
|
+
processOnEvents({type:'ontimeout', ignoreInit: true});
|
5513
|
+
|
5514
|
+
}
|
5515
|
+
|
5298
5516
|
}
|
5517
|
+
|
5299
5518
|
} else {
|
5519
|
+
|
5300
5520
|
// flash loaded? Shouldn't be a blocking issue, then.
|
5521
|
+
|
5301
5522
|
if (sm2.flashLoadTimeout === 0) {
|
5302
|
-
|
5523
|
+
|
5524
|
+
_wDS('waitForever');
|
5525
|
+
|
5303
5526
|
} else {
|
5527
|
+
|
5304
5528
|
failSafely(true);
|
5529
|
+
|
5305
5530
|
}
|
5531
|
+
|
5306
5532
|
}
|
5307
5533
|
}
|
5308
5534
|
|
@@ -5362,7 +5588,7 @@ function SoundManager(smURL, smID) {
|
|
5362
5588
|
if (sm2.useHTML5Audio && sm2.hasHTML5) {
|
5363
5589
|
for (item in sm2.audioFormats) {
|
5364
5590
|
if (sm2.audioFormats.hasOwnProperty(item)) {
|
5365
|
-
tests.push(item + ' = ' + sm2.html5[item] + (!sm2.html5[item] &&
|
5591
|
+
tests.push(item + ' = ' + sm2.html5[item] + (!sm2.html5[item] && needsFlash && sm2.flash[item] ? ' (using flash)' : (sm2.preferFlash && sm2.flash[item] && needsFlash ? ' (preferring flash)': (!sm2.html5[item] ? ' (' + (sm2.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));
|
5366
5592
|
}
|
5367
5593
|
}
|
5368
5594
|
sm2._wD('SoundManager 2 HTML5 support: ' + tests.join(', '), 1);
|
@@ -5559,12 +5785,11 @@ function SoundManager(smURL, smID) {
|
|
5559
5785
|
a2 = 'sm2-preferflash=',
|
5560
5786
|
b = null,
|
5561
5787
|
b2 = null,
|
5562
|
-
hasCon = (window.console !== _undefined && typeof console.log === 'function'),
|
5563
5788
|
l = wl.toLowerCase();
|
5564
5789
|
|
5565
5790
|
if (l.indexOf(a) !== -1) {
|
5566
5791
|
b = (l.charAt(l.indexOf(a)+a.length) === '1');
|
5567
|
-
if (
|
5792
|
+
if (hasConsole) {
|
5568
5793
|
console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter');
|
5569
5794
|
}
|
5570
5795
|
sm2.setup({
|
@@ -5574,7 +5799,7 @@ function SoundManager(smURL, smID) {
|
|
5574
5799
|
|
5575
5800
|
if (l.indexOf(a2) !== -1) {
|
5576
5801
|
b2 = (l.charAt(l.indexOf(a2)+a2.length) === '1');
|
5577
|
-
if (
|
5802
|
+
if (hasConsole) {
|
5578
5803
|
console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter');
|
5579
5804
|
}
|
5580
5805
|
sm2.setup({
|
@@ -5596,8 +5821,6 @@ function SoundManager(smURL, smID) {
|
|
5596
5821
|
}
|
5597
5822
|
|
5598
5823
|
testHTML5();
|
5599
|
-
sm2.html5.usingFlash = featureCheck();
|
5600
|
-
needsFlash = sm2.html5.usingFlash;
|
5601
5824
|
|
5602
5825
|
if (!hasFlash && needsFlash) {
|
5603
5826
|
messages.push(strings.needFlash);
|