soundmanager2-rails 2.97.20130324 → 2.97.20130512
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.
- 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);
|