diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index 89aa9f987..6ca115e1b 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -4,6 +4,7 @@ const util = require("util"); const Base = require("../structures/Base"); const DCAOpusTransformer = require("./streams/DCAOpusTransformer"); const FFmpegOggTransformer = require("./streams/FFmpegOggTransformer"); +const OggOpusPassthroughTransformer = require("./streams/OggOpusPassthroughTransformer"); const FFmpegPCMTransformer = require("./streams/FFmpegPCMTransformer"); const FS = require("fs"); const HTTP = require("http"); @@ -146,7 +147,15 @@ class Piper extends EventEmitter { this._dataPacketMin = 4; } else { if(this.libopus) { - if(typeof source === "string") { + if(options.opusPassthrough) { + this.streams.push(source = source.pipe(new OggOpusPassthroughTransformer({ + command: this.converterCommand, + encoderArgs: options.encoderArgs, + inputArgs: options.inputArgs, + format: options.format, + frameDuration: options.frameDuration + })).once("error", (e) => this.stop(e))); + } else if(typeof source === "string") { this.streams.push(source = new FFmpegOggTransformer({ command: this.converterCommand, input: source, diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 0f21bbb35..f703bc119 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -451,7 +451,7 @@ class VoiceConnection extends EventEmitter { options.frameDuration = options.frameDuration || this.frameDuration; options.frameSize = options.frameSize || options.samplingRate * options.frameDuration / 1000; options.pcmSize = options.pcmSize || options.frameSize * 2 * this.channels; - + options.opusPassthrough = options.opusPassthrough || true; if(!this.piper.encode(source, options)) { this.emit("error", new Error("Unable to encode source")); return; diff --git a/lib/voice/streams/FFmpegOggTransformer.js b/lib/voice/streams/FFmpegOggTransformer.js index 6a50eb897..e42a8130a 100644 --- a/lib/voice/streams/FFmpegOggTransformer.js +++ b/lib/voice/streams/FFmpegOggTransformer.js @@ -10,6 +10,7 @@ module.exports = function(options = {}) { options.frameDuration = 60; } let inputArgs = [ + "-analyzeduration", "0", "-loglevel", "24" ].concat(options.inputArgs || []); if(options.format === "pcm") { @@ -24,7 +25,9 @@ module.exports = function(options = {}) { "-vn" ); const outputArgs = [ - "-c", "copy", + "-c:a", "libopus", + "-vbr", "on", + "-frame_duration", "" + options.frameDuration, "-f", "ogg", "-" ]; diff --git a/lib/voice/streams/OggOpusPassthroughTransformer.js b/lib/voice/streams/OggOpusPassthroughTransformer.js new file mode 100644 index 000000000..6a50eb897 --- /dev/null +++ b/lib/voice/streams/OggOpusPassthroughTransformer.js @@ -0,0 +1,32 @@ +"use strict"; + +const FFmpegDuplex = require("./FFmpegDuplex"); + +module.exports = function(options = {}) { + if(!options.command) { + throw new Error("Invalid converter command"); + } + if(options.frameDuration === undefined) { + options.frameDuration = 60; + } + let inputArgs = [ + "-loglevel", "24" + ].concat(options.inputArgs || []); + if(options.format === "pcm") { + inputArgs = inputArgs.concat( + "-f", "s16le", + "-ar", "48000", + "-ac", "2" + ); + } + inputArgs = inputArgs.concat( + "-i", options.input || "-", + "-vn" + ); + const outputArgs = [ + "-c", "copy", + "-f", "ogg", + "-" + ]; + return FFmpegDuplex.spawn(options.command, inputArgs.concat(options.encoderArgs || [], outputArgs)); +};