la-music-core
Version:
A discord.js bot music package.
776 lines (771 loc) • 36.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const discord_js_1 = require("discord.js");
const ytdl = require("ytdl-core");
var YouTube = require("simple-youtube-api");
class musicClient {
/**
* Options for the music client
* @typedef {object} ClientOptions
* @property {boolean} [earProtections=true] Whether to protect ears from high volume of music.
* @property {boolean} [loop=false] Whether to loop the queue by default.
* @property {number} [songChooseTimeout=10] The default timeout for song choosing, in terms of seconds.
* @property {number} [volume=30] The default client volume to be used.
*/
/**
* @param {string} YouTubeApiKey The YouTube Data Api Key v3 to use.
* @param {ClientOptions} [options] The music client options avalible to configure.
*/
constructor(YouTubeApiKey, options = {
earProtections: true,
loop: false,
songChooseTimeout: 10,
volume: 30
}) {
if (typeof YouTubeApiKey !== "string")
throw new Error("The YouTube Api Key provided is not a string.");
this.google_api_key = YouTubeApiKey;
this.youtube = new YouTube(this.google_api_key);
this.queueList = new Map();
this.settings = {};
if (options.songChooseTimeout)
this.settings.songChooseTimeout = options.songChooseTimeout * 1000;
else
this.settings.songChooseTimeout = 10000;
if (options.volume)
this.settings.volume = options.volume;
else
this.settings.volume = 30;
if (options.earProtections !== true) {
console.log("Caution : The volume limit cap has been removed.\nPlease be sure not to unintentionally input a volume higher than 100, or it may damage your device and/or ears.");
this.settings.earProtections = options.earProtections;
}
else
this.settings.earProtections = true;
if (options.loop)
this.settings.loop = options.loop;
else
this.settings.loop = false;
}
/**
* Play the music requested in a voice channel with the command user.
*
* If there is a queue for playing, the searched video will be queued instead.
* @param msg The message object that triggers the command.
* @param {string} searchQuery Search string for the video/YouTube video URL/YouTube playlist URL
*/
play(msg, searchQuery) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof searchQuery !== "string")
return console.log("The query provided is not a string.");
const youtube = this.youtube;
const url = searchQuery ? searchQuery.replace(/<(.+)>/g, '$1') : '';
const voiceChannel = msg.member.voiceChannel;
if (!voiceChannel)
return msg.channel.send('I\'m sorry but you need to be in a voice channel to play music!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
const permissions = voiceChannel.permissionsFor(msg.client.user);
if (!permissions.has('CONNECT'))
return msg.channel.send('I cannot connect to your voice channel, make sure I have the proper permissions!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (!permissions.has('SPEAK'))
return msg.channel.send('I cannot speak in this voice channel, make sure I have the proper permissions!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
const playlist = yield youtube.getPlaylist(url);
const videos = yield playlist.getVideos();
let video;
for (video of Object.values(videos)) {
const video2 = yield youtube.getVideoByID(video.id);
yield musicFunctions.handleVideo(this.queueList, video2, msg, voiceChannel, this.settings.volume, this.settings.loop, false, true);
}
return msg.channel.send(`✅ Playlist: **${playlist.title}** has been added to the queue!`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
else {
try {
var video = yield youtube.getVideo(url);
}
catch (error) {
try {
var videos = yield youtube.searchVideos(searchQuery, 10);
let index = 0;
msg.channel.send(`
__**Song selection:**__
${videos.map((video2) => { return `**${++index} -** ${video2.title}`; }).join('\n')}
Please provide a value to select one of the search results ranging from 1-10.
`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
try {
var response = yield msg.channel.awaitMessages((msg2) => { return msg2.content > 0 && msg2.content < 11; }, {
errors: ['time'],
maxMatches: 1,
time: this.settings.songChooseTimeout
});
}
catch (err) {
console.error(err);
return msg.channel.send('No or invalid value entered, cancelling video selection.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
const videoIndex = parseInt(response.first().content);
var video = yield youtube.getVideoByID(videos[videoIndex - 1].id);
}
catch (err) {
console.error(err);
return msg.channel.send('🆘 I could not obtain any search results.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
return musicFunctions.handleVideo(this.queueList, video, msg, voiceChannel, this.settings.volume, this.settings.loop);
}
});
}
/**
* Play the music requested in a voice channel with the command user.
*
* If there is a queue for playing, the searched video will be queued on top of others instead.
*
* The bot will return the command if a playlist URL is used.
* @param msg The message object that triggers the command.
* @param {string} searchQuery Search string for the video/YouTube video URL
*/
playTop(msg, searchQuery) {
return __awaiter(this, void 0, void 0, function* () {
var youtube = this.youtube;
const url = searchQuery ? searchQuery.replace(/<(.+)>/g, '$1') : '';
const voiceChannel = msg.member.voiceChannel;
if (!voiceChannel)
return msg.channel.send('I\'m sorry but you need to be in a voice channel to play music!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
const permissions = voiceChannel.permissionsFor(msg.client.user);
if (!permissions.has('CONNECT'))
return msg.channel.send('I cannot connect to your voice channel, make sure I have the proper permissions!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (!permissions.has('SPEAK'))
return msg.channel.send('I cannot speak in this voice channel, make sure I have the proper permissions!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/))
return msg.channel.send("You cannot use the playTop command with a playlist.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
else {
try {
var video = yield youtube.getVideo(url);
}
catch (error) {
try {
var videos = yield youtube.searchVideos(searchQuery, 10);
let index = 0;
msg.channel.send(`
__**Song selection:**__
${videos.map((video2) => { return `**${++index} -** ${video2.title}`; }).join('\n')}
Please provide a value to select one of the search results ranging from 1-10.
`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
try {
var response = yield msg.channel.awaitMessages((msg2) => { return msg2.content > 0 && msg2.content < 11; }, {
errors: ['time'],
maxMatches: 1,
time: this.settings.songChooseTimeout
});
}
catch (err) {
console.error(err);
return msg.channel.send('No or invalid value entered, cancelling video selection.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
const videoIndex = parseInt(response.first().content);
var video = yield youtube.getVideoByID(videos[videoIndex - 1].id);
}
catch (err) {
console.error(err);
return msg.channel.send('🆘 I could not obtain any search results.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
return musicFunctions.handleVideo(this.queueList, video, msg, voiceChannel, this.settings.volume, this.settings.loop, true);
}
});
}
/**
* Stops music and remove the music queue.
*
* This will also cause the bot to leave the voice channel.
* @param msg The message object that triggers the command.
*/
stop(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!msg.member.voiceChannel)
return msg.channel.send('You are not in a voice channel!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (!serverQueue)
return msg.channel.send('There is nothing playing that I could stop for you.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
serverQueue.songs = [];
serverQueue.connection.dispatcher.end("Bot got stopped.");
}
/**
* Skips the music which the bot is now playing.
*
* If this is the last song in the queue,
* this will also cause the bot to leave the voice channel.
* @param msg The message object that triggers the command.
*/
skip(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!msg.member.voiceChannel)
return msg.channel.send('You are not in a voice channel!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (!serverQueue)
return msg.channel.send('There is nothing playing that I could skip for you.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
serverQueue.connection.dispatcher.end("Song got skipped.");
}
/**
* Displays the music queue.
* @param msg The message object that triggers the command.
*/
showQueue(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
var index = 0;
var songArray = serverQueue.songs.map((song) => { return `**${++index}-** [${song.title}](${song.url})`; });
musicFunctions.addMusicQueueField(msg, songArray, queue).then((results) => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < results.length; i++) {
yield new Promise((r) => { return setTimeout(r, 500); });
const element = results[i];
msg.channel.send(element).then((m) => {
return m.delete(30000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}));
}
/**
* Displays the music now playing.
* @param msg The message object that triggers the command.
*/
nowPlaying(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
var embed = new discord_js_1.RichEmbed()
.setColor(Math.floor(Math.random() * 16777214) + 1)
.setTimestamp()
.setThumbnail(serverQueue.songs[0].icon)
.addField(`Now playing in ${msg.guild.name}:`, `[**${serverQueue.songs[0].title}**](${serverQueue.songs[0].url})`)
.setFooter(`Requested by ${msg.author.username}`, msg.author.avatarURL);
return msg.channel.send(embed).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
/**
* Removes a certain song in the music queue.
*
* You cannot remove the first song in the queue with this method.
* @param msg The message object that triggers the command.
* @param {number} queueIndex The index for the song in the queue.
* @example
* // Song queue :
* // 1. National Anthem of USSR,
* // 2. Do you hear the people sing?
*
* // I wanted to remove the song "Do you hear the people sing?".
* musicClient.remove(2)
* // New song queue :
* // 1. National Anthem of USSR
*/
remove(msg, queueIndex) {
if (typeof queueIndex !== "number")
return console.log("The query provided is not a number.");
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
var deleteIndex = queueIndex - 1;
if (deleteIndex === 0)
return msg.channel.send(`You cannot remove the song that is now playing. To remove it, use skip command instead.`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
var removed = serverQueue.songs.splice(deleteIndex, 1);
msg.channel.send(`**${removed[0].title}** has been removed from the queue.`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
var index = 0;
var songArray = serverQueue.songs.map((song) => { return `**${++index}-** [${song.title}](${song.url})`; });
musicFunctions.addMusicQueueField(msg, songArray, queue).then((results) => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < results.length; i++) {
yield new Promise((r) => { return setTimeout(r, 500); });
const element = results[i];
msg.channel.send(element).then((m) => {
return m.delete(30000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}));
}
/**
* Repeats the first song in queue.
*
* Looping the song queue will be disabled upon usage of this command.
* @param msg The message object that triggers the command.
*/
repeat(msg) {
const serverQueue = this.queueList.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (serverQueue.repeat === false) {
serverQueue.repeat = true;
msg.channel.send("The first song in the queue is now being repeated.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (serverQueue.loop === true) {
serverQueue.loop = false;
msg.channel.send("Looping has been disabled to avoid confusion.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
else {
serverQueue.repeat = false;
msg.channel.send("The first song in the queue is no longer being repeated.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
/**
* Loops the whole song queue.
*
* Repeat a single song will be disabled upon usage of this command.
* @param msg The message object that triggers the command.
*/
loop(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (serverQueue.loop === false) {
serverQueue.loop = true;
msg.channel.send("The song queue is now being looped.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (serverQueue.repeat === true) {
serverQueue.repeat = false;
msg.channel.send("Repeating the first song has been disabled to avoid confusion.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
else {
serverQueue.loop = false;
msg.channel.send("The song queue is no longer being looped.").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
/**
* Shuffles the whole music queue.
* @param msg The message object that triggers the command.
*/
shuffle(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
musicFunctions.shuffleArray(serverQueue.songs);
var index = 0;
var songArray = serverQueue.songs.map((song) => { return `**${++index}-** [${song.title}](${song.url})`; });
musicFunctions.addMusicQueueField(msg, songArray, queue).then((results) => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < results.length; i++) {
yield new Promise((r) => { return setTimeout(r, 500); });
const element = results[i];
msg.channel.send(element).then((m) => {
return m.delete(30000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}));
msg.channel.send("Song queue has been shuffled.").then((m) => {
return m.delete(30000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
/**
* Changes the volume of the music.
*
* The default volume is 20/100, which is safe to turn the music bot volume in discord to 100%.
* Tuning up the volume higher than 50 is not recommended.
*
* Any negative numbers in the volume will only cause the bot to display current volume.
*
* This will NOT cause any performance issues as stated from some music bot developers.
* @param msg The message object that triggers the command.
* @param {number} volume A number to change the volume based on 100.
*/
volume(msg, volume = -1) {
if (typeof volume !== "number")
return msg.channel.send("The volume provided is not a number").then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (!msg.member.voiceChannel)
return msg.channel.send('You are not in a voice channel!').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (!serverQueue)
return msg.channel.send('There is nothing playing.').then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (volume > 100 && this.settings.earProtections === true)
return msg.channel.send(`I think you still need your ears for listening to more beautiful music.\nThe volume limit was capped on 100. The volume has not been modified. The current volume is ${serverQueue.volume}.`);
if (volume > 100)
msg.channel.send("WARNING : THE MUSIC WILL PLAY IN AN EXTREMELY LOUD VOLUME.").then((m) => {
return m.delete(15000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
if (volume < 0)
return msg.channel.send(`The current volume is ${serverQueue.volume}.`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
serverQueue.volume = volume;
serverQueue.connection.dispatcher.setVolumeLogarithmic(volume / 100);
return msg.channel.send(`I set the volume to: **${volume}**`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
/**
* Pause the music playback.
* @param msg The message object that triggers the command.
*/
pause(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (serverQueue.paused === false) {
serverQueue.paused = true;
return msg.channel.send("The song playback has been stopped.");
}
else {
return msg.channel.send("The song playback is already stopped.");
}
}
/**
* Resumes the music playback.
* @param msg The message object that triggers the command.
*/
resume(msg) {
const queue = this.queueList;
const serverQueue = queue.get(msg.guild.id);
if (serverQueue.paused === true) {
serverQueue.paused = false;
return msg.channel.send("The song playback has been resumed.");
}
else {
return msg.channel.send("The song playback is not stopped.");
}
}
}
exports.musicClient = musicClient;
const musicFunctions = {
addMusicQueueField(msg, content, queue) {
return __awaiter(this, void 0, void 0, function* () {
const serverQueue = queue.get(msg.guild.id);
var toSendEmbed = [];
var color = Math.floor(Math.random() * 16777214) + 1;
let i = 0;
while (i < content.length) {
var embed = new discord_js_1.RichEmbed();
let index = 0;
while (i < content.length && index < 25) {
var list = [];
const element0 = content[i];
index++;
i++;
const element1 = content[i];
index++;
i++;
const element2 = content[i];
index++;
i++;
const element3 = content[i];
index++;
i++;
const element4 = content[i];
index++;
i++;
list.push(element0);
element1 ? list.push(element1) : console.log("Empty element");
element1 ? list.push(element2) : console.log("Empty element");
element1 ? list.push(element3) : console.log("Empty element");
element1 ? list.push(element4) : console.log("Empty element");
if (i < 25) {
embed.setTitle(`Song queue for ${msg.guild.name}`);
embed.setDescription(`There are ${serverQueue.songs.length} songs in total.`);
embed.setAuthor(msg.author.username, msg.author.avatarURL);
}
embed.setTimestamp();
embed.setFooter(`Now playing : ${serverQueue.songs[0].title}`);
embed.addField("** **", list.join("\n"));
embed.setColor(color);
}
toSendEmbed.push(embed);
}
return toSendEmbed;
});
},
handleVideo(queueList, video, msg, voiceChannel, musicVolume = 20, loopQueue = false, top = false, playlist = false) {
return __awaiter(this, void 0, void 0, function* () {
const serverQueue = queueList.get(msg.guild.id);
const song = {
guild: msg.guild.name,
icon: video.thumbnails.default.url,
id: video.id,
length: {
hrs: video.duration.hours,
mins: video.duration.minutes,
secs: video.duration.seconds
},
title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`
};
if (!serverQueue) {
var queueConstruct = {
connection: null,
loop: loopQueue,
paused: true,
repeat: false,
songs: [],
textChannel: msg.channel,
voiceChannel,
volume: musicVolume
};
queueList.set(msg.guild.id, queueConstruct);
queueConstruct.songs.push(song);
console.log("Song added to queue.");
try {
var connection = yield voiceChannel.join();
queueConstruct.connection = connection;
musicFunctions.playMusic(msg.guild, queueConstruct.songs[0], queueList);
}
catch (error) {
console.error(`I could not join the voice channel: ${error}`);
queueList.delete(msg.guild.id);
return msg.channel.send(`I could not join the voice channel: ${error}`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
}
else if (top) {
serverQueue.songs.splice(1, 0, song);
if (playlist)
return undefined;
else
return msg.channel.send(`✅ **${song.title}** has been added to the queue!`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
else {
serverQueue.songs.push(song);
if (playlist)
return undefined;
else
return msg.channel.send(`✅ **${song.title}** has been added to the queue!`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
}
return undefined;
});
},
playMusic(guild, song, queueList) {
const serverQueue = queueList.get(guild.id);
try {
if (!song) {
serverQueue.voiceChannel.leave();
queueList.delete(guild.id);
return;
}
}
catch (error) {
console.log(error);
}
const dispatcher = serverQueue.connection.playStream(ytdl(song.url, {
filter: "audioonly",
highWaterMark: 1024 * 512,
quality: "highestaudio"
})).on('end', (reason) => {
if (serverQueue.loop === true) {
console.log("Song ended, but looped");
var toPush = serverQueue.songs[0];
serverQueue.songs.push(toPush);
serverQueue.songs.shift();
musicFunctions.playMusic(guild, serverQueue.songs[0], queueList);
}
else if (serverQueue.repeat === true) {
console.log("Song ended, but repeated");
musicFunctions.playMusic(guild, serverQueue.songs[0], queueList);
}
else {
if (reason === 'Stream is not generating quickly enough.')
console.log('Song ended.');
else
console.log(`${reason}`);
serverQueue.songs.shift();
musicFunctions.playMusic(guild, serverQueue.songs[0], queueList);
}
}).on('error', (error) => { return console.error(error); });
dispatcher.setVolumeLogarithmic(serverQueue.volume / 100);
serverQueue.textChannel.send(`🎶 Start playing: **${song.title}**`).then((m) => {
return m.delete(10000).catch((reason) => {
console.log(`Attempting to delete a deleted message (Which is impossible)`);
});
});
},
shuffleArray(array) {
let temp = array[0];
array.splice(0, 1);
var i;
var j;
var x;
for (i = array.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = array[i];
array[i] = array[j];
array[j] = x;
}
array.unshift(temp);
temp = [];
return array;
}
};
module.exports = musicClient;