|
|
|
@ -32,9 +32,9 @@ exports.DJ = class {
|
|
|
|
|
connect(voiceChannel) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
this.voiceChannel = voiceChannel || this.voiceChannel;
|
|
|
|
|
if (this.connected)
|
|
|
|
|
if (this.connected)
|
|
|
|
|
this.stop();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.verbose(`Connecting to voiceChannel ${this.voiceChannel.name}`);
|
|
|
|
|
this.voiceChannel.join().then(connection => {
|
|
|
|
|
logger.info(`Connected to Voicechannel ${this.voiceChannel.name}`);
|
|
|
|
@ -51,9 +51,9 @@ exports.DJ = class {
|
|
|
|
|
*/
|
|
|
|
|
set listenOnRepeat(value) {
|
|
|
|
|
this.repeat = value;
|
|
|
|
|
if (this.current)
|
|
|
|
|
if (this.current)
|
|
|
|
|
this.queue.push(this.current);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -100,79 +100,69 @@ exports.DJ = class {
|
|
|
|
|
this.stop();
|
|
|
|
|
}, config.music.timeout || 300000);
|
|
|
|
|
} else if (this.connected) {
|
|
|
|
|
setTimeout(() => this.checkListeners(), 10000);
|
|
|
|
|
setTimeout(() => this.checkListeners(), 10000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Plays the url of the current song if there is no song playing or puts it in the queue.
|
|
|
|
|
* If the url is a playlist (regex match), the videos of the playlist are fetched and put
|
|
|
|
|
* If the url is a playlist, the videos of the playlist are fetched and put
|
|
|
|
|
* in the queue. For each song the title is saved in the queue too.
|
|
|
|
|
* @param url
|
|
|
|
|
* @param playnext
|
|
|
|
|
*/
|
|
|
|
|
playYouTube(url, playnext) {
|
|
|
|
|
async playYouTube(url, playnext) {
|
|
|
|
|
let plist = utils.YouTube.getPlaylistIdFromUrl(url);
|
|
|
|
|
if (plist) {
|
|
|
|
|
logger.debug(`Adding playlist ${plist} to queue`);
|
|
|
|
|
ypi(ytapiKey, plist).then(items => {
|
|
|
|
|
let firstSong = utils.YouTube.getVideoUrlFromId(items.shift().resourceId.videoId);
|
|
|
|
|
|
|
|
|
|
this.getVideoName(firstSong).then((title) => { // getting the first song to start playing music
|
|
|
|
|
if (this.repeat) // listen on repeat
|
|
|
|
|
this.queue.push({'url': firstSong, 'title': title}); // put the current song back at the end of the queue
|
|
|
|
|
this.playYouTube(firstSong); // call with single url that gets queued if a song is already playing
|
|
|
|
|
}).catch((err) => logger.verbose(err.message));
|
|
|
|
|
for (let item of items) {
|
|
|
|
|
let vurl = utils.YouTube.getVideoUrlFromId(item.resourceId.videoId);
|
|
|
|
|
this.getVideoName(vurl).then((title) => {
|
|
|
|
|
this.queue.push({'url': vurl, 'title': title});
|
|
|
|
|
}).catch((err) => logger.verbose(err.message));
|
|
|
|
|
let playlistItems = await ypi(ytapiKey, plist);
|
|
|
|
|
let firstSong = utils.YouTube.getVideoUrlFromId(playlistItems.shift().resourceId.videoId);
|
|
|
|
|
let firstSongTitle = await this.getVideoName(firstSong);
|
|
|
|
|
|
|
|
|
|
if (this.repeat)
|
|
|
|
|
this.queue.push({'url': firstSong, 'title': firstSongTitle});
|
|
|
|
|
this.playYouTube(firstSong).catch((err) => logger.warn(err.message));
|
|
|
|
|
|
|
|
|
|
for (let item of playlistItems) {
|
|
|
|
|
let vurl = utils.YouTube.getVideoUrlFromId(item.resourceId.videoId);
|
|
|
|
|
this.queue.push({'url': vurl, 'title': await this.getVideoName(vurl)}); //eslint-disable-line no-await-in-loop
|
|
|
|
|
}
|
|
|
|
|
logger.debug(`Added ${playlistItems.length} songs to the queue`);
|
|
|
|
|
} else if (!this.playing || !this.disp) {
|
|
|
|
|
logger.debug(`Playing ${url}`);
|
|
|
|
|
|
|
|
|
|
this.current = ({'url': url, 'title': await this.getVideoName(url)});
|
|
|
|
|
|
|
|
|
|
this.disp = this.conn.playStream(ytdl(url,
|
|
|
|
|
{filter: 'audioonly', quality: this.quality, liveBuffer: 40000}),
|
|
|
|
|
{volume: this.volume});
|
|
|
|
|
|
|
|
|
|
this.disp.on('end', (reason) => { // end event triggers the next song to play when the reason is not stop
|
|
|
|
|
if (reason !== 'stop') {
|
|
|
|
|
this.playing = false;
|
|
|
|
|
this.current = null;
|
|
|
|
|
if (this.queue.length > 0) {
|
|
|
|
|
this.current = this.queue.shift();
|
|
|
|
|
if (this.repeat) // listen on repeat
|
|
|
|
|
this.queue.push(this.current);
|
|
|
|
|
this.playYouTube(this.current.url).catch((err) => logger.warn(err.message));
|
|
|
|
|
} else {
|
|
|
|
|
this.stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
logger.debug(`Added ${items.length} songs to the queue`);
|
|
|
|
|
});
|
|
|
|
|
this.playing = true;
|
|
|
|
|
} else {
|
|
|
|
|
if (!this.playing || !this.disp) {
|
|
|
|
|
logger.debug(`Playing ${url}`);
|
|
|
|
|
|
|
|
|
|
this.getVideoName(url).then((title) => {
|
|
|
|
|
this.current = ({'url': url, 'title': title});
|
|
|
|
|
|
|
|
|
|
this.disp = this.conn.playStream(ytdl(url, {
|
|
|
|
|
filter: 'audioonly', quality: this.quality, liveBuffer: 40000
|
|
|
|
|
}), {volume: this.volume});
|
|
|
|
|
|
|
|
|
|
this.disp.on('end', (reason) => { // end event triggers the next song to play when the reason is not stop
|
|
|
|
|
if (reason !== 'stop') {
|
|
|
|
|
this.playing = false;
|
|
|
|
|
this.current = null;
|
|
|
|
|
if (this.queue.length > 0) {
|
|
|
|
|
this.current = this.queue.shift();
|
|
|
|
|
if (this.repeat) // listen on repeat
|
|
|
|
|
this.queue.push(this.current);
|
|
|
|
|
this.playYouTube(this.current.url);
|
|
|
|
|
} else {
|
|
|
|
|
this.stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.playing = true;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
logger.debug(`Added ${url} to the queue`);
|
|
|
|
|
if (playnext)
|
|
|
|
|
this.getVideoName(url).then((title) => {
|
|
|
|
|
this.queue.unshift({'url': url, 'title': title});
|
|
|
|
|
}).catch((err) => logger.verbose(err.message));
|
|
|
|
|
else
|
|
|
|
|
this.getVideoName(url).then((title) => {
|
|
|
|
|
this.queue.push({'url': url, 'title': title});
|
|
|
|
|
}).catch((err) => logger.verbose(err.message));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
logger.debug(`Added ${url} to the queue`);
|
|
|
|
|
if (playnext)
|
|
|
|
|
this.queue.unshift({'url': url, 'title': await this.getVideoName(url)});
|
|
|
|
|
else
|
|
|
|
|
this.queue.push({'url': url, 'title': await this.getVideoName(url)});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the name of the YouTube Video at url
|
|
|
|
|
* @param url
|
|
|
|
@ -210,11 +200,11 @@ setTimeout(() => this.checkListeners(), 10000);
|
|
|
|
|
*/
|
|
|
|
|
pause() {
|
|
|
|
|
logger.verbose("Pausing music...");
|
|
|
|
|
if (this.disp !== null)
|
|
|
|
|
if (this.disp !== null)
|
|
|
|
|
this.disp.pause();
|
|
|
|
|
else
|
|
|
|
|
else
|
|
|
|
|
logger.warn("No dispatcher found");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -222,11 +212,11 @@ setTimeout(() => this.checkListeners(), 10000);
|
|
|
|
|
*/
|
|
|
|
|
resume() {
|
|
|
|
|
logger.verbose("Resuming music...");
|
|
|
|
|
if (this.disp !== null)
|
|
|
|
|
if (this.disp !== null)
|
|
|
|
|
this.disp.resume();
|
|
|
|
|
else
|
|
|
|
|
else
|
|
|
|
|
logger.warn("No dispatcher found");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -341,13 +331,13 @@ exports.playFile = function (guildId, filename) {
|
|
|
|
|
*/
|
|
|
|
|
exports.play = function (voiceChannel, url) {
|
|
|
|
|
let guildId = voiceChannel.guild.id;
|
|
|
|
|
if (!djs[guildId])
|
|
|
|
|
if (!djs[guildId])
|
|
|
|
|
this.connect(voiceChannel).then(() => {
|
|
|
|
|
djs[guildId].playYouTube(url);
|
|
|
|
|
});
|
|
|
|
|
else
|
|
|
|
|
else
|
|
|
|
|
djs[guildId].playYouTube(url);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -358,13 +348,13 @@ exports.play = function (voiceChannel, url) {
|
|
|
|
|
*/
|
|
|
|
|
exports.playnext = function (voiceChannel, url) {
|
|
|
|
|
let guildId = voiceChannel.guild.id;
|
|
|
|
|
if (!djs[guildId])
|
|
|
|
|
if (!djs[guildId])
|
|
|
|
|
this.connect(voiceChannel).then(() => {
|
|
|
|
|
djs[guildId].playYouTube(url, true);
|
|
|
|
|
});
|
|
|
|
|
else
|
|
|
|
|
else
|
|
|
|
|
djs[guildId].playYouTube(url, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|