From 6490d1b911a8922ca048a1d48a71206cebd78ed1 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Thu, 26 Oct 2017 18:36:04 +0100 Subject: [PATCH] FEC and PLP exposed --- src/client/voice/VoiceConnection.js | 4 +++- src/client/voice/dispatcher/StreamDispatcher.js | 8 +++++++- src/client/voice/player/AudioPlayer.js | 9 ++++----- test/voice.js | 10 +++++----- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/client/voice/VoiceConnection.js b/src/client/voice/VoiceConnection.js index 9465caa95..42b7fabe0 100644 --- a/src/client/voice/VoiceConnection.js +++ b/src/client/voice/VoiceConnection.js @@ -434,7 +434,9 @@ class VoiceConnection extends EventEmitter { * @property {number} [seek=0] The time to seek to * @property {number} [volume=1] The volume to play at * @property {number} [passes=1] How many times to send the voice packet to reduce packet loss - * @property {number|string} [bitrate=48000] The bitrate (quality) of the audio. + * @property {number} [plp] Expected packet loss percentage + * @property {boolean} [fec] Enabled forward error correction + * @property {number|string} [bitrate=96] The bitrate (quality) of the audio in kbps * If set to 'auto', the voice channel's bitrate will be used */ diff --git a/src/client/voice/dispatcher/StreamDispatcher.js b/src/client/voice/dispatcher/StreamDispatcher.js index 9bb7e2bd6..82f30b4dc 100644 --- a/src/client/voice/dispatcher/StreamDispatcher.js +++ b/src/client/voice/dispatcher/StreamDispatcher.js @@ -29,7 +29,8 @@ nonce.fill(0); * @extends {stream.Writable} */ class StreamDispatcher extends Writable { - constructor(player, streamOptions, streams) { + constructor(player, { seek = 0, volume = 1, passes = 1, fec, plp, bitrate = 96 } = {}, streams) { + const streamOptions = { seek, volume, passes, fec, plp, bitrate }; super(streamOptions); /** * The Audio Player that controls this dispatcher @@ -55,6 +56,11 @@ class StreamDispatcher extends Writable { // Still emitting end for backwards compatibility, probably remove it in the future! this.emit('end'); }); + + if (typeof volume !== 'undefined') this.setVolume(volume); + if (typeof fec !== 'undefined') this.setFEC(fec); + if (typeof plp !== 'undefined') this.setPLP(plp); + if (typeof bitrate !== 'undefined') this.setBitrate(bitrate); } get _sdata() { diff --git a/src/client/voice/player/AudioPlayer.js b/src/client/voice/player/AudioPlayer.js index cae69f099..8ef3d7673 100644 --- a/src/client/voice/player/AudioPlayer.js +++ b/src/client/voice/player/AudioPlayer.js @@ -46,14 +46,14 @@ class AudioPlayer extends EventEmitter { } } - playUnknownStream(stream, options = {}) { + playUnknownStream(stream, options) { this.destroyDispatcher(); const ffmpeg = new prism.FFmpeg({ args: FFMPEG_ARGUMENTS }); stream.pipe(ffmpeg); return this.playPCMStream(ffmpeg, options, { ffmpeg }); } - playPCMStream(stream, options = {}, streams = {}) { + playPCMStream(stream, options, streams = {}) { this.destroyDispatcher(); const volume = streams.volume = new prism.VolumeTransformer16LE(null, { volume: 0.2 }); const opus = streams.opus = new prism.opus.Encoder({ channels: 2, rate: 48000, frameSize: 960 }); @@ -61,7 +61,7 @@ class AudioPlayer extends EventEmitter { return this.playOpusStream(opus, options, streams); } - playOpusStream(stream, options = {}, streams = {}) { + playOpusStream(stream, options, streams = {}) { this.destroyDispatcher(); streams.opus = stream; const dispatcher = this.dispatcher = this.createDispatcher(options, streams); @@ -69,9 +69,8 @@ class AudioPlayer extends EventEmitter { return dispatcher; } - createDispatcher({ seek = 0, volume = 1, passes = 1 } = {}, streams) { + createDispatcher(options, streams) { this.destroyDispatcher(); - const options = { seek, volume, passes }; const dispatcher = new StreamDispatcher(this, options, streams); dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value)); return dispatcher; diff --git a/test/voice.js b/test/voice.js index c88cbed31..60f923278 100644 --- a/test/voice.js +++ b/test/voice.js @@ -14,7 +14,7 @@ client.login(auth.token).then(() => console.log('logged')).catch(console.error); const connections = new Map(); -let broadcast; +var d; client.on('debug', console.log); client.on('error', console.log); @@ -29,9 +29,7 @@ client.on('message', m => { conn.player.on('error', (...e) => console.log('player', ...e)); if (!connections.has(m.guild.id)) connections.set(m.guild.id, { conn, queue: [] }); m.reply('ok!'); - const d = conn.playOpusStream( - fs.createReadStream('C:/users/amish/downloads/s.ogg').pipe(new prism.OggOpusDemuxer()) - ); + d = conn.playStream(ytdl('https://www.youtube.com/watch?v=EUoe7cf0HYw', { filter: 'audioonly' }, { passes: 3 })); }); } else { m.reply('Specify a voice channel!'); @@ -42,7 +40,9 @@ client.on('message', m => { .replace(//g, ''); const stream = ytdl(url, { filter: 'audioonly' }, { passes: 3 }); - m.guild.voiceConnection.playStream(stream); + d = m.guild.voiceConnection.playStream(stream); + d.setBitrate(1); + setTimeout(() => d.setBitrate(320), 5000); } } else if (m.content.startsWith('/skip')) { if (connections.has(m.guild.id)) {