close/destroy streams when playback finished
This commit is contained in:
parent
cb011c903b
commit
e0a8d2350e
3 changed files with 48 additions and 13 deletions
|
@ -1,6 +1,9 @@
|
||||||
const NodeSpeaker = require('../libs/speaker/index.js');
|
const NodeSpeaker = require('../libs/speaker/index.js');
|
||||||
const EventEmitter = require('events');
|
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 {
|
class StreamBuffer extends EventEmitter {
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ class StreamBuffer extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
getProgress() {
|
getProgress() {
|
||||||
return this.streams.output?.bytesWritten || 0;
|
return this.streams?.output?.bytesWritten || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHiccups() {
|
getHiccups() {
|
||||||
|
@ -169,6 +172,13 @@ class StreamBuffer extends EventEmitter {
|
||||||
this.streams.buffer.on('error', (error) => {
|
this.streams.buffer.on('error', (error) => {
|
||||||
logger.error('buffer stream encountered an 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() {
|
#handleInputStream() {
|
||||||
|
@ -182,8 +192,12 @@ class StreamBuffer extends EventEmitter {
|
||||||
this.#fillBuffer();
|
this.#fillBuffer();
|
||||||
});
|
});
|
||||||
this.streams.input.on('close', () => {
|
this.streams.input.on('close', () => {
|
||||||
|
if (this.streams.input.destroyed !== true) {
|
||||||
|
return this.streams.input.destroy();
|
||||||
|
}
|
||||||
this.times.transmitted = Date.now();
|
this.times.transmitted = Date.now();
|
||||||
logger.debug('input stream closed, transmitting file took ' + (this.times.transmitted - this.times.start) + 'ms');
|
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) => {
|
this.streams.output.on('error', (error) => {
|
||||||
logger.error('output stream encountered an error: ' + error);
|
logger.error('output stream encountered an error: ' + error);
|
||||||
this.#createOutputStream();
|
restart();
|
||||||
});
|
});
|
||||||
this.streams.output.on('written', (bytes) => {
|
this.streams.output.on('written', (bytes) => {
|
||||||
this.#writeBufferedChunk(bytes);
|
this.#writeBufferedChunk(bytes);
|
||||||
|
@ -207,6 +221,13 @@ class StreamBuffer extends EventEmitter {
|
||||||
}
|
}
|
||||||
this.#destroy();
|
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.streams.output.on('hiccup', () => {
|
||||||
this.playback.hiccups++;
|
this.playback.hiccups++;
|
||||||
logger.warn('hiccup ' + this.playback.hiccups + ' detected...');
|
logger.warn('hiccup ' + this.playback.hiccups + ' detected...');
|
||||||
|
@ -214,13 +235,9 @@ class StreamBuffer extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
#destroy() {
|
#destroy() {
|
||||||
for (const key in this.streams) {
|
this.streams.input.destroy();
|
||||||
const stream = this.streams[key];
|
this.streams.buffer.destroy();
|
||||||
if (stream.destroyed === true) {
|
this.streams.output.close();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stream.destroy();
|
|
||||||
}
|
|
||||||
this.times.stop = Date.now();
|
this.times.stop = Date.now();
|
||||||
this.emit('close');
|
this.emit('close');
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,10 +72,10 @@ class Player extends EventEmitter {
|
||||||
if (this.events.includes(state)) {
|
if (this.events.includes(state)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.events.push(state);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
20
libs/util.js
20
libs/util.js
|
@ -1,3 +1,5 @@
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
|
||||||
function isEnabled(parameter) {
|
function isEnabled(parameter) {
|
||||||
return isSet(parameter?.enabled) && parameter.enabled === true;
|
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 = {
|
module.exports = {
|
||||||
isEnabled,
|
isEnabled,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
isSet,
|
isSet,
|
||||||
isUnset,
|
isUnset,
|
||||||
sleep
|
sleep,
|
||||||
|
restart
|
||||||
}
|
}
|
Loading…
Reference in a new issue