From 9eaf1456b28f3152c84fff15c2afcbadb1684bde Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Wed, 12 Apr 2017 20:12:51 +0100 Subject: [PATCH] Clean up AudioPlayer internals, remove the concept of multiple "temporary" streams --- src/client/voice/player/AudioPlayer.js | 68 +++++++++++++++----------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/client/voice/player/AudioPlayer.js b/src/client/voice/player/AudioPlayer.js index 54932bcb8..f49becf22 100644 --- a/src/client/voice/player/AudioPlayer.js +++ b/src/client/voice/player/AudioPlayer.js @@ -36,6 +36,7 @@ class AudioPlayer extends EventEmitter { */ this.opusEncoder = OpusEncoders.fetch(); this.streams = new Collection(); + this.currentStream = {}; this.streamingData = { channels: 2, count: 0, @@ -47,7 +48,7 @@ class AudioPlayer extends EventEmitter { } get currentTranscoder() { - return (this.streams.last() || {}).transcoder; + return this.currentStream.transcoder; } /** @@ -56,29 +57,19 @@ class AudioPlayer extends EventEmitter { * @readonly */ get currentDispatcher() { - return this.streams.size > 0 ? this.streams.last().dispatcher || null : null; + return this.currentStream.dispatcher; } destroy() { if (this.opusEncoder) this.opusEncoder.destroy(); } - destroyStream(stream) { - const data = this.streams.get(stream); - if (!data) return; - const transcoder = data.transcoder; - const dispatcher = data.dispatcher; + destroyCurrentStream() { + const transcoder = this.currentTranscoder; + const dispatcher = this.currentDispatcher; if (transcoder) transcoder.kill(); if (dispatcher) dispatcher.destroy('end'); - this.streams.delete(stream); - } - - destroyAllStreams(except) { - for (const stream of this.streams.keys()) { - if (except === stream) continue; - if (except === true && this.streams.get(stream) === this.streams.last()) continue; - this.destroyStream(stream); - } + this.currentStream = {}; } playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { @@ -89,30 +80,46 @@ class AudioPlayer extends EventEmitter { media: stream, ffmpegArguments: ffmpegArguments.concat(['-ss', String(seek)]), }); - this.streams.set(transcoder.output, { transcoder, input: stream }); + this.destroyCurrentStream(); + this.currentStream = { + transcoder: transcoder, + output: transcoder.output, + input: stream, + }; transcoder.on('error', e => { - this.destroyStream(stream); + this.destroyCurrentStream(); if (this.listenerCount('error') > 0) this.emit('error', e); this.emit('warn', `prism transcoder error - ${e}`); }); - return this.playPCMStream(transcoder.output, options); + return this.playPCMStream(transcoder.output, options, true); } - playPCMStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { + playPCMStream(stream, { seek = 0, volume = 1, passes = 1 } = {}, fromUnknown = false) { OpusEncoders.guaranteeOpusEngine(); const options = { seek, volume, passes }; - this.destroyAllStreams(stream); const dispatcher = this.createDispatcher(stream, options); - if (!this.streams.has(stream)) this.streams.set(stream, { dispatcher, input: stream }); - this.streams.get(stream).dispatcher = dispatcher; + if (fromUnknown) { + this.currentStream.dispatcher = dispatcher; + } else { + this.destroyCurrentStream(); + this.currentStream = { + dispatcher, + input: stream, + output: stream, + }; + } return dispatcher; } playOpusStream(stream, { seek = 0, passes = 1 } = {}) { const options = { seek, passes, opus: true }; - this.destroyAllStreams(stream); + this.destroyCurrentStream(); const dispatcher = this.createDispatcher(stream, options); - this.streams.set(stream, { dispatcher, input: stream }); + this.currentStream = { + dispatcher, + input: stream, + output: stream, + }; return dispatcher; } @@ -120,15 +127,20 @@ class AudioPlayer extends EventEmitter { const options = { volume, passes }; this.destroyAllStreams(); const dispatcher = this.createDispatcher(broadcast, options); - this.streams.set(broadcast, { dispatcher, input: broadcast }); + this.currentStream = { + dispatcher, + broadcast, + input: broadcast, + output: broadcast, + }; broadcast.registerDispatcher(dispatcher); return dispatcher; } createDispatcher(stream, options) { const dispatcher = new StreamDispatcher(this, stream, options); - dispatcher.on('end', () => this.destroyStream(stream)); - dispatcher.on('error', () => this.destroyStream(stream)); + dispatcher.on('end', () => this.destroyCurrentStream()); + dispatcher.on('error', () => this.destroyCurrentStream()); dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value)); return dispatcher; }