Start rewrite with new prism

This commit is contained in:
Amish Shah
2017-10-25 23:14:41 +01:00
parent 0589b7d7f1
commit 65673197d4
6 changed files with 91 additions and 398 deletions

View File

@@ -1,10 +1,10 @@
const EventEmitter = require('events').EventEmitter;
const Prism = require('prism-media');
const prism = require('prism-media');
const StreamDispatcher = require('../dispatcher/StreamDispatcher');
const Collection = require('../../../util/Collection');
const OpusEncoders = require('../opus/OpusEngineList');
const ffmpegArguments = [
const FFMPEG_ARGUMENTS = [
'-analyzeduration', '0',
'-loglevel', '0',
'-f', 's16le',
@@ -25,13 +25,10 @@ class AudioPlayer extends EventEmitter {
* @type {VoiceConnection}
*/
this.voiceConnection = voiceConnection;
/**
* The prism transcoder that the player uses
* @type {Prism}
*/
this.prism = new Prism();
this.streams = new Collection();
this.currentStream = {};
this.streams = {};
this.dispatcher = null;
this.streamingData = {
channels: 2,
count: 0,
@@ -39,45 +36,19 @@ class AudioPlayer extends EventEmitter {
timestamp: 0,
pausedTime: 0,
};
this.voiceConnection.once('closing', () => this.destroyCurrentStream());
}
/**
* The current transcoder
* @type {?Object}
* @readonly
*/
get transcoder() {
return this.currentStream.transcoder;
}
/**
* The current dispatcher
* @type {?StreamDispatcher}
* @readonly
*/
get dispatcher() {
return this.currentStream.dispatcher;
}
destroy() {
if (this.opusEncoder) this.opusEncoder.destroy();
this.opusEncoder = null;
this.destroyDispatcher();
}
destroyCurrentStream() {
const transcoder = this.transcoder;
const dispatcher = this.dispatcher;
if (transcoder) transcoder.kill();
if (dispatcher) {
const end = dispatcher.listeners('end')[0];
const error = dispatcher.listeners('error')[0];
if (end) dispatcher.removeListener('end', end);
if (error) dispatcher.removeListener('error', error);
dispatcher.destroy('end');
destroyDispatcher() {
if (this.dispatcher) {
this.dispatcher.destroy();
this.dispatcher = null;
}
this.currentStream = {};
this.streamingData.pausedTime = 0;
}
/**
@@ -93,76 +64,35 @@ class AudioPlayer extends EventEmitter {
}
playUnknownStream(stream, options = {}) {
this.destroy();
this.opusEncoder = OpusEncoders.fetch(options);
const transcoder = this.prism.transcode({
type: 'ffmpeg',
media: stream,
ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek || 0)]),
});
this.destroyCurrentStream();
this.currentStream = {
transcoder: transcoder,
output: transcoder.output,
input: stream,
};
transcoder.on('error', e => {
this.destroyCurrentStream();
if (this.listenerCount('error') > 0) this.emit('error', e);
this.emit('warn', `prism transcoder error - ${e}`);
});
return this.playPCMStream(transcoder.output, options, true);
this.destroyDispatcher();
const ffmpeg = this.streams.ffmpeg = new prism.FFmpeg({ args: FFMPEG_ARGUMENTS });
stream.pipe(ffmpeg);
return this.playPCMStream(ffmpeg, options);
}
playPCMStream(stream, options = {}, fromUnknown = false) {
this.destroy();
this.opusEncoder = OpusEncoders.fetch(options);
this.setBitrate(options.bitrate);
const dispatcher = this.createDispatcher(stream, options);
if (fromUnknown) {
this.currentStream.dispatcher = dispatcher;
} else {
this.destroyCurrentStream();
this.currentStream = {
dispatcher,
input: stream,
output: stream,
};
}
return dispatcher;
playPCMStream(stream, options = {}) {
this.destroyDispatcher();
const opus = this.streams.opus = new prism.opus.Encoder({ channels: 2, rate: 48000, frameSize: 960 });
stream.pipe(opus);
return this.playOpusStream(opus, options);
}
playOpusStream(stream, options = {}) {
options.opus = true;
this.destroyCurrentStream();
const dispatcher = this.createDispatcher(stream, options);
this.currentStream = {
dispatcher,
input: stream,
output: stream,
};
this.destroyDispatcher();
const dispatcher = this.dispatcher = this.createDispatcher(options);
stream.pipe(dispatcher);
return dispatcher;
}
playBroadcast(broadcast, options) {
this.destroyCurrentStream();
const dispatcher = this.createDispatcher(broadcast, options);
this.currentStream = {
dispatcher,
broadcast,
input: broadcast,
output: broadcast,
};
broadcast.registerDispatcher(dispatcher);
return dispatcher;
}
createDispatcher(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
createDispatcher({ seek = 0, volume = 1, passes = 1 } = {}) {
this.destroyDispatcher();
const options = { seek, volume, passes };
const dispatcher = new StreamDispatcher(this, stream, options);
dispatcher.on('end', () => this.destroyCurrentStream());
dispatcher.on('error', () => this.destroyCurrentStream());
const dispatcher = new StreamDispatcher(this, options);
this.streamingData.count = 0;
dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value));
return dispatcher;
}