|
1 | 1 | /*! |
2 | | - * howler.js v2.2.1 |
| 2 | + * howler.js v2.2.2 |
3 | 3 | * howlerjs.com |
4 | 4 | * |
5 | 5 | * (c) 2013-2020, James Simpson of GoldFire Studios |
|
264 | 264 | var mpegTest = audioTest.canPlayType('audio/mpeg;').replace(/^no$/, ''); |
265 | 265 |
|
266 | 266 | // Opera version <33 has mixed MP3 support, so we need to check for and block it. |
267 | | - var checkOpera = self._navigator && self._navigator.userAgent.match(/OPR\/([0-6].)/g); |
| 267 | + var ua = self._navigator ? self._navigator.userAgent : ''; |
| 268 | + var checkOpera = ua.match(/OPR\/([0-6].)/g); |
268 | 269 | var isOldOpera = (checkOpera && parseInt(checkOpera[0].split('/')[1], 10) < 33); |
| 270 | + var checkSafari = ua.indexOf('Safari') !== -1 && ua.indexOf('Chrome') === -1; |
| 271 | + var isOldSafari = (checkSafari && parseInt(ua.match(/Version\/(.*?) /)[1], 10) < 15); |
269 | 272 |
|
270 | 273 | self._codecs = { |
271 | 274 | mp3: !!(!isOldOpera && (mpegTest || audioTest.canPlayType('audio/mp3;').replace(/^no$/, ''))), |
|
279 | 282 | m4a: !!(audioTest.canPlayType('audio/x-m4a;') || audioTest.canPlayType('audio/m4a;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''), |
280 | 283 | m4b: !!(audioTest.canPlayType('audio/x-m4b;') || audioTest.canPlayType('audio/m4b;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''), |
281 | 284 | mp4: !!(audioTest.canPlayType('audio/x-mp4;') || audioTest.canPlayType('audio/mp4;') || audioTest.canPlayType('audio/aac;')).replace(/^no$/, ''), |
282 | | - weba: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, ''), |
283 | | - webm: !!audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, ''), |
| 285 | + weba: !!(!isOldSafari && audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')), |
| 286 | + webm: !!(!isOldSafari && audioTest.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')), |
284 | 287 | dolby: !!audioTest.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/, ''), |
285 | 288 | flac: !!(audioTest.canPlayType('audio/x-flac;') || audioTest.canPlayType('audio/flac;')).replace(/^no$/, '') |
286 | 289 | }; |
|
392 | 395 | document.removeEventListener('touchstart', unlock, true); |
393 | 396 | document.removeEventListener('touchend', unlock, true); |
394 | 397 | document.removeEventListener('click', unlock, true); |
| 398 | + document.removeEventListener('keydown', unlock, true); |
395 | 399 |
|
396 | 400 | // Let all sounds know that audio has been unlocked. |
397 | 401 | for (var i=0; i<self._howls.length; i++) { |
|
404 | 408 | document.addEventListener('touchstart', unlock, true); |
405 | 409 | document.addEventListener('touchend', unlock, true); |
406 | 410 | document.addEventListener('click', unlock, true); |
| 411 | + document.addEventListener('keydown', unlock, true); |
407 | 412 |
|
408 | 413 | return self; |
409 | 414 | }, |
|
915 | 920 | node._unlocked = true; |
916 | 921 | if (!internal) { |
917 | 922 | self._emit('play', sound._id); |
| 923 | + } else { |
918 | 924 | self._loadQueue(); |
919 | 925 | } |
920 | 926 | }) |
|
931 | 937 | self._playLock = false; |
932 | 938 | setParams(); |
933 | 939 | self._emit('play', sound._id); |
934 | | - self._loadQueue(); |
935 | 940 | } |
936 | 941 |
|
937 | 942 | // Setting rate before playing won't work in IE, so we set it again here. |
|
974 | 979 | playHtml5(); |
975 | 980 | } else { |
976 | 981 | self._playLock = true; |
| 982 | + self._state = 'loading'; |
977 | 983 |
|
978 | 984 | var listener = function() { |
| 985 | + self._state = 'loaded'; |
| 986 | + |
979 | 987 | // Begin playback. |
980 | 988 | playHtml5(); |
981 | 989 |
|
|
1463 | 1471 | if (loop) { |
1464 | 1472 | sound._node.bufferSource.loopStart = sound._start || 0; |
1465 | 1473 | sound._node.bufferSource.loopEnd = sound._stop; |
| 1474 | + |
| 1475 | + // If playing, restart playback to ensure looping updates. |
| 1476 | + if (self.playing(ids[i])) { |
| 1477 | + self.pause(ids[i], true); |
| 1478 | + self.play(ids[i], true); |
| 1479 | + } |
1466 | 1480 | } |
1467 | 1481 | } |
1468 | 1482 | } |
|
1582 | 1596 | // Determine the values based on arguments. |
1583 | 1597 | if (args.length === 0) { |
1584 | 1598 | // We will simply return the current position of the first node. |
1585 | | - id = self._sounds[0]._id; |
| 1599 | + if (self._sounds.length) { |
| 1600 | + id = self._sounds[0]._id; |
| 1601 | + } |
1586 | 1602 | } else if (args.length === 1) { |
1587 | 1603 | // First check if this is an ID, and if not, assume it is a new seek position. |
1588 | 1604 | var ids = self._getSoundIds(); |
|
1600 | 1616 |
|
1601 | 1617 | // If there is no ID, bail out. |
1602 | 1618 | if (typeof id === 'undefined') { |
1603 | | - return self; |
| 1619 | + return 0; |
1604 | 1620 | } |
1605 | 1621 |
|
1606 | 1622 | // If the sound hasn't loaded, add it to the load queue to seek when capable. |
|
1638 | 1654 |
|
1639 | 1655 | // Seek and emit when ready. |
1640 | 1656 | var seekAndEmit = function() { |
1641 | | - self._emit('seek', id); |
1642 | | - |
1643 | 1657 | // Restart the playback if the sound was playing. |
1644 | 1658 | if (playing) { |
1645 | 1659 | self.play(id, true); |
1646 | 1660 | } |
| 1661 | + |
| 1662 | + self._emit('seek', id); |
1647 | 1663 | }; |
1648 | 1664 |
|
1649 | 1665 | // Wait for the play lock to be unset before emitting (HTML5 Audio). |
|
2569 | 2585 | /*! |
2570 | 2586 | * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported. |
2571 | 2587 | * |
2572 | | - * howler.js v2.2.1 |
| 2588 | + * howler.js v2.2.2 |
2573 | 2589 | * howlerjs.com |
2574 | 2590 | * |
2575 | 2591 | * (c) 2013-2020, James Simpson of GoldFire Studios |
|
0 commit comments