Skip to content

Commit 273394e

Browse files
committed
v2.0.4
1 parent d3236c5 commit 273394e

File tree

8 files changed

+83
-44
lines changed

8 files changed

+83
-44
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## 2.0.4 (June 9, 2017)
2+
- `CHANGED` Removed the `resuming` state, which wasn't actually being used and was leading to a bug on Android ([#679](https://github.com/goldfire/howler.js/pull/679)).
3+
- `CHANGED` Any playback initiated before the sound has loaded will now go into the queue to fix various race conditions ([#714](https://github.com/goldfire/howler.js/pull/714)).
4+
- `FIXED` Correctly initialize an AudioContext with the global mute status ([#714](https://github.com/goldfire/howler.js/pull/714)).
5+
- `FIXED` AudioContext unlocks on user interaction within a cross-domain iframe on Android Chrome ([#756](https://github.com/goldfire/howler.js/pull/756)).
6+
- `FIXED` Stopping/pausing a group of sounds now behaves as expected in edge cases ([#734](https://github.com/goldfire/howler.js/pull/734)).
7+
- `FIXED` Sound ID's now start at 1000 instead of 0 to avoid `rate` collisions ([#764](https://github.com/goldfire/howler.js/issues/764)).
8+
- `FIXED` Prevent unknown mime errors on Internet Explorer when unloading a sound ([#720](https://github.com/goldfire/howler.js/pull/720)).
9+
- `FIXED` Correctly clean up error event listeners ([#720](https://github.com/goldfire/howler.js/pull/720)).
10+
- `FIXED` Audio clipping in Internet Explorer when network latency is present with HTML5 Audio ([#720](https://github.com/goldfire/howler.js/pull/720)).
11+
- `FIXED` Allow passing just an event and ID to turn off listener ([#767](https://github.com/goldfire/howler.js/issues/767)).
12+
- `FIXED` `npm` warning caused by invalid license definition ([#763](https://github.com/goldfire/howler.js/pull/763)).
13+
114
## 2.0.3 (March 11, 2017)
215
- `CHANGED` Unloading a sound no longer fires the `end` event ([#675](https://github.com/goldfire/howler.js/pull/675)).
316
- `FIXED` Remove `setTimeout` wrapper on HTML5 `play` call to fix issues on mobile browsers ([#694](https://github.com/goldfire/howler.js/pull/694)).

dist/howler.core.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/howler.js

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* howler.js v2.0.3
2+
* howler.js v2.0.4
33
* howlerjs.com
44
*
55
* (c) 2013-2017, James Simpson of GoldFire Studios
@@ -31,7 +31,7 @@
3131
var self = this || Howler;
3232

3333
// Create a global ID counter.
34-
self._counter = 0;
34+
self._counter = 1000;
3535

3636
// Internal properties.
3737
self._codecs = {};
@@ -303,6 +303,9 @@
303303
// then check if the audio actually played to determine if
304304
// audio has now been unlocked on iOS, Android, etc.
305305
var unlock = function() {
306+
// Fix Android can not play in suspend state.
307+
Howler._autoResume();
308+
306309
// Create an empty buffer.
307310
var source = self.ctx.createBufferSource();
308311
source.buffer = self._scratchBuffer;
@@ -315,6 +318,11 @@
315318
source.start(0);
316319
}
317320

321+
// Calling resume() on a stack initiated by user gesture is what actually unlocks the audio on Android Chrome >= 55.
322+
if (typeof self.ctx.resume === 'function') {
323+
self.ctx.resume();
324+
}
325+
318326
// Setup a timeout to check that we are unlocked on the next event loop.
319327
source.onended = function() {
320328
source.disconnect(0);
@@ -397,7 +405,6 @@
397405
clearTimeout(self._suspendTimer);
398406
self._suspendTimer = null;
399407
} else if (self.state === 'suspended') {
400-
self.state = 'resuming';
401408
self.ctx.resume().then(function() {
402409
self.state = 'running';
403410

@@ -651,17 +658,26 @@
651658
sprite = sound._sprite || '__default';
652659
}
653660

654-
// If we have no sprite and the sound hasn't loaded, we must wait
655-
// for the sound to load to get our audio's duration.
656-
if (self._state !== 'loaded' && !self._sprite[sprite]) {
661+
// If the sound hasn't loaded, we must wait to get the audio's duration.
662+
// We also need to wait to make sure we don't run into race conditions with
663+
// the order of function calls.
664+
if (self._state !== 'loaded') {
665+
// Set the sprite value on this sound.
666+
sound._sprite = sprite;
667+
668+
// Makr this sounded as not ended in case another sound is played before this one loads.
669+
sound._ended = false;
670+
671+
// Add the sound to the queue to be played on load.
672+
var soundId = sound._id;
657673
self._queue.push({
658674
event: 'play',
659675
action: function() {
660-
self.play(self._soundById(sound._id) ? sound._id : undefined);
676+
self.play(soundId);
661677
}
662678
});
663679

664-
return sound._id;
680+
return soundId;
665681
}
666682

667683
// Don't play the sound if an id was passed and it is already playing.
@@ -819,9 +835,9 @@
819835

820836
if (sound._node) {
821837
if (self._webAudio) {
822-
// make sure the sound has been created
838+
// Make sure the sound has been created.
823839
if (!sound._node.bufferSource) {
824-
return self;
840+
continue;
825841
}
826842

827843
if (typeof sound._node.bufferSource.stop === 'undefined') {
@@ -890,32 +906,26 @@
890906

891907
if (sound._node) {
892908
if (self._webAudio) {
893-
// make sure the sound has been created
894-
if (!sound._node.bufferSource) {
895-
if (!internal) {
896-
self._emit('stop', sound._id);
909+
// Make sure the sound's AudioBufferSourceNode has been created.
910+
if (sound._node.bufferSource) {
911+
if (typeof sound._node.bufferSource.stop === 'undefined') {
912+
sound._node.bufferSource.noteOff(0);
913+
} else {
914+
sound._node.bufferSource.stop(0);
897915
}
898916

899-
return self;
900-
}
901-
902-
if (typeof sound._node.bufferSource.stop === 'undefined') {
903-
sound._node.bufferSource.noteOff(0);
904-
} else {
905-
sound._node.bufferSource.stop(0);
917+
// Clean up the buffer source.
918+
self._cleanBuffer(sound._node);
906919
}
907-
908-
// Clean up the buffer source.
909-
self._cleanBuffer(sound._node);
910920
} else if (!isNaN(sound._node.duration) || sound._node.duration === Infinity) {
911921
sound._node.currentTime = sound._start || 0;
912922
sound._node.pause();
913923
}
914924
}
915-
}
916925

917-
if (sound && !internal) {
918-
self._emit('stop', sound._id);
926+
if (!internal) {
927+
self._emit('stop', sound._id);
928+
}
919929
}
920930
}
921931

@@ -1478,8 +1488,11 @@
14781488

14791489
// Remove the source or disconnect.
14801490
if (!self._webAudio) {
1481-
// Set the source to 0-second silence to stop any downloading.
1482-
sounds[i]._node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA';
1491+
// Set the source to 0-second silence to stop any downloading (except in IE).
1492+
var checkIE = /MSIE |Trident\//.test(Howler._navigator && Howler._navigator.userAgent);
1493+
if (!checkIE) {
1494+
sounds[i]._node.src = 'data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA';
1495+
}
14831496

14841497
// Remove any event listeners.
14851498
sounds[i]._node.removeEventListener('error', sounds[i]._errorFn, false);
@@ -1554,10 +1567,17 @@
15541567
var events = self['_on' + event];
15551568
var i = 0;
15561569

1557-
if (fn) {
1570+
// Allow passing just an event and ID.
1571+
if (typeof fn === 'number') {
1572+
id = fn;
1573+
fn = null;
1574+
}
1575+
1576+
if (fn || id) {
15581577
// Loop through event store and remove the passed function.
15591578
for (i=0; i<events.length; i++) {
1560-
if (fn === events[i].fn && id === events[i].id) {
1579+
var isId = (id === events[i].id);
1580+
if (fn === events[i].fn && isId || !fn && isId) {
15611581
events.splice(i, 1);
15621582
break;
15631583
}
@@ -1655,6 +1675,14 @@
16551675
var self = this;
16561676
var sprite = sound._sprite;
16571677

1678+
// If we are using IE and there was network latency we may be clipping
1679+
// audio before it completes playing. Lets check the node to make sure it
1680+
// believes it has completed, before ending the playback.
1681+
if (!self._webAudio && self._node && !self._node.ended) {
1682+
setTimeout(self._ended.bind(self, sound), 100);
1683+
return self;
1684+
}
1685+
16581686
// Should this sound loop?
16591687
var loop = !!(sound._loop || self._sprite[sprite][2]);
16601688

@@ -1887,7 +1915,6 @@
18871915
self._muted = parent._muted;
18881916
self._loop = parent._loop;
18891917
self._volume = parent._volume;
1890-
self._muted = parent._muted;
18911918
self._rate = parent._rate;
18921919
self._seek = 0;
18931920
self._paused = true;
@@ -1956,7 +1983,6 @@
19561983
self._muted = parent._muted;
19571984
self._loop = parent._loop;
19581985
self._volume = parent._volume;
1959-
self._muted = parent._muted;
19601986
self._rate = parent._rate;
19611987
self._seek = 0;
19621988
self._rateSeek = 0;
@@ -1980,7 +2006,7 @@
19802006
self._parent._emit('loaderror', self._id, self._node.error ? self._node.error.code : 0);
19812007

19822008
// Clear the event listener.
1983-
self._node.removeEventListener('error', self._errorListener, false);
2009+
self._node.removeEventListener('error', self._errorFn, false);
19842010
},
19852011

19862012
/**
@@ -2155,7 +2181,7 @@
21552181
// Create and expose the master GainNode when using Web Audio (useful for plugins or advanced usage).
21562182
if (Howler.usingWebAudio) {
21572183
Howler.masterGain = (typeof Howler.ctx.createGain === 'undefined') ? Howler.ctx.createGainNode() : Howler.ctx.createGain();
2158-
Howler.masterGain.gain.value = 1;
2184+
Howler.masterGain.gain.value = Howler._muted ? 0 : 1;
21592185
Howler.masterGain.connect(Howler.ctx.destination);
21602186
}
21612187

@@ -2197,7 +2223,7 @@
21972223
/*!
21982224
* Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.
21992225
*
2200-
* howler.js v2.0.3
2226+
* howler.js v2.0.4
22012227
* howlerjs.com
22022228
*
22032229
* (c) 2013-2017, James Simpson of GoldFire Studios

dist/howler.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/howler.spatial.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"uglify-js": "2.x"
2929
},
3030
"main": "dist/howler.js",
31-
"version": "2.0.3",
31+
"version": "2.0.4",
3232
"license": "MIT",
3333
"files": [
3434
"src",

src/howler.core.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* howler.js v2.0.3
2+
* howler.js v2.0.4
33
* howlerjs.com
44
*
55
* (c) 2013-2017, James Simpson of GoldFire Studios

src/plugins/howler.spatial.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
* Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.
33
*
4-
* howler.js v2.0.3
4+
* howler.js v2.0.4
55
* howlerjs.com
66
*
77
* (c) 2013-2017, James Simpson of GoldFire Studios

0 commit comments

Comments
 (0)