Skip to content

Commit ef3cb1f

Browse files
committed
Sound in Web Audio now uses AudioContext.onended to trigger when it will stop playing instead of using a time based value. This is only used if the sound doesn't loop and isn't an audio sprite, but will give a much more accurate Sound.onStop event. It also prevents short audio files from being cut off during playback (phaserjs#1471) and accounts for time spent decoding.
1 parent eba1743 commit ef3cb1f

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ We've also removed functions and properties from Pixi classes that Phaser doesn'
148148
* PIXI.TextureSilentFail is a boolean that defaults to `false`. If `true` then `PIXI.Texture.setFrame` will no longer throw an error if the texture dimensions are incorrect. Instead `Texture.valid` will be set to `false` (#1556)
149149
* InputHandler.enableDrag with a boundsRect set now takes into account the Sprites anchor when limiting the drag (thanks @unindented #1593)
150150
* InputHandler.enableDrag with a boundsSprite set now takes into account both the Sprites anchor and the boundsSprite anchor when limiting the drag.
151+
* Sound in Web Audio now uses AudioContext.onended to trigger when it will stop playing instead of using a time based value. This is only used if the sound doesn't loop and isn't an audio sprite, but will give a much more accurate `Sound.onStop` event. It also prevents short audio files from being cut off during playback (#1471) and accounts for time spent decoding.
151152

152153
### Bug Fixes
153154

src/sound/Sound.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,20 @@ Phaser.Sound.prototype = {
376376

377377
},
378378

379+
/**
380+
* Called automatically by the AudioContext when the sound stops playing.
381+
* Doesn't get called if the sound is set to loop or is a section of an Audio Sprite.
382+
*
383+
* @method Phaser.Sound#onEndedHandler
384+
* @protected
385+
*/
386+
onEndedHandler: function () {
387+
388+
this.isPlaying = false;
389+
this.stop();
390+
391+
},
392+
379393
/**
380394
* Called automatically by Phaser.SoundManager.
381395
* @method Phaser.Sound#update
@@ -423,7 +437,11 @@ Phaser.Sound.prototype = {
423437
}
424438
else
425439
{
426-
this.stop();
440+
// Stop if we're using an audio marker, otherwise we let onended handle it
441+
if (this.currentMarker !== '')
442+
{
443+
this.stop();
444+
}
427445
}
428446
}
429447
else
@@ -595,13 +613,20 @@ Phaser.Sound.prototype = {
595613
this._sound.loop = true;
596614
}
597615

616+
if (!this.loop && marker === '')
617+
{
618+
this._sound.onended = this.onEndedHandler.bind(this);
619+
}
620+
598621
this.totalDuration = this._sound.buffer.duration;
599622

623+
// console.log('dur', this._sound.buffer.duration, Math.ceil(this._sound.buffer.duration * 1000));
624+
600625
if (this.duration === 0)
601626
{
602627
// console.log('duration reset');
603628
this.duration = this.totalDuration;
604-
this.durationMS = this.totalDuration * 1000;
629+
this.durationMS = Math.ceil(this.totalDuration * 1000);
605630
}
606631

607632
// Useful to cache this somewhere perhaps?
@@ -788,6 +813,8 @@ Phaser.Sound.prototype = {
788813
*/
789814
stop: function () {
790815

816+
if (typeof fromNative === 'undefined') { fromNative = false; }
817+
791818
if (this.isPlaying && this._sound)
792819
{
793820
if (this.usingWebAudio)

0 commit comments

Comments
 (0)