mirror of
https://github.com/scratchfoundation/scratch-audio.git
synced 2024-12-22 22:12:48 -05:00
fix: listen to ended event to note playback stopping
- Fix playing a sound a second time once the first playback finished
This commit is contained in:
parent
a5702a7d49
commit
5c822e6542
1 changed files with 39 additions and 12 deletions
|
@ -2,6 +2,8 @@ const {EventEmitter} = require('events');
|
||||||
|
|
||||||
const VolumeEffect = require('./effects/VolumeEffect');
|
const VolumeEffect = require('./effects/VolumeEffect');
|
||||||
|
|
||||||
|
const ON_ENDED = 'ended';
|
||||||
|
|
||||||
class SoundPlayer extends EventEmitter {
|
class SoundPlayer extends EventEmitter {
|
||||||
constructor (audioEngine, {id, buffer}) {
|
constructor (audioEngine, {id, buffer}) {
|
||||||
super();
|
super();
|
||||||
|
@ -17,31 +19,48 @@ class SoundPlayer extends EventEmitter {
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
this.playbackRate = 1;
|
this.playbackRate = 1;
|
||||||
|
|
||||||
this.onEnd = this.onEnd.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnd () {
|
/**
|
||||||
|
* Handle any event we have told the output node to listen for.
|
||||||
|
*/
|
||||||
|
handleEvent (event) {
|
||||||
|
if (event.type === ON_ENDED) {
|
||||||
|
this.onEnded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnded () {
|
||||||
this.emit('stop');
|
this.emit('stop');
|
||||||
|
|
||||||
|
this.isPlaying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize () {
|
_createSource () {
|
||||||
|
if (this.outputNode !== null) {
|
||||||
|
this.outputNode.removeEventListener(ON_ENDED, this);
|
||||||
|
this.outputNode.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
this.outputNode = this.audioEngine.audioContext.createBufferSource();
|
this.outputNode = this.audioEngine.audioContext.createBufferSource();
|
||||||
this.outputNode.playbackRate.value = this.playbackRate;
|
this.outputNode.playbackRate.value = this.playbackRate;
|
||||||
this.outputNode.buffer = this.buffer;
|
this.outputNode.buffer = this.buffer;
|
||||||
|
|
||||||
this.outputNode.addEventListener('end', this.onEnd);
|
this.outputNode.addEventListener(ON_ENDED, this);
|
||||||
|
|
||||||
this.volumeEffect = new VolumeEffect(this.audioEngine, this, null);
|
|
||||||
|
|
||||||
this.initialized = true;
|
|
||||||
|
|
||||||
if (this.target !== null) {
|
if (this.target !== null) {
|
||||||
this.connect(this.target);
|
this.connect(this.target);
|
||||||
this.setPlaybackRate(this.playbackRate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize () {
|
||||||
|
this.initialized = true;
|
||||||
|
|
||||||
|
this.volumeEffect = new VolumeEffect(this.audioEngine, this, null);
|
||||||
|
|
||||||
|
this._createSource();
|
||||||
|
}
|
||||||
|
|
||||||
connect (target) {
|
connect (target) {
|
||||||
if (target === this.volumeEffect) {
|
if (target === this.volumeEffect) {
|
||||||
this.outputNode.disconnect();
|
this.outputNode.disconnect();
|
||||||
|
@ -79,7 +98,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
|
|
||||||
take () {
|
take () {
|
||||||
if (this.outputNode) {
|
if (this.outputNode) {
|
||||||
this.outputNode.removeEventListener('end', this.onEnd);
|
this.outputNode.removeEventListener(ON_ENDED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const taken = new SoundPlayer(this.audioEngine, this);
|
const taken = new SoundPlayer(this.audioEngine, this);
|
||||||
|
@ -119,6 +138,8 @@ class SoundPlayer extends EventEmitter {
|
||||||
|
|
||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
} else {
|
||||||
|
this._createSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.volumeEffect.set(this.volumeEffect.DEFAULT_VALUE);
|
this.volumeEffect.set(this.volumeEffect.DEFAULT_VALUE);
|
||||||
|
@ -135,7 +156,7 @@ class SoundPlayer extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.volumeEffect.set(0);
|
this.volumeEffect.set(0);
|
||||||
this.outputNode.stop(this.audioEngine.audioEngineoContext.currentTime + this.audioEngine.DECAY_TIME);
|
this.outputNode.stop(this.audioEngine.audioContext.currentTime + this.audioEngine.DECAY_TIME);
|
||||||
|
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
|
||||||
|
@ -154,6 +175,12 @@ class SoundPlayer extends EventEmitter {
|
||||||
this.emit('stop');
|
this.emit('stop');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finished () {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.once('stop', resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setPlaybackRate (value) {
|
setPlaybackRate (value) {
|
||||||
this.playbackRate = value;
|
this.playbackRate = value;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue