|
1 | 1 | /*!
|
2 |
| - * howler.js v2.0.1 |
| 2 | + * howler.js v2.0.2 |
3 | 3 | * howlerjs.com
|
4 | 4 | *
|
5 | 5 | * (c) 2013-2016, James Simpson of GoldFire Studios
|
|
155 | 155 | }
|
156 | 156 |
|
157 | 157 | // Create a new AudioContext to make sure it is fully reset.
|
158 |
| - if (self.usingWebAudio && typeof self.ctx.close !== 'undefined') { |
| 158 | + if (self.usingWebAudio && self.ctx && typeof self.ctx.close !== 'undefined') { |
159 | 159 | self.ctx.close();
|
160 | 160 | self.ctx = null;
|
161 | 161 | setupAudioContext();
|
|
186 | 186 | // Automatically begin the 30-second suspend process
|
187 | 187 | self._autoSuspend();
|
188 | 188 |
|
| 189 | + // Check if audio is available. |
| 190 | + if (!self.usingWebAudio) { |
| 191 | + // No audio is available on this system if noAudio is set to true. |
| 192 | + if (typeof Audio !== 'undefined') { |
| 193 | + try { |
| 194 | + var test = new Audio(); |
| 195 | + |
| 196 | + // Check if the canplaythrough event is available. |
| 197 | + if (typeof test.oncanplaythrough === 'undefined') { |
| 198 | + self._canPlayEvent = 'canplay'; |
| 199 | + } |
| 200 | + } catch(e) { |
| 201 | + self.noAudio = true; |
| 202 | + } |
| 203 | + } else { |
| 204 | + self.noAudio = true; |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + // Test to make sure audio isn't disabled in Internet Explorer. |
| 209 | + try { |
| 210 | + var test = new Audio(); |
| 211 | + if (test.muted) { |
| 212 | + self.noAudio = true; |
| 213 | + } |
| 214 | + } catch (e) {} |
| 215 | + |
189 | 216 | // Check for supported codecs.
|
190 | 217 | if (!self.noAudio) {
|
191 | 218 | self._setupCodecs();
|
|
200 | 227 | */
|
201 | 228 | _setupCodecs: function() {
|
202 | 229 | var self = this || Howler;
|
203 |
| - var audioTest = (typeof Audio !== 'undefined') ? new Audio() : null; |
| 230 | + var audioTest = null; |
| 231 | + |
| 232 | + // Must wrap in a try/catch because IE11 in server mode throws an error. |
| 233 | + try { |
| 234 | + audioTest = (typeof Audio !== 'undefined') ? new Audio() : null; |
| 235 | + } catch (err) { |
| 236 | + return self; |
| 237 | + } |
204 | 238 |
|
205 | 239 | if (!audioTest || typeof audioTest.canPlayType !== 'function') {
|
206 | 240 | return self;
|
|
363 | 397 | self.state = 'resuming';
|
364 | 398 | self.ctx.resume().then(function() {
|
365 | 399 | self.state = 'running';
|
| 400 | + |
| 401 | + // Emit to all Howls that the audio has resumed. |
| 402 | + for (var i=0; i<self._howls.length; i++) { |
| 403 | + self._howls[i]._emit('resume'); |
| 404 | + } |
366 | 405 | });
|
367 | 406 |
|
368 | 407 | if (self._suspendTimer) {
|
|
444 | 483 | self._onvolume = o.onvolume ? [{fn: o.onvolume}] : [];
|
445 | 484 | self._onrate = o.onrate ? [{fn: o.onrate}] : [];
|
446 | 485 | self._onseek = o.onseek ? [{fn: o.onseek}] : [];
|
| 486 | + self._onresume = []; |
447 | 487 |
|
448 | 488 | // Web Audio or HTML5 Audio?
|
449 | 489 | self._webAudio = Howler.usingWebAudio && !self._html5;
|
|
456 | 496 | // Keep track of this Howl group in the global controller.
|
457 | 497 | Howler._howls.push(self);
|
458 | 498 |
|
| 499 | + // If they selected autoplay, add a play event to the load queue. |
| 500 | + if (self._autoplay) { |
| 501 | + self._queue.push({ |
| 502 | + event: 'play', |
| 503 | + action: function() { |
| 504 | + self.play(); |
| 505 | + } |
| 506 | + }); |
| 507 | + } |
| 508 | + |
459 | 509 | // Load the source file unless otherwise specified.
|
460 | 510 | if (self._preload) {
|
461 | 511 | self.load();
|
|
624 | 674 | }
|
625 | 675 |
|
626 | 676 | // Determine how long to play for and where to start playing.
|
627 |
| - var seek = sound._seek > 0 ? sound._seek : self._sprite[sprite][0] / 1000; |
628 |
| - var duration = ((self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000) - seek; |
| 677 | + var seek = Math.max(0, sound._seek > 0 ? sound._seek : self._sprite[sprite][0] / 1000); |
| 678 | + var duration = Math.max(0, ((self._sprite[sprite][0] + self._sprite[sprite][1]) / 1000) - seek); |
629 | 679 | var timeout = (duration * 1000) / Math.abs(sound._rate);
|
630 | 680 |
|
631 | 681 | // Update the parameters of the sound
|
|
668 | 718 | }
|
669 | 719 | };
|
670 | 720 |
|
671 |
| - if (self._state === 'loaded') { |
| 721 | + var isRunning = (Howler.state === 'running'); |
| 722 | + if (self._state === 'loaded' && isRunning) { |
672 | 723 | playWebAudio();
|
673 | 724 | } else {
|
674 | 725 | // Wait for the audio to load and then begin playback.
|
675 |
| - self.once('load', playWebAudio, sound._id); |
| 726 | + self.once(isRunning ? 'load' : 'resume', playWebAudio, isRunning ? sound._id : null); |
676 | 727 |
|
677 | 728 | // Cancel the end timer.
|
678 | 729 | self._clearTimer(sound._id);
|
|
779 | 830 | sound._node.pause();
|
780 | 831 | }
|
781 | 832 | }
|
| 833 | + } |
782 | 834 |
|
783 |
| - // Fire the pause event, unless `true` is passed as the 2nd argument. |
784 |
| - if (!arguments[1]) { |
785 |
| - self._emit('pause', sound._id); |
786 |
| - } |
| 835 | + // Fire the pause event, unless `true` is passed as the 2nd argument. |
| 836 | + if (!arguments[1]) { |
| 837 | + self._emit('pause', sound ? sound._id : null); |
787 | 838 | }
|
788 | 839 | }
|
789 | 840 |
|
|
1948 | 1999 | parent._loadQueue();
|
1949 | 2000 | }
|
1950 | 2001 |
|
1951 |
| - if (parent._autoplay) { |
1952 |
| - parent.play(); |
1953 |
| - } |
1954 |
| - |
1955 | 2002 | // Clear the event listener.
|
1956 | 2003 | self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false);
|
1957 | 2004 | }
|
|
2069 | 2116 | self._emit('load');
|
2070 | 2117 | self._loadQueue();
|
2071 | 2118 | }
|
2072 |
| - |
2073 |
| - // Begin playback if specified. |
2074 |
| - if (self._autoplay) { |
2075 |
| - self.play(); |
2076 |
| - } |
2077 | 2119 | };
|
2078 | 2120 |
|
2079 | 2121 | /**
|
2080 | 2122 | * Setup the audio context when available, or switch to HTML5 Audio mode.
|
2081 | 2123 | */
|
2082 | 2124 | var setupAudioContext = function() {
|
2083 |
| - Howler.noAudio = false; |
2084 |
| - |
2085 | 2125 | // Check if we are using Web Audio and setup the AudioContext if we are.
|
2086 | 2126 | try {
|
2087 | 2127 | if (typeof AudioContext !== 'undefined') {
|
|
2095 | 2135 | Howler.usingWebAudio = false;
|
2096 | 2136 | }
|
2097 | 2137 |
|
2098 |
| - if (!Howler.usingWebAudio) { |
2099 |
| - // No audio is available on this system if noAudio is set to true. |
2100 |
| - if (typeof Audio !== 'undefined') { |
2101 |
| - try { |
2102 |
| - var test = new Audio(); |
2103 |
| - |
2104 |
| - // Check if the canplaythrough event is available. |
2105 |
| - if (typeof test.oncanplaythrough === 'undefined') { |
2106 |
| - Howler._canPlayEvent = 'canplay'; |
2107 |
| - } |
2108 |
| - } catch(e) { |
2109 |
| - Howler.noAudio = true; |
2110 |
| - } |
2111 |
| - } else { |
2112 |
| - Howler.noAudio = true; |
2113 |
| - } |
2114 |
| - } |
2115 |
| - |
2116 |
| - // Test to make sure audio isn't disabled in Internet Explorer |
2117 |
| - try { |
2118 |
| - var test = new Audio(); |
2119 |
| - if (test.muted) { |
2120 |
| - Howler.noAudio = true; |
2121 |
| - } |
2122 |
| - } catch (e) {} |
2123 |
| - |
2124 | 2138 | // Check if a webview is being used on iOS8 or earlier (rather than the browser).
|
2125 | 2139 | // If it is, disable Web Audio as it causes crashing.
|
2126 | 2140 | var iOS = (/iP(hone|od|ad)/.test(Howler._navigator && Howler._navigator.platform));
|
|
2178 | 2192 | /*!
|
2179 | 2193 | * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.
|
2180 | 2194 | *
|
2181 |
| - * howler.js v2.0.1 |
| 2195 | + * howler.js v2.0.2 |
2182 | 2196 | * howlerjs.com
|
2183 | 2197 | *
|
2184 | 2198 | * (c) 2013-2016, James Simpson of GoldFire Studios
|
|
0 commit comments