close/destroy streams when playback finished

This commit is contained in:
Daniel Sommer 2022-05-03 14:58:02 +02:00
parent cb011c903b
commit e0a8d2350e
3 changed files with 48 additions and 13 deletions

View file

@ -1,6 +1,9 @@
const NodeSpeaker = require('../libs/speaker/index.js');
const EventEmitter = require('events');
const { Readable } = require('stream');
const { Readable, Writable } = require('stream');
const { restart } = require('../libs/util.js');
const { Socket } = require('net');
class StreamBuffer extends EventEmitter {
@ -35,7 +38,7 @@ class StreamBuffer extends EventEmitter {
}
getProgress() {
return this.streams.output?.bytesWritten || 0;
return this.streams?.output?.bytesWritten || 0;
}
getHiccups() {
@ -169,6 +172,13 @@ class StreamBuffer extends EventEmitter {
this.streams.buffer.on('error', (error) => {
logger.error('buffer stream encountered an error: ' + error);
});
this.streams.buffer.on('close', () => {
if (this.streams.buffer.destroyed !== true) {
return this.streams.buffer.destroy();
}
logger.debug('buffer stream closed');
this.streams.buffer.removeAllListeners();
});
}
#handleInputStream() {
@ -182,8 +192,12 @@ class StreamBuffer extends EventEmitter {
this.#fillBuffer();
});
this.streams.input.on('close', () => {
if (this.streams.input.destroyed !== true) {
return this.streams.input.destroy();
}
this.times.transmitted = Date.now();
logger.debug('input stream closed, transmitting file took ' + (this.times.transmitted - this.times.start) + 'ms');
this.streams.input.removeAllListeners();
});
}
@ -193,7 +207,7 @@ class StreamBuffer extends EventEmitter {
}
this.streams.output.on('error', (error) => {
logger.error('output stream encountered an error: ' + error);
this.#createOutputStream();
restart();
});
this.streams.output.on('written', (bytes) => {
this.#writeBufferedChunk(bytes);
@ -207,6 +221,13 @@ class StreamBuffer extends EventEmitter {
}
this.#destroy();
});
this.streams.output.on('close', () => {
if (this.streams.output.destroyed !== true) {
return this.streams.output.destroy();
}
logger.debug('output stream closed');
this.streams.output.removeAllListeners();
});
this.streams.output.on('hiccup', () => {
this.playback.hiccups++;
logger.warn('hiccup ' + this.playback.hiccups + ' detected...');
@ -214,13 +235,9 @@ class StreamBuffer extends EventEmitter {
}
#destroy() {
for (const key in this.streams) {
const stream = this.streams[key];
if (stream.destroyed === true) {
continue;
}
stream.destroy();
}
this.streams.input.destroy();
this.streams.buffer.destroy();
this.streams.output.close();
this.times.stop = Date.now();
this.emit('close');
}

View file

@ -72,10 +72,10 @@ class Player extends EventEmitter {
if (this.events.includes(state)) {
return;
}
this.events.push(state);
logger.debug('emitting state \'' + state + '\' of audio player...');
this.emit(this.state, { data: data });
this.emit(constants.STATECHANGE, { state: this.state, progress: this.getProgress() });
this.events.push(state);
}
}

View file

@ -1,3 +1,5 @@
const { spawn } = require('child_process');
function isEnabled(parameter) {
return isSet(parameter?.enabled) && parameter.enabled === true;
}
@ -23,10 +25,26 @@ async function sleep(ms) {
});
}
function restart() {
const args = process.argv;
const cmd = args[0];
args.shift();
const newProcess = spawn(cmd, args, { detached: true, stdio: 'ignore' });
newProcess.unref();
newProcess.on('error', (error) => {
logger.error('ERROR RESTARTING: '+ error);
});
newProcess.on('spawn', () => {
logger.warn('PROCESS RESTARTED WITH PID: ' + newProcess.pid);
process.exit(0);
});
}
module.exports = {
isEnabled,
isDisabled,
isSet,
isUnset,
sleep
sleep,
restart
}