|
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