|
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