implemented / fixed start, resume, pause and stop functionality

This commit is contained in:
Daniel Sommer 2022-05-02 14:19:30 +02:00
parent 7dc3fb6ece
commit ac1fca8368
3 changed files with 55 additions and 24 deletions

View file

@ -40,17 +40,19 @@ class Api {
}
global.audioserver = new AudioServer('/home/velvettear/mounts/kingston/public/test.pcm');
});
this.#registerEndpoint(constants.API_RESUME, constants.REQUEST_METHOD_POST, async () => {
if (global.audioserver === undefined) {
return;
}
await global.audioserver.destroy();
global.audioserver = new AudioServer('/home/velvettear/mounts/kingston/public/test.pcm', global.audioserver.progress);
});
this.#registerEndpoint(constants.API_PAUSE, constants.REQUEST_METHOD_POST, async () => {
if (global.audioserver === undefined) {
return;
}
global.audioserver.pausePlayback();
});
this.#registerEndpoint(constants.API_RESUME, constants.REQUEST_METHOD_POST, async () => {
if (global.audioserver === undefined) {
return;
}
});
this.#registerEndpoint(constants.API_STOP, constants.REQUEST_METHOD_POST, async () => {
if (global.audioserver === undefined) {
return;

View file

@ -1,24 +1,21 @@
const sleep = require('../libs/util.js').sleep;
const net = require('net');
const fs = require('fs');
const stat = require('fs/promises').stat;
const { stat, open } = require('fs/promises');
const Message = require('./Message.js');
const constants = require('../libs/constants.js');
class AudioServer {
constructor(file) {
constructor(file, progress) {
this.listen = config?.server?.listen || '0.0.0.0';
this.port = 0;
this.buffer = {
file: file,
stream: fs.createReadStream(file)
file: file
};
this.clients = [];
this.sockets = [];
this.broadcasts = {};
this.progress = 0;
this.progress = progress || 0;
this.server = net.createServer();
this.#prepare();
}
@ -41,17 +38,35 @@ class AudioServer {
});
this.server.on('error', (err) => {
logger.error('ERROR IN AUDIOSERVER ' + err);
reject('an error occured preparing the audio server for file \'' + this.file + '\' > ' + err);
reject('audio server encountered an error: ' + err);
});
this.server.on('close', () => {
logger.info('audio server closed');
});
});
await this.#prepareBuffer();
this.#announceAudioServer();
}
async #prepareBuffer() {
if (this.buffer.fd !== undefined) {
this.buffer.fd.close();
}
if (this.buffer.stream?.destroyed === false) {
this.buffer.stream.close();
this.buffer.stream.destroy();
}
this.buffer.fd = await open(this.buffer.file);
this.buffer.stream = this.buffer.fd.createReadStream({
start: this.progress
});
const stats = await stat(this.buffer.file);
this.buffer.size = stats.size;
this.buffer.size = stats.size - this.progress;
let percentage = 30;
if (!(isNaN(config.audio?.threshold))) {
percentage = config.audio.threshold;
}
this.buffer.threshold = (this.buffer.size / 100) * percentage;
this.#announceAudioServer();
}
#handleEvents() {
@ -145,6 +160,9 @@ class AudioServer {
if (client === undefined) {
return;
}
if (this.progress < data?.progress) {
this.progress = data.progress;
}
switch (client.state) {
case constants.CLIENT_STATE_REGISTERED:
return this.#handleStateRegistered(client);
@ -174,7 +192,7 @@ class AudioServer {
if (!this.#allClientsInState(constants.CLIENT_STATE_READY)) {
return;
}
this.#startPlayback();
this.startPlayback();
}
async #handleStatePlaying(client) {
@ -196,6 +214,10 @@ class AudioServer {
async #handleStateStopped(client, data) {
logger.debug(client.getTag() + ' stopped playback, progress: ' + data.progress + '/' + this.buffer.size + '...');
if (!this.#allClientsInState(constants.CLIENT_STATE_STOPPED)) {
return;
}
this.destroy();
}
async #handleStateError(client, data) {
@ -232,7 +254,7 @@ class AudioServer {
logger.debug('sent broadcast for audio server to client(s) \'' + this.broadcasts[constants.CLIENT_STATE_REGISTERED] + '\'...');
}
async #startPlayback() {
async startPlayback() {
this.broadcasts[constants.CLIENT_STATE_PLAYING] = await new Message('audio:play').broadcast();
logger.debug('sent broadcast to start playback to client(s) \'' + this.broadcasts[constants.CLIENT_STATE_PLAYING] + '\'...');
}
@ -289,16 +311,22 @@ class AudioServer {
}
audiosocket.destroy();
}
this.buffer.fd.close();
this.buffer.stream.close();
this.buffer.stream.destroy();
if (this.server?.listening !== true) {
return;
}
await new Promise((resolve, reject) => {
this.server.close((err) => {
if (err !== undefined) {
logger.error('ERROR CLOSING AUDIOSERVER ' + err);
reject(err);
this.server.close((error) => {
if (error !== undefined) {
logger.error('an error occured closing the audio server: ' + error);
// TODO: reject and try/catch later?
// reject(error);
}
resolve();
});
});
}
}

View file

@ -9,6 +9,7 @@ module.exports = {
CLIENT_STATE_READY: 'ready',
CLIENT_STATE_PLAYING: 'playing',
CLIENT_STATE_PAUSED: 'paused',
CLIENT_STATE_RESUMING: 'resuming',
CLIENT_STATE_STOPPED: 'stopped',
CLIENT_STATE_ERROR: 'error',