/**
* Handles audio playback on guilds.
*
* An instance is automatically created for each guild by the GuildManager
* To access it from a command callback, use the data.audioPlayerObject.
*/
class GuildAudioPlayer {
/**
* Instantiates a new audio player.
* @param {object} guild - Discordie guild object.
*/
constructor(guild) {
/** Associated guild */
this.guild = guild;
/** Current voice connection */
this.voiceConnection = undefined;
/** Current encoder object */
this.currentEncoder = undefined;
/** Current encoder stream */
this.encoderStream = undefined;
// this.volume = 50;
}
/**
* Plays an audio stream.
* @param {object} audioChannel - Discordie VoiceChannel object
* @param {String} path - Stream path or URL
* @param {object} flags - Flags to append to the FFMpeg command
* @param {string[]} flags.input - Input flags
* @param {string[]} flags.output - Output flags
* @return {Promise<Object>} Discordie encoder object
*/
play(audioChannel, path, flags={}, offset=0) {
if (this.currentEncoder) {
return Promise.reject('Bot is currently playing another file on the server.');
}
return this.join(audioChannel)
.then(v => v.createExternalEncoder({
type: 'ffmpeg',
source: path,
format: 'opus', // opus doesn't allow volume change on the fly :C
frameDuration: 60,
inputArgs: flags.input,
outputArgs: flags.output,
})).then((encoder) => {
this.currentEncoder = encoder;
this.encoderStream = encoder.play();
this.encoderStream.resetTimestamp();
this._offset = offset;
// this.voiceConnection.getEncoder().setVolume(this.volume);
encoder.on('end', () => this.clean());
return encoder;
});
}
/**
* Joins a voice channel.
* @param {object} audioChannel - Discordie voice channel object
* @return {Promise<Object>} Discordie voice connection object
*/
join(audioChannel) {
return audioChannel.join().then((info) => {
this.voiceConnection = info.voiceConnection;
return info.voiceConnection;
});
}
/**
get volume() {
return this._vol;
}
set volume(vol) {
this._vol = vol;
try {
this.voiceConnection.getEncoder().setVolume(vol);
} catch (e) { }
}
*/
/**
* Attempts to stop playback.
* @param {boolean} disconnect - Set to true to also disconnect from the voice channel
*/
stop(disconnect) {
try {
this.currentEncoder.stop();
} catch (e) {}
this.clean(disconnect);
}
/**
* Current playback timestamp.
* @type {number}
*/
get timestamp() {
return this.encoderStream.timestamp + this._offset;
}
/**
* Cleans resources and (optionally) disconnects from the voice channel.
* @param {boolean} disconnect - Set to true to disconnect
*/
clean(disconnect) {
delete this.currentEncoder;
delete this.encoderStream;
if (disconnect) {
try {
this.voiceConnection.disconnect();
delete this.voiceConnection;
} catch (e) { }
}
}
}
module.exports = GuildAudioPlayer;