|
1746 | 1746 | // Remove any event listeners.
|
1747 | 1747 | sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);
|
1748 | 1748 | sounds[i]._node.removeEventListener(Howler._canPlayEvent, sounds[i]._loadFn, false);
|
| 1749 | + sounds[i]._node.removeEventListener('ended', sounds[i]._endFn, false); |
1749 | 1750 |
|
1750 | 1751 | // Release the Audio object back to the pool.
|
1751 | 1752 | Howler._releaseHtml5Audio(sounds[i]._node);
|
|
2242 | 2243 | self._loadFn = self._loadListener.bind(self);
|
2243 | 2244 | self._node.addEventListener(Howler._canPlayEvent, self._loadFn, false);
|
2244 | 2245 |
|
| 2246 | + // Listen for the 'ended' event on the sound to account for edge-case where |
| 2247 | + // a finite sound has a duration of Infinity. |
| 2248 | + self._endFn = self._endListener.bind(self); |
| 2249 | + self._node.addEventListener('ended', self._endFn, false); |
| 2250 | + |
2245 | 2251 | // Setup the new audio node.
|
2246 | 2252 | self._node.src = parent._src;
|
2247 | 2253 | self._node.preload = parent._preload === true ? 'auto' : parent._preload;
|
|
2315 | 2321 |
|
2316 | 2322 | // Clear the event listener.
|
2317 | 2323 | self._node.removeEventListener(Howler._canPlayEvent, self._loadFn, false);
|
| 2324 | + }, |
| 2325 | + |
| 2326 | + /** |
| 2327 | + * HTML5 Audio ended listener callback. |
| 2328 | + */ |
| 2329 | + _endListener: function() { |
| 2330 | + var self = this; |
| 2331 | + var parent = self._parent; |
| 2332 | + |
| 2333 | + // Only handle the `ended`` event if the duration is Infinity. |
| 2334 | + if (parent._duration === Infinity) { |
| 2335 | + // Update the parent duration to match the real audio duration. |
| 2336 | + // Round up the duration to account for the lower precision in HTML5 Audio. |
| 2337 | + parent._duration = Math.ceil(self._node.duration * 10) / 10; |
| 2338 | + |
| 2339 | + // Update the sprite that corresponds to the real duration. |
| 2340 | + if (parent._sprite.__default[1] === Infinity) { |
| 2341 | + parent._sprite.__default[1] = parent._duration * 1000; |
| 2342 | + } |
| 2343 | + |
| 2344 | + // Run the regular ended method. |
| 2345 | + parent._ended(self); |
| 2346 | + } |
| 2347 | + |
| 2348 | + // Clear the event listener since the duration is now correct. |
| 2349 | + self._node.removeEventListener('ended', self._endFn, false); |
2318 | 2350 | }
|
2319 | 2351 | };
|
2320 | 2352 |
|
|
0 commit comments