Added Opus stream support, added volume interface (#1102)

* Added opus stream support, added volume interface

* Remove setImmediate

* Fix weird syntax error

* Most useless commit ever

You're welcome, @PgBiel

* Fix potential memory leak with OpusScript

Emscripten has the tendency to not free resources even when the Opus engine instance has been garbage collected. Thanks to @abalabahaha for pointing this out.

* Typo

* VoiceReceiver.destroy: destroy opus encoder
This commit is contained in:
Programmix
2017-01-29 11:07:33 -08:00
committed by Amish Shah
parent 6fae17912e
commit 7ed58f5f7f
9 changed files with 262 additions and 190 deletions

View File

@@ -50,6 +50,10 @@ class AudioPlayer extends EventEmitter {
return this.streams.last().transcoder;
}
destroy() {
this.opusEncoder.destroy();
}
destroyStream(stream) {
const data = this.streams.get(stream);
if (!data) return;
@@ -69,6 +73,7 @@ class AudioPlayer extends EventEmitter {
}
playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
OpusEncoders.guaranteeOpusEngine();
const options = { seek, volume, passes };
const transcoder = this.prism.transcode({
type: 'ffmpeg',
@@ -85,28 +90,39 @@ class AudioPlayer extends EventEmitter {
}
playPCMStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
OpusEncoders.guaranteeOpusEngine();
const options = { seek, volume, passes };
this.destroyAllStreams(stream);
const dispatcher = new StreamDispatcher(this, stream, options);
dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value));
const dispatcher = this.createDispatcher(stream, options);
if (!this.streams.has(stream)) this.streams.set(stream, { dispatcher, input: stream });
this.streams.get(stream).dispatcher = dispatcher;
dispatcher.on('end', () => this.destroyStream(stream));
dispatcher.on('error', () => this.destroyStream(stream));
return dispatcher;
}
playOpusStream(stream, { seek = 0, passes = 1 } = {}) {
const options = { seek, passes, opus: true };
this.destroyAllStreams(stream);
const dispatcher = this.createDispatcher(stream, options);
this.streams.set(stream, { dispatcher, input: stream });
return dispatcher;
}
playBroadcast(broadcast, { volume = 1, passes = 1 } = {}) {
const options = { volume, passes };
this.destroyAllStreams();
const dispatcher = new StreamDispatcher(this, broadcast, options);
dispatcher.on('end', () => this.destroyStream(broadcast));
dispatcher.on('error', () => this.destroyStream(broadcast));
dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value));
const dispatcher = this.createDispatcher(broadcast, options);
this.streams.set(broadcast, { dispatcher, input: broadcast });
broadcast.registerDispatcher(dispatcher);
return dispatcher;
}
createDispatcher(stream, options) {
const dispatcher = new StreamDispatcher(this, stream, options);
dispatcher.on('end', () => this.destroyStream(stream));
dispatcher.on('error', () => this.destroyStream(stream));
dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value));
return dispatcher;
}
}
module.exports = AudioPlayer;