discord.js/src/client/voice/pcm/FfmpegConverterEngine.js
2016-10-25 14:46:50 +01:00

80 lines
2.2 KiB
JavaScript

const ConverterEngine = require('./ConverterEngine');
const ChildProcess = require('child_process');
const EventEmitter = require('events').EventEmitter
class PCMConversionProcess extends EventEmitter {
constructor(process) {
super();
this.process = process;
this.input = null;
this.process.on('error', e => this.emit('error', e));
}
setInput(stream) {
this.input = stream;
stream.pipe(this.process.stdin, { end: false });
this.input.on('error', e => this.emit('error', e));
this.process.stdin.on('error', e => this.emit('error', e));
}
destroy() {
this.emit('debug', 'destroying a ffmpeg process:');
if (this.input && this.input.unpipe && this.process.stdin) {
this.input.unpipe(this.process.stdin);
this.emit('unpiped the user input stream from the process input stream');
}
if (this.process.stdin) {
this.process.stdin.end();
this.emit('ended the process stdin');
}
if (this.process.stdin.destroy) {
this.process.stdin.destroy();
this.emit('destroyed the process stdin');
}
if (this.process.kill) {
this.process.kill();
this.emit('killed the process');
}
}
}
class FfmpegConverterEngine extends ConverterEngine {
constructor(player) {
super(player);
this.command = chooseCommand();
}
handleError(encoder, err) {
if (encoder.destroy) encoder.destroy();
this.emit('error', err);
}
createConvertStream(seek = 0) {
super.createConvertStream();
const encoder = ChildProcess.spawn(this.command, [
'-analyzeduration', '0',
'-loglevel', '0',
'-i', '-',
'-f', 's16le',
'-ar', '48000',
'-ac', '2',
'-ss', String(seek),
'pipe:1',
], { stdio: ['pipe', 'pipe', 'ignore'] });
return new PCMConversionProcess(encoder);
}
}
function chooseCommand() {
for (const cmd of ['ffmpeg', 'avconv', './ffmpeg', './avconv']) {
if (!ChildProcess.spawnSync(cmd, ['-h']).error) return cmd;
}
throw new Error(
'FFMPEG was not found on your system, so audio cannot be played. ' +
'Please make sure FFMPEG is installed and in your PATH.'
);
}
module.exports = FfmpegConverterEngine;