From 4fa68a30596f7a8ae07ef997b4cfdd1535627d14 Mon Sep 17 00:00:00 2001 From: velvettear Date: Thu, 14 Apr 2022 15:26:46 +0200 Subject: [PATCH] bandaid fixed play/pause --- classes/Audiostream.js | 18 ++++++----- classes/Player.js | 69 ++++++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/classes/Audiostream.js b/classes/Audiostream.js index 186df14..870ad9f 100644 --- a/classes/Audiostream.js +++ b/classes/Audiostream.js @@ -1,6 +1,5 @@ const net = require('net'); const Message = require('./Message'); -const Player = require('./Player.js'); class Audiostream { @@ -49,16 +48,19 @@ class Audiostream { socket.on('close', () => { logger.info('connection to audio server \'' + this.getTag() + '\' closed'); }); - // global.player.on('spawned', () => { - // while (this.buffer.length > 0) { - // const tmp = this.buffer[0]; - // this.buffer.shift(); - // global.player.feed(tmp); - // } - // }); global.player.on('ready', () => { global.player.play(); }); + global.player.on('playing', async () => { + await new Promise((resolve, reject) => { + setTimeout(resolve, 10000); + }); + global.player.pause(); + await new Promise((resolve, reject) => { + setTimeout(resolve, 2000); + }); + global.player.play(); + }); } } diff --git a/classes/Player.js b/classes/Player.js index 45eb0d5..31030db 100644 --- a/classes/Player.js +++ b/classes/Player.js @@ -1,13 +1,15 @@ const EventEmitter = require('events'); const { sleep } = require('../libs/util.js'); const { spawn } = require('child_process'); -const fs = require('fs'); +const createWriteStream = require('fs').createWriteStream; +const unlink = require('fs/promises').unlink; +const resolve = require('path').resolve; const STATE_SPAWNED = 'spawned'; const STATE_READY = 'ready'; const STATE_PLAYING = 'playing'; const STATE_PAUSED = 'paused'; -const STATE_FINISHED = 'finished'; +const STATE_STOPPED = 'stopped'; const STATE_ERROR = 'error'; class Player extends EventEmitter { @@ -17,6 +19,9 @@ class Player extends EventEmitter { this.position = 0; this.events = []; this.buffer = []; + this.tmp = { + file: resolve('/tmp/kannon.tmp') + } this.buffersize = 0; } @@ -24,8 +29,9 @@ class Player extends EventEmitter { logger.debug('preparing audio player...'); this.size = size; this.threshold = threshold; + this.tmp.stream = createWriteStream(this.tmp.file); this.#reset(); - await this.#spawnProcess(); + this.#spawnProcess(); } feed(buffer) { @@ -37,10 +43,6 @@ class Player extends EventEmitter { } async play() { - if (this.buffer === undefined || this.buffer.length === 0) { - logger.warn('aborting playback of an empty buffer...'); - return; - } if (this.isPlaying()) { this.stop(); } @@ -53,11 +55,18 @@ class Player extends EventEmitter { return; } this.position = position; - logger.debug('CURRENT POSITION: ' + this.position); }); this.process.stdin.on('error', (error) => { this.#setState(STATE_ERROR, error); }); + if (this.process.spawnargs[this.process.spawnargs.length] === this.tmp.file) { + return; + } + if (this.buffer === undefined || this.buffer.length === 0) { + logger.warn('aborting playback of an empty buffer...'); + return; + } + const timestamp = Date.now(); while (true) { if (this.buffer.length === 0 && this.buffersize !== this.size) { await sleep(1); @@ -66,18 +75,24 @@ class Player extends EventEmitter { const tmp = this.buffer[0]; this.buffer.shift(); if (this.buffer.length === 0 && this.buffersize === this.size) { + logger.warn('BUFFER EMPTIED AFTER ' + ( Date.now() - timestamp) + 'ms') this.process.stdin.end(tmp); + this.tmp.stream.end(tmp); break; - } + } + this.tmp.stream.write(tmp); this.process.stdin.write(tmp); } } async pause() { - this.#reset(true); + this.#setState(STATE_PAUSED); + this.#reset(); + this.#spawnProcess(); } async stop() { + this.#setState(STATE_STOPPED); this.#reset(); } @@ -98,7 +113,7 @@ class Player extends EventEmitter { } isFinished() { - return this.state === STATE_FINISHED; + return this.state === STATE_STOPPED; } hasError() { @@ -106,11 +121,21 @@ class Player extends EventEmitter { } async #spawnProcess() { + if (this.process !== undefined) { + return; + } return new Promise((resolve, reject) => { - if (this.process !== undefined) { - resolve(); + const args = [ + '-vn', + '-nodisp' + ]; + if (this.isPaused()) { + args.unshift('-ss', this.position); + args.push(this.tmp.file); + } else { + args.push('-'); } - this.process = spawn("ffplay", ['-vn', '-nodisp', '-']); + this.process = spawn("ffplay", args); this.process.on('error', (error) => { this.#reset(); // TODO: try/catch error @@ -154,7 +179,7 @@ class Player extends EventEmitter { if (this.events.includes(state)) { return; } - logger.debug('emitting state of audio player...'); + logger.debug('emitting state \'' + state + '\' of audio player...'); this.emit(state, data); this.events.push(state); } @@ -176,13 +201,19 @@ class Player extends EventEmitter { } } - #reset(keepBuffer) { + async #reset() { this.#killProcess(); - this.position = 0; this.events = []; - if (keepBuffer !== true) { - this.buffer = []; + this.buffer = []; + if (!this.isPaused()) { + this.position = 0; + this.backupbuffer = []; this.buffersize = 0; + try { + await unlink(this.tmp.file); + } catch (error) { + logger.error('no file to unlink ' + this.tmp.file); + } } }