Files
shred.ing-discord/ShredPlaybackChannel.js

140 lines
3.5 KiB
JavaScript

// encapsulate a channel where we do playback
class ShredPlaybackChannel {
constructor(guildID, vcID, vtID=null, autoJoin=false, active=true) {
this._guildID = guildID;
this._vcID = vcID;
this._vtID = vtID;
this._uri = ShredPlaybackChannel.defaultURI;
this._auto = autoJoin;
this._active = active;
}
get guildID() { return this._guildID; }
get vcID() { return this._vcID; }
get vtID() { return this._vtID; }
get uri() { return this._uri; }
get autoJoin() { return this.autoJoin === true; }
get active() { return this._active === true; }
stopPlayback(part=false) {
if(this.voiceConnection) {
// stop if we are already playing (allows start to reset)
console.log("Stopping player..");
this.voiceConnection.stopPlaying();
if( part !== false ) {
this.voiceConnection.leave();
}
} else {
console.log("Unable to stop playback: no voice connection.");
}
}
restartPlaybackDelayed(
// miliseconds of delay before resuming playback
delay=ShredPlaybackChannel.defaultRestartPlaybackDelayMS
)
{
setTimeout( function() { this.onVoiceConnection() }, delay );
}
startPlayback() {
if(this.voiceConnection) {
// stop if we are already playing (allows start to reset)
if(this.voiceConnection.playing) {
this.stopPlayback();
}
// invokes FFMPEG
this.voiceConnection.play(
ShredPlaybackChannel.defaultURI,
ShredPlaybackChannel.defaultStreamOptions
);
// if that didn't throw the stream is now active
this._active = true;
// auto-reconnect unless stream if stream was active
this.voiceConnection.once("end", function () {
if(this.active) {
this._active = false;
this.restartPlaybackDelayed();
}
});
} else {
console.log("Unable to start playback: no voice connection.");
}
}
onVoiceConnection(voiceConnection=null) {
if(voiceConnection) {
// save new voiceConnection when provided
this.voiceConnection = voiceConnection;
}
if(this.active) {
this.startPlayback();
}
}
endVoiceConnection() {
this._active = false;
if(this.voiceConnection) {
this.stopPlaying();
this.voiceConnection = null;
}
else {
console.log(`Cannot end voice connection, no connection to channel ID ${this.vcID}`);
}
}
startVoiceConnection(bot) {
const me = this;
bot.joinVoiceChannel( me.vcID ).catch((err) => {
console.log( 'ERROR: failed to join channel '
+ `${this.vcID} on guild ${this.guildID}: `
+ err);
console.debug( me );
}).then(function (vc) {
me.onVoiceConnection(vc);
if( me.vtID ) {
bot.createMessage( me.vtID, `Now playing **${me.uri}**`)
}
});
}
static JoinAndPlay(
bot,
guildID,
voiceChannelID,
voiceTextChannelID=null,
autoJoin=false,
active=true
)
{
try {
const ch = new ShredPlaybackChannel(
guildID,
voiceChannelID,
voiceTextChannelID,
autoJoin,
active
);
ch.startVoiceConnection(bot);
return ch;
} catch (err) {
console.log(
'ERROR: failed to join channel '
+`${voiceChannelID} on guild ${guildID}: `
+ err
);
}
}
static get defaultURI() { return "https://shred.ing/live.ogg"; }
static get defaultStreamOptions() { return { voiceDataTimeout: -1 }; }
static get defaultRestartPlaybackDelayMS() { return 1500; }
}
module.exports = ShredPlaybackChannel;