mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 18:13:29 +01:00
@@ -9,6 +9,8 @@ try {
|
||||
// no opus!
|
||||
}
|
||||
|
||||
import VolumeTransformer from "./VolumeTransformer";
|
||||
|
||||
export default class AudioEncoder {
|
||||
constructor() {
|
||||
if (opus) {
|
||||
@@ -40,8 +42,7 @@ export default class AudioEncoder {
|
||||
}
|
||||
|
||||
getCommand(force) {
|
||||
|
||||
if (this.choice && force)
|
||||
if(this.choice && force)
|
||||
return choice;
|
||||
|
||||
var choices = ["avconv", "ffmpeg"];
|
||||
@@ -58,75 +59,79 @@ export default class AudioEncoder {
|
||||
}
|
||||
|
||||
encodeStream(stream, options) {
|
||||
var self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
var enc = cpoc.spawn(self.getCommand(), [
|
||||
this.volume = new VolumeTransformer(options.volume || 1);
|
||||
|
||||
var enc = cpoc.spawn(this.getCommand(), [
|
||||
'-loglevel', '0',
|
||||
'-i', '-',
|
||||
'-f', 's16le',
|
||||
'-ar', '48000',
|
||||
'-af', 'volume=' + (options.volume || 1),
|
||||
'-ss', (options.seek || 0),
|
||||
'-ac', 2,
|
||||
'pipe:1'
|
||||
], {stdio: ['pipe', 'pipe', 'ignore']});
|
||||
|
||||
stream.pipe(enc.stdin);
|
||||
enc.stdout.pipe(this.volume);
|
||||
|
||||
enc.stdout.once("readable", function () {
|
||||
this.volume.once("readable", () => {
|
||||
resolve({
|
||||
proc: enc,
|
||||
stream: enc.stdout,
|
||||
stream: this.volume,
|
||||
instream: stream,
|
||||
channels : 2
|
||||
channels: 2
|
||||
});
|
||||
});
|
||||
|
||||
enc.stdout.on("end", function () {
|
||||
this.volume.on("end", () => {
|
||||
reject("end");
|
||||
});
|
||||
|
||||
enc.stdout.on("close", function () {
|
||||
this.volume.on("close", () => {
|
||||
reject("close");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
encodeFile(file, options) {
|
||||
var self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
var enc = cpoc.spawn(self.getCommand(), [
|
||||
this.volume = new VolumeTransformer(options.volume || 1);
|
||||
|
||||
var enc = cpoc.spawn(this.getCommand(), [
|
||||
'-loglevel', '0',
|
||||
'-i', file,
|
||||
'-f', 's16le',
|
||||
'-ar', '48000',
|
||||
'-af', 'volume=' + (options.volume || 1),
|
||||
'-ss', (options.seek || 0),
|
||||
'-ac', 2,
|
||||
'pipe:1'
|
||||
], { stdio: ['pipe', 'pipe', 'ignore'] });
|
||||
], {stdio: ['pipe', 'pipe', 'ignore']});
|
||||
|
||||
enc.stdout.once("readable", function () {
|
||||
enc.stdout.pipe(this.volume);
|
||||
|
||||
this.volume.once("readable", () => {
|
||||
resolve({
|
||||
proc: enc,
|
||||
stream: enc.stdout,
|
||||
channels : 2
|
||||
stream: this.volume,
|
||||
channels: 2
|
||||
});
|
||||
});
|
||||
|
||||
enc.stdout.on("end", function () {
|
||||
this.volume.on("end", () => {
|
||||
reject("end");
|
||||
});
|
||||
|
||||
enc.stdout.on("close", function () {
|
||||
this.volume.on("close", () => {
|
||||
reject("close");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
encodeArbitraryFFmpeg(ffmpegOptions) {
|
||||
var self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.volume = new VolumeTransformer(1);
|
||||
|
||||
// add options discord.js needs
|
||||
var options = ffmpegOptions.concat([
|
||||
'-loglevel', '0',
|
||||
@@ -135,21 +140,23 @@ export default class AudioEncoder {
|
||||
'-ac', 2,
|
||||
'pipe:1'
|
||||
]);
|
||||
var enc = cpoc.spawn(self.getCommand(), options, { stdio: ['pipe', 'pipe', 'ignore'] });
|
||||
var enc = cpoc.spawn(this.getCommand(), options, {stdio: ['pipe', 'pipe', 'ignore']});
|
||||
|
||||
enc.stdout.once("readable", function () {
|
||||
enc.stdout.pipe(this.volume);
|
||||
|
||||
this.volume.once("readable", () => {
|
||||
resolve({
|
||||
proc: enc,
|
||||
stream: enc.stdout,
|
||||
channels : 2
|
||||
stream: this.volume,
|
||||
channels: 2
|
||||
});
|
||||
});
|
||||
|
||||
enc.stdout.on("end", function () {
|
||||
this.volume.on("end", () => {
|
||||
reject("end");
|
||||
});
|
||||
|
||||
enc.stdout.on("close", function () {
|
||||
this.volume.on("close", () => {
|
||||
reject("close");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -83,18 +83,19 @@ export default class VoiceConnection extends EventEmitter {
|
||||
}
|
||||
|
||||
playStream(stream, channels=2) {
|
||||
var self = this,
|
||||
startTime = Date.now(),
|
||||
count = 0,
|
||||
length = 20,
|
||||
retStream = new StreamIntent(),
|
||||
onWarning = false,
|
||||
lastVolume = this.volume !== undefined ? this.volume.get() : 1;
|
||||
|
||||
var self = this;
|
||||
this.volume = stream;
|
||||
this.playing = true;
|
||||
this.playingIntent = retStream;
|
||||
|
||||
var startTime = Date.now();
|
||||
var count = 0;
|
||||
|
||||
var length = 20;
|
||||
|
||||
self.playing = true;
|
||||
var retStream = new StreamIntent();
|
||||
var onWarning = false;
|
||||
self.playingIntent = retStream;
|
||||
this.setVolume(lastVolume);
|
||||
|
||||
function send() {
|
||||
if (!self.playingIntent || !self.playing) {
|
||||
@@ -371,4 +372,28 @@ export default class VoiceConnection extends EventEmitter {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
wrapVolume(stream) {
|
||||
stream.pipe(this.volume);
|
||||
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
setVolume(volume) {
|
||||
this.volume.set(volume);
|
||||
}
|
||||
|
||||
getVolume() {
|
||||
return this.volume.get();
|
||||
}
|
||||
|
||||
mute() {
|
||||
this.lastVolume = this.volume.get();
|
||||
this.setVolume(0);
|
||||
}
|
||||
|
||||
unmute() {
|
||||
this.setVolume(this.lastVolume);
|
||||
this.lastVolume = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
45
src/Voice/VolumeTransformer.js
Normal file
45
src/Voice/VolumeTransformer.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const Transform = require('stream').Transform;
|
||||
|
||||
class Volume extends Transform {
|
||||
get volume() {
|
||||
return this._volume === undefined ? 1 : this._volume;
|
||||
}
|
||||
|
||||
set volume(value) {
|
||||
this._volume = value;
|
||||
}
|
||||
|
||||
get multiplier() {
|
||||
return Math.tan(this.volume);
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
set(volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
_transform(buffer, encoding, callback) {
|
||||
let out = new Buffer(buffer.length);
|
||||
|
||||
for (let i = 0; i < buffer.length; i += 2) {
|
||||
// Read Int16, multiple with multiplier and round down
|
||||
//console.log(this.volume, this.multiplier, buffer.readInt16LE(i));
|
||||
let uint = Math.floor(this.multiplier * buffer.readInt16LE(i));
|
||||
|
||||
// Ensure value stays within 16bit
|
||||
uint = Math.min(32767, uint);
|
||||
uint = Math.max(-32767, uint);
|
||||
|
||||
// Write 2 new bytes into other buffer;
|
||||
out.writeInt16LE(uint, i);
|
||||
}
|
||||
|
||||
this.push(out);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Volume;
|
||||
Reference in New Issue
Block a user