modified / fixed start, resume, pause and stop functionality

This commit is contained in:
Daniel Sommer 2022-05-02 14:20:33 +02:00
parent 35681ffede
commit 717f1d1fc6
5 changed files with 34 additions and 33 deletions

View file

@ -6,24 +6,27 @@ class StreamBuffer extends EventEmitter {
constructor(stream, settings) { constructor(stream, settings) {
super(); super();
this.size = settings.size;
this.times = { this.times = {
start: Date.now() start: Date.now()
}; };
this.playback = { this.playback = {
paused: false, paused: false,
progress: 0,
hiccups: 0 hiccups: 0
}; };
this.#setupBuffer(settings?.threshold); this.#setupBuffer(settings?.threshold);
this.#setupStreams(stream, settings?.audio); this.#setupStreams(stream, settings?.audio);
} }
resume() { play() {
this.#writeBufferedChunk(4096, true); this.#writeBufferedChunk(4096, true);
} }
pause() { pause() {
this.playback.paused = true; this.playback.paused = true;
this.threshold.announced = false;
this.streams.buffer._readableState.buffer.clear();
this.streams.buffer._readableState.length = 0;
} }
stop() { stop() {
@ -31,7 +34,7 @@ class StreamBuffer extends EventEmitter {
} }
getProgress() { getProgress() {
return this.playback.progress; return this.streams.output?.bytesWritten || 0;
} }
getHiccups() { getHiccups() {
@ -189,12 +192,15 @@ class StreamBuffer extends EventEmitter {
}); });
this.streams.output.on('drain', () => { this.streams.output.on('drain', () => {
this.times.drained = Date.now(); this.times.drained = Date.now();
logger.debug('output stream is drained, file should be completely written to the speaker after ' + (this.times.drained - this.times.start) + 'ms'); logger.debug('output stream is drained, wrote ' + this.streams.output.bytesWritten + '/' + this.size + ' bytes to the speaker after ' + (this.times.drained - this.times.start) + 'ms');
if (this.streams.output.bytesWritten < this.size) {
return;
}
this.#destroy(); this.#destroy();
}); });
this.streams.output.on('progress', (progress) => { // this.streams.output.on('progress', (progress) => {
this.playback.progress = progress; // this.playback.progress = progress;
}); // });
this.streams.output.on('hiccup', () => { this.streams.output.on('hiccup', () => {
this.playback.hiccups++; this.playback.hiccups++;
logger.warn('hiccup ' + this.playback.hiccups + ' detected...'); logger.warn('hiccup ' + this.playback.hiccups + ' detected...');

View file

@ -37,11 +37,15 @@ class Audiostream {
logger.debug('handling event \'audio:initialize\'...'); logger.debug('handling event \'audio:initialize\'...');
this.#initialize(data); this.#initialize(data);
}); });
this.eventParser.on(constants.AUDIO_PLAY, (data) => { this.eventParser.on(constants.AUDIO_PLAY, () => {
logger.debug('handling event \'' + constants.AUDIO_PLAY + '\'...'); logger.debug('handling event \'' + constants.AUDIO_PLAY + '\'...');
global.player.play(); global.player.play();
}); });
this.eventParser.on(constants.AUDIO_PAUSE, (data) => { this.eventParser.on(constants.AUDIO_RESUME, () => {
logger.debug('handling event \'' + constants.AUDIO_RESUME + '\'...');
global.player.resume();
});
this.eventParser.on(constants.AUDIO_PAUSE, () => {
logger.debug('handling event \'' + constants.AUDIO_PAUSE + '\'...'); logger.debug('handling event \'' + constants.AUDIO_PAUSE + '\'...');
global.player.pause(); global.player.pause();
}); });

View file

@ -11,24 +11,24 @@ class Player extends EventEmitter {
async prepare(stream, settings) { async prepare(stream, settings) {
logger.debug('preparing audio player...'); logger.debug('preparing audio player...');
this.#reset(); this.settings = settings;
this.audiobuffer = new AudioBuffer(stream, settings); this.audiobuffer = new AudioBuffer(stream, this.settings);
this.audiobuffer.on(constants.THRESHOLD, () => { this.audiobuffer.on(constants.THRESHOLD, () => {
this.#setState(constants.READY); this.#setState(constants.READY);
}); });
this.audiobuffer.on('close', () => {
this.#setState(constants.STOPPED);
});
this.audiobuffer.on('play', () => { this.audiobuffer.on('play', () => {
this.#setState(constants.PLAYING); this.#setState(constants.PLAYING);
}); });
this.audiobuffer.on('pause', () => { this.audiobuffer.on('pause', () => {
this.#setState(constants.PAUSED); this.#setState(constants.PAUSED);
}) });
this.audiobuffer.on('close', () => {
this.#setState(constants.STOPPED);
});
} }
play() { play() {
this.audiobuffer.resume(); this.audiobuffer.play();
} }
pause() { pause() {
@ -37,8 +37,6 @@ class Player extends EventEmitter {
async stop() { async stop() {
this.audiobuffer.stop(); this.audiobuffer.stop();
this.#reset();
this.#setState(constants.STOPPED);
} }
isReady() { isReady() {
@ -62,28 +60,21 @@ class Player extends EventEmitter {
} }
getProgress() { getProgress() {
return this.audiobuffer?.getProgress(); return this.audiobuffer?.getProgress() || 0;
} }
#setState(state, data) { #setState(state, data) {
if (this.state === state) {
return;
}
this.state = state; this.state = state;
logger.debug('setting state of audio player to \'' + state + '\'...'); logger.debug('setting state of audio player to \'' + state + '\'...');
if (this.events.includes(state)) { // if (this.events.includes(state)) {
return; // return;
} // }
logger.debug('emitting state \'' + state + '\' of audio player...'); logger.debug('emitting state \'' + state + '\' of audio player...');
this.emit(this.state, { data: data }); this.emit(this.state, { data: data });
this.emit(constants.STATECHANGE, { state: this.state, progress: this.getProgress() }); this.emit(constants.STATECHANGE, { state: this.state, progress: this.getProgress() });
this.events.push(state); this.events.push(state);
} }
#reset() {
this.events = [];
}
} }
module.exports = Player; module.exports = Player;

View file

@ -15,6 +15,7 @@ module.exports = {
PROGRESS: 'progress', PROGRESS: 'progress',
AUDIO_PLAY: 'audio:play', AUDIO_PLAY: 'audio:play',
AUDIO_RESUME: 'audio:resume',
AUDIO_PAUSE: 'audio:pause', AUDIO_PAUSE: 'audio:pause',
AUDIO_STOP: 'audio:stop', AUDIO_STOP: 'audio:stop',
AUDIO_STATE: 'audio:state', AUDIO_STATE: 'audio:state',

View file

@ -51,7 +51,7 @@ class Speaker extends Writable {
this.on('unpipe', this._unpipe) this.on('unpipe', this._unpipe)
// total bytes written // total bytes written
this.bytesWritten = 0; this.bytesWritten = 0
} }
/** /**
@ -206,9 +206,8 @@ class Speaker extends Writable {
} }
const onwrite = (r) => { const onwrite = (r) => {
this.bytesWritten += r; this.bytesWritten += r
this.emit('written', r); this.emit('written', r)
this.emit('progress', this.bytesWritten);
debug('wrote %o bytes', r) debug('wrote %o bytes', r)
if (r === 0) { if (r === 0) {
this.emit('hiccup'); this.emit('hiccup');