├── MusicBot ├── settiings │ ├── config.json │ └── credentials.json ├── handlers │ ├── ready.js │ └── message.js ├── package.json ├── commands │ ├── pause.js │ ├── resume.js │ ├── stop.js │ ├── queue.js │ ├── reload.js │ ├── volume.js │ ├── help.js │ ├── skip.js │ ├── play.js │ └── search.js ├── index.js ├── global │ ├── utils.js │ └── functions.js └── package-lock.json └── README.md /MusicBot/settiings/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "prefix": "!", 3 | "commandNotFound": false 4 | } -------------------------------------------------------------------------------- /MusicBot/settiings/credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "", 3 | "YouTubeAPIKey": "" 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Music-Bot-Development 2 | Source code of Music Bot from the livestream can be found here! 3 | -------------------------------------------------------------------------------- /MusicBot/handlers/ready.js: -------------------------------------------------------------------------------- 1 | const {token} = require('../settiings/credentials.json'); 2 | 3 | module.exports = { 4 | 5 | ready : (bot) => { 6 | bot.login(token) 7 | bot.on('ready', () => { 8 | bot.user.setActivity('Music', {type: 'LISTENING'}); 9 | bot.user.setStatus('dnd'); 10 | console.log('I am ready to play MUSICS!!'); 11 | }); 12 | } 13 | 14 | }; 15 | -------------------------------------------------------------------------------- /MusicBot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "musicbot", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "async-limiter": "^1.0.0", 13 | "discord.js": "^11.4.2", 14 | "long": "^4.0.0", 15 | "prism-media": "0.0.3", 16 | "safe-buffer": "^5.1.2", 17 | "snekfetch": "^4.0.4", 18 | "tweetnacl": "^1.0.0", 19 | "ws": "^6.1.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MusicBot/commands/pause.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | 3 | module.exports.run = async (bot, message, args) => { 4 | 5 | let queue = bot.queue.get(message.guild.id); 6 | 7 | if (queue && queue.playing) { 8 | queue.playing = false; 9 | queue.connection.dispatcher.pause(); 10 | return message.channel.send(`🎵 Music has now been paused`); 11 | } 12 | 13 | return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 14 | 15 | }; 16 | 17 | module.exports.help = { 18 | name: 'pause', 19 | aliases: [] 20 | }; -------------------------------------------------------------------------------- /MusicBot/commands/resume.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | 3 | module.exports.run = async (bot, message, args) => { 4 | 5 | let queue = bot.queue.get(message.guild.id); 6 | 7 | if (queue && !queue.playing) { 8 | queue.playing = true; 9 | queue.connection.dispatcher.resume(); 10 | return message.channel.send(`🎵 Music has now been resumed`); 11 | } 12 | 13 | return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 14 | 15 | }; 16 | 17 | module.exports.help = { 18 | name: 'resume', 19 | aliases: [] 20 | }; -------------------------------------------------------------------------------- /MusicBot/commands/stop.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | const config = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let queue = bot.queue.get(message.guild.id); 7 | if (!message.member.voiceChannel) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please join a voice channel to run this command!`, `${config.prefix}stop`), 5000)]; 8 | if (!queue) return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 9 | 10 | queue.musics = []; 11 | queue.connection.dispatcher.end(); 12 | 13 | }; 14 | 15 | module.exports.help = { 16 | name: 'stop', 17 | aliases: ['leave'] 18 | }; -------------------------------------------------------------------------------- /MusicBot/commands/queue.js: -------------------------------------------------------------------------------- 1 | const discord = require('discord.js'); 2 | const utils = require('../global/utils'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let queue = bot.queue.get(message.guild.id); 7 | if (!queue) return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 8 | 9 | let embed = new discord.RichEmbed() 10 | .setColor('RANDOM') 11 | .setThumbnail(bot.user.avatarURL) 12 | .setDescription(`**-=- Music Queue -=-**\n${queue.musics.map(music => 13 | `**-** ${music.title}`).join('\n')}\n\n🎵 **Currently Playing:** ${queue.musics[0].title}`); 14 | 15 | message.channel.send(embed); 16 | 17 | }; 18 | 19 | module.exports.help = { 20 | name: 'queue', 21 | aliases: ['list', 'musiclist', 'songlist'] 22 | } -------------------------------------------------------------------------------- /MusicBot/index.js: -------------------------------------------------------------------------------- 1 | const discord = require('discord.js'); 2 | const ytdl = require('ytdl-core'); 3 | const YouTube = require('simple-youtube-api'); 4 | const ready = require('./handlers/ready'); 5 | const message = require('./handlers/message'); 6 | const config = require('./settiings/config.json'); 7 | const {YouTubeAPIKey} = require('./settiings/credentials.json'); 8 | const utils = require('./global/utils'); 9 | const bot = new discord.Client(); 10 | 11 | require('./global/functions')(bot, utils, ytdl, config); 12 | 13 | bot.commands = new discord.Collection(); 14 | bot.aliases = new discord.Collection(); 15 | bot.youtube = new YouTube(YouTubeAPIKey); // YouTube Client 16 | bot.queue = new Map() // Music Queue 17 | bot.votes = new Map(); // Vote Skip 18 | ready.ready(bot); 19 | message.message(bot, utils, config, discord); -------------------------------------------------------------------------------- /MusicBot/commands/reload.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | const config = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | if (!message.member.hasPermission('ADMINISTRATOR')) return utils.timed_msg(utils.no_perm(`${message.author}, you do have the permissions to run this command!`), 5000) 7 | 8 | let command = args[0]; 9 | if (!command) return utils.timed_msg(utils.cmd_fail('Please enter a command to reload!', `${config.prefix}reload `), 5000) 10 | 11 | let response = await bot.unloadCommand(command); 12 | if (response) return [message.delete(), utils.timed_msg(response, 5000)]; 13 | 14 | response = bot.loadCommand(command); 15 | if (response) return [message.delete(), utils.timed_msg(response, 5000)]; 16 | 17 | return [message.delete(), utils.timed_msg(`Command ${command} has been reloaded successfully!`, 5000)]; 18 | }; 19 | 20 | module.exports.help = { 21 | name: 'reload', 22 | aliases: [] 23 | }; -------------------------------------------------------------------------------- /MusicBot/commands/volume.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | const config = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let queue = bot.queue.get(message.guild.id); 7 | if (!queue) return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 8 | 9 | if (!args[0]) return [message.delete(), message.channel.send(`🎵 Current Volume: **${queue.volume}/100**`)]; 10 | if (isNaN(args[0])) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please input a volume between 0 and 100 only!`, `${config.prefix}volume `), 5000)]; 11 | if (args[0] < 0 || args[0] > 100) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please input a volume between 0 and 100 only!`, `${config.prefix}volume `), 5000)]; 12 | 13 | queue.volume = args[0]; 14 | queue.connection.dispatcher.setVolumeLogarithmic(args[0] / 100); 15 | 16 | return message.channel.send(`🎵 Volume has now been set to **${queue.volume}/100**`); 17 | }; 18 | 19 | module.exports.help = { 20 | name: 'volume', 21 | aliases: ['vol'] 22 | }; -------------------------------------------------------------------------------- /MusicBot/commands/help.js: -------------------------------------------------------------------------------- 1 | const discord = require('discord.js'); 2 | const {prefix} = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let embed = new discord.RichEmbed() 7 | .setColor('RANDOM') 8 | .setThumbnail(bot.user.avatarURL) 9 | .setTitle(`-=- Help -=- <>: MUST, []: OPTIONAL`) 10 | .addField(`${prefix}play `, 'Plays musics!') 11 | .addField(`${prefix}search `, 'Search for top 10 results of musics on youtube') 12 | .addField(`${prefix}skip`, 'Skip the music to the next in the queue (3 votes needed if you have no permissions)') 13 | .addField(`${prefix}volume [volume]`, 'Shows the current volume of if entered arguments, changes volume') 14 | .addField(`${prefix}pause`, 'Pauses the music playback') 15 | .addField(`${prefix}resume`,'Resumes the music playback') 16 | .addField(`${prefix}stop`, 'Stops the music playback, and bot leaves the voice channel') 17 | .addField(`${prefix}reload `, 'Reloads a specified command'); 18 | 19 | message.channel.send(embed); 20 | 21 | }; 22 | 23 | module.exports.help = { 24 | name: 'help', 25 | aliases: [] 26 | }; -------------------------------------------------------------------------------- /MusicBot/global/utils.js: -------------------------------------------------------------------------------- 1 | let disc; 2 | let b; 3 | let conf; 4 | let msg; 5 | let a; 6 | let g; 7 | 8 | module.exports = { 9 | 10 | load: (discord, bot, config, message, args, guild) => { 11 | disc = discord; 12 | b = bot; 13 | conf = config; 14 | msg = message; 15 | a = args; 16 | g = guild; 17 | }, 18 | 19 | timed_msg: (string, time) => { 20 | return msg.channel.send(string).then(msg => msg.delete(time)); 21 | }, 22 | 23 | no_perm: (error) => { 24 | let embed = new disc.RichEmbed() 25 | .setColor('#d30000') 26 | .setAuthor('ERROR: Insufficient Permissions!', b.user.displayAvatarURL) 27 | .setThumbnail(b.user.avatarURL) 28 | .setDescription(error) 29 | .setFooter('Insufficient Permissions!'); 30 | 31 | return embed; 32 | }, 33 | 34 | cmd_fail: (error, syntax) => { 35 | let embed = new disc.RichEmbed() 36 | .setColor("#8e0000") 37 | .setAuthor('ERROR: WRONG SYNTAX', b.user.displayAvatarURL) 38 | .setThumbnail(b.user.avatarURL) 39 | .setDescription(error) 40 | .setFooter(syntax); 41 | return embed; 42 | } 43 | } -------------------------------------------------------------------------------- /MusicBot/commands/skip.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | const config = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let queue = bot.queue.get(message.guild.id); 7 | let votes = bot.votes.get(message.guild.id); 8 | if (!message.member.voiceChannel) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please join a voice channel to run this command!`, `${config.prefix}skip`), 5000)]; 9 | if (!queue) return [message.delete(), utils.timed_msg('⚠ No musics are being played.', 5000)]; 10 | 11 | if (!message.member.hasPermission('ADMINISTRATOR')) { 12 | if (votes.voters.includes(message.author.id)) return [message.delete(), utils.timed_msg(utils.cmd_fail(`⚠ ${message.author}, you have already voted! **${votes.votes}/3** votes`, `${config.prefix}skip`), 5000)]; 13 | 14 | votes.votes++ 15 | votes.voters.push(message.author.id); 16 | message.channel.send(`🎵 ${message.author}, you have voted to skip! **${votes.votes}/3** votes`); 17 | 18 | if (votes.votes > 3) return queue.connection.dispatcher.end(); 19 | } else return queue.connection.dispatcher.end(); 20 | 21 | }; 22 | 23 | module.exports.help = { 24 | name: 'skip', 25 | aliases: [] 26 | }; -------------------------------------------------------------------------------- /MusicBot/handlers/message.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | message: (bot, utils, config, discord) => { 4 | bot.on('message', async message => { 5 | 6 | if (message.author.bot) return; 7 | if (message.channel.type === "dm") return; 8 | 9 | let prefix = config.prefix; 10 | let args = message.content.slice(prefix.length).trim().split(' '); 11 | let cmd = args.shift().toLowerCase(); 12 | let command; 13 | 14 | utils.load(discord, bot, config, message, args, message.guild); 15 | if (!message.content.startsWith(config.prefix)) return; 16 | if (bot.commands.has(cmd)) { 17 | command = bot.commands.get(cmd); 18 | } else if (bot.aliases.has(cmd)) { 19 | command = bot.commands.get(bot.aliases.get(cmd)); 20 | } 21 | 22 | if (config.commandNotFound == true) { 23 | try { 24 | command.run(bot, message, args); 25 | } catch (err) { 26 | if (err) utils.timed_msg(utils.cmd_fail(`Command \`${cmd}\` is not found!`, `${prefix}play `), 5000); 27 | } 28 | } else { 29 | try { 30 | command.run(bot, message, args); 31 | } catch (err) { 32 | if (err) return undefined; 33 | } 34 | } 35 | }); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /MusicBot/commands/play.js: -------------------------------------------------------------------------------- 1 | const utils = require('../global/utils'); 2 | const config = require('../settiings/config.json'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | 6 | let VC = message.member.voiceChannel; 7 | if (!VC) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please join a voice channel!`, `${config.prefix}play `), 5000)]; 8 | 9 | let url = args[0] ? args[0].replace(/<(.+)>/g, '$1') : ''; 10 | let pl = /^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/ 11 | 12 | let searchString = args.join(' '); 13 | if (!url || !searchString) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please enter a music name or url!`, `${config.prefix}play `), 5000)]; 14 | 15 | let perms = VC.permissionsFor(message.client.user); 16 | if (!perms.has('CONNECT')) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, I do not have permissions to connect to voice channels!`, `${config.prefix}play `), 5000)]; 17 | if (!perms.has('SPEAK')) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, I do not have permissions to speak in a voice channel`, `${config.prefix}play `), 5000)]; 18 | 19 | if (url.match(pl)) { 20 | let playlist = await bot.youtube.getPlaylist(url); 21 | let videos = await playlist.getVideos(); 22 | 23 | for (const vid of Object.values(videos)) { 24 | let video = await bot.youtube.getVideoByID(vid.id) 25 | await bot.handleVideo(video, message, VC, true) 26 | } 27 | 28 | return message.channel.send(`🎵 **${playlist.title}** has been added to queue.`); 29 | } else { 30 | 31 | try { 32 | var video = await bot.youtube.getVideo(url); 33 | } catch (err) { 34 | if (err) undefined; 35 | try { 36 | var vid = await bot.youtube.searchVideos(searchString, 1); 37 | var video = await bot.youtube.getVideoByID(vid[0].id); 38 | } catch (err) { 39 | console.error(err); 40 | return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, no videos can be found with the argument \`${searchString}\``, `${config.prefix}play `), 5000)]; 41 | } 42 | } 43 | return bot.handleVideo(video, message, VC); 44 | } 45 | }; 46 | 47 | module.exports.help = { 48 | name: 'play', 49 | aliases: ['join'] 50 | }; -------------------------------------------------------------------------------- /MusicBot/commands/search.js: -------------------------------------------------------------------------------- 1 | const discord = require('discord.js'); 2 | const utils = require('../global/utils'); 3 | const config = require('../settiings/config.json'); 4 | 5 | module.exports.run = async (bot, message, args) => { 6 | 7 | let VC = message.member.voiceChannel; 8 | if (!VC) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please join a voice channel!`, `${config.prefix}play `), 5000)]; 9 | 10 | let url = args[0] ? args[0].replace(/<(.+)>/g, '$1') : ''; 11 | let pl = /^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/ 12 | 13 | let searchString = args.join(' '); 14 | if (!url || !searchString) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, please enter a music name or url!`, `${config.prefix}play `), 5000)]; 15 | 16 | let perms = VC.permissionsFor(message.client.user); 17 | if (!perms.has('CONNECT')) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, I do not have permissions to connect to voice channels!`, `${config.prefix}play `), 5000)]; 18 | if (!perms.has('SPEAK')) return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, I do not have permissions to speak in a voice channel`, `${config.prefix}play `), 5000)]; 19 | 20 | if (url.match(pl)) { 21 | let playlist = await bot.youtube.getPlaylist(url); 22 | let videos = await playlist.getVideos(); 23 | 24 | for (const vid of Object.values(videos)) { 25 | let video = await bot.youtube.getVideoByID(vid.id) 26 | await bot.handleVideo(video, message, VC, true) 27 | } 28 | 29 | return message.channel.send(`🎵 **${playlist.title}** has been added to queue.`); 30 | } else { 31 | 32 | try { 33 | var video = await bot.youtube.getVideo(url); 34 | } catch (err) { 35 | if (err) undefined; 36 | try { 37 | var videos = await bot.youtube.searchVideos(searchString, 10); 38 | let index = 0; 39 | 40 | let embed = new discord.RichEmbed() 41 | .setColor('RANDOM') 42 | .setThumbnail(bot.user.avatarURL) 43 | .setDescription(`**-=- Music Searches -=-**\n${videos.map(video => 44 | `**${++index} -** ${video.title}`).join('\n')}\n\n🎵 Select a music from above between **1** and **10** within **10 seconds**`); 45 | 46 | message.channel.send(embed); 47 | 48 | try { 49 | var response = await message.channel.awaitMessages(msg => msg.content > 0 && msg.content < 11, { 50 | maxMatches: 1, 51 | time: 10000, 52 | errors: ['time'] 53 | }); 54 | } catch (err) { 55 | if (err) undefined 56 | return message.channel.send(utils.cmd_fail('⚠ You have exceeded the 10 seconds selection time', `${config.prefix}search `)); 57 | } 58 | const videoIndex = parseInt(response.first().content); 59 | var video = await bot.youtube.getVideoByID(videos[videoIndex - 1].id); 60 | } catch (err) { 61 | console.error(err); 62 | return [message.delete(), utils.timed_msg(utils.cmd_fail(`${message.author}, no videos can be found with the argument \`${searchString}\``, `${config.prefix}play `), 5000)]; 63 | } 64 | } 65 | return bot.handleVideo(video, message, VC); 66 | } 67 | }; 68 | 69 | module.exports.help = { 70 | name: 'search', 71 | aliases: [] 72 | }; -------------------------------------------------------------------------------- /MusicBot/global/functions.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | module.exports = (bot, utils, ytdl, config) => { 3 | 4 | fs.readdir("./commands/", (err, files) => { 5 | 6 | if (err) console.error(err); 7 | let jsfiles = files.filter(f => f.split(".").pop() === "js"); 8 | 9 | if (jsfiles.length <= 0) return console.log("There are no commands to load..."); 10 | 11 | console.log(`Loading ${jsfiles.length} commands...`); 12 | jsfiles.forEach((f, i) => { 13 | let props = require(`../commands/${f}`); 14 | console.log(`${i + 1}: ${f} loaded!`); 15 | bot.commands.set(props.help.name, props); 16 | props.help.aliases.forEach(alias => { 17 | bot.aliases.set(alias, props.help.name); 18 | }); 19 | }); 20 | }); 21 | 22 | bot.loadCommand = (commandName) => { 23 | try { 24 | let props = require(`../commands/${commandName}`); 25 | if (props.init) props.init(bot); 26 | bot.commands.set(commandName, props); 27 | props.help.aliases.forEach(alias => { 28 | bot.aliases.set(alias, props.help.name); 29 | }); 30 | return false; 31 | } catch (err) { 32 | return utils.cmd_fail(`Error: ${err}\nCommand \`${commandName}\` cannot be found.`, `${config.prefix}reload `); 33 | } 34 | }; 35 | 36 | bot.unloadCommand = async (commandName) => { 37 | try { 38 | if (!commandName) return `The command \`${commandName}\` doesn"t seem to exist. Try again!`; 39 | 40 | if (commandName.shutdown) await commandName.shutdown(bot); 41 | delete require.cache[require.resolve(`../commands/${commandName}.js`)]; 42 | return false; 43 | } catch (err) { 44 | return utils.cmd_fail(`Error: ${err}\nCommand \`${commandName}\` cannot be found.`, `${config.prefix}reload `); 45 | } 46 | }; 47 | 48 | bot.handleVideo = async (video, message, vc, playlist = false) => { 49 | let queue = bot.queue.get(message.guild.id); 50 | let music = { 51 | id: video.id, 52 | title: video.title, 53 | url: `https://www.youtube.com/watch?v=${video.id}` 54 | }; 55 | 56 | if (!queue) { 57 | let queueConstruct = { 58 | textChannel: message.channel, 59 | voiceChannel: vc, 60 | connection: null, 61 | musics: [], 62 | volume: 50, 63 | playing: true 64 | }; 65 | let voteConstruct = { 66 | votes: 0, 67 | voters: [] 68 | }; 69 | 70 | bot.queue.set(message.guild.id, queueConstruct); 71 | bot.votes.set(message.guild.id, voteConstruct) 72 | queueConstruct.musics.push(music); 73 | 74 | try { 75 | var connection = await vc.join(); 76 | queueConstruct.connection = connection; 77 | bot.play(message.guild, queueConstruct.musics[0]); 78 | } catch (err) { 79 | bot.queue.delete(message.guild.id); 80 | console.error(`I could not join your voice channel: ${err}`); 81 | } 82 | } else { 83 | queue.musics.push(music); 84 | if (playlist) return; 85 | else return message.channel.send(`🎵 **${music.title}** has been added to queue`); 86 | } 87 | return; 88 | } 89 | 90 | bot.play = (guild, music) => { 91 | let queue = bot.queue.get(guild.id); 92 | let votes = bot.votes.get(guild.id) 93 | if (!music) { 94 | queue.voiceChannel.leave(); 95 | bot.queue.delete(guild.id); 96 | bot.votes.delete(guild.id); 97 | return queue.textChannel.send(`🎵 Music playback has ended`); 98 | } 99 | 100 | let dispatcher = queue.connection.playStream(ytdl(music.url)) 101 | .on('end', () => { 102 | queue.musics.shift(); 103 | votes.votes = 0; 104 | votes.voters = []; 105 | setTimeout(() => { 106 | bot.play(guild, queue.musics[0]); 107 | }, 250); 108 | }) 109 | .on('error', err => console.error(err)); 110 | dispatcher.setVolumeLogarithmic(queue.volume / 100); 111 | 112 | queue.textChannel.send(`🎵 **${music.title}** is now being played`); 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /MusicBot/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "async-limiter": { 6 | "version": "1.0.0", 7 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 8 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 9 | }, 10 | "cross-fetch": { 11 | "version": "2.2.2", 12 | "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", 13 | "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", 14 | "requires": { 15 | "node-fetch": "2.1.2", 16 | "whatwg-fetch": "2.0.4" 17 | } 18 | }, 19 | "discord.js": { 20 | "version": "11.4.2", 21 | "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-11.4.2.tgz", 22 | "integrity": "sha512-MDwpu0lMFTjqomijDl1Ed9miMQe6kB4ifKdP28QZllmLv/HVOJXhatRgjS8urp/wBlOfx+qAYSXcdI5cKGYsfg==", 23 | "requires": { 24 | "long": "4.0.0", 25 | "prism-media": "0.0.3", 26 | "snekfetch": "3.6.4", 27 | "tweetnacl": "1.0.0", 28 | "ws": "4.1.0" 29 | } 30 | }, 31 | "html-entities": { 32 | "version": "1.2.1", 33 | "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", 34 | "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" 35 | }, 36 | "iso8601-duration": { 37 | "version": "1.1.6", 38 | "resolved": "https://registry.npmjs.org/iso8601-duration/-/iso8601-duration-1.1.6.tgz", 39 | "integrity": "sha512-wyVl4tmjZyaoh9GeohL3Dh4DKwr8CgiOL8eFRyRJyk8nopHOhZ0Ql76EwOUvx3OGQeI08xGj8+4AJgyXYs3iJw==" 40 | }, 41 | "long": { 42 | "version": "4.0.0", 43 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 44 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" 45 | }, 46 | "m3u8stream": { 47 | "version": "0.4.2", 48 | "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.4.2.tgz", 49 | "integrity": "sha512-VZeobA83iQdd2TY12K2DNLuUmE1XNjN660SYU9s6A4kP7ZhFEp/bQPUpOWU2EbkFYwsonyaFT+RxLDr1OhPTRA==", 50 | "requires": { 51 | "miniget": "1.5.0", 52 | "sax": "1.2.4" 53 | } 54 | }, 55 | "miniget": { 56 | "version": "1.5.0", 57 | "resolved": "https://registry.npmjs.org/miniget/-/miniget-1.5.0.tgz", 58 | "integrity": "sha512-RbRCj2m8Q/arS1nExuMB8qO4QavCpvfetQR+HVCeHGiFJGOryPn8u0z4WrIx9AAIDYFDVcFhQsRYvSY+UA5HJQ==" 59 | }, 60 | "node-fetch": { 61 | "version": "2.1.2", 62 | "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", 63 | "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" 64 | }, 65 | "opusscript": { 66 | "version": "0.0.6", 67 | "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.6.tgz", 68 | "integrity": "sha512-F7nx1SWZCD5Rq2W+5Fx39HlkRkz/5Zqt0LglEB9uHexk8HjedDEiM+u/Y2rBfDFcS/0uQIWu2lJhw+Gjsta+cA==" 69 | }, 70 | "prism-media": { 71 | "version": "0.0.3", 72 | "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-0.0.3.tgz", 73 | "integrity": "sha512-c9KkNifSMU/iXT8FFTaBwBMr+rdVcN+H/uNv1o+CuFeTThNZNTOrQ+RgXA1yL/DeLk098duAeRPP3QNPNbhxYQ==" 74 | }, 75 | "safe-buffer": { 76 | "version": "5.1.2", 77 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 78 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 79 | }, 80 | "sax": { 81 | "version": "1.2.4", 82 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 83 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 84 | }, 85 | "simple-youtube-api": { 86 | "version": "5.0.2", 87 | "resolved": "https://registry.npmjs.org/simple-youtube-api/-/simple-youtube-api-5.0.2.tgz", 88 | "integrity": "sha512-MtFToFLoX4eWNVUcqhbJ3J7SN8tBNaHRAHC4RKzSCW7cEVVZygNHa3nhCEWVINBoI1fmxjEUW7zwdlChYNuoZg==", 89 | "requires": { 90 | "cross-fetch": "2.2.2", 91 | "iso8601-duration": "1.1.6" 92 | } 93 | }, 94 | "snekfetch": { 95 | "version": "3.6.4", 96 | "resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz", 97 | "integrity": "sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw==" 98 | }, 99 | "tweetnacl": { 100 | "version": "1.0.0", 101 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz", 102 | "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins=" 103 | }, 104 | "whatwg-fetch": { 105 | "version": "2.0.4", 106 | "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", 107 | "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" 108 | }, 109 | "ws": { 110 | "version": "4.1.0", 111 | "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", 112 | "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", 113 | "requires": { 114 | "async-limiter": "1.0.0", 115 | "safe-buffer": "5.1.2" 116 | } 117 | }, 118 | "ytdl-core": { 119 | "version": "0.26.0", 120 | "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-0.26.0.tgz", 121 | "integrity": "sha512-s6BbWiO4lFvOEHjtW2vaLmg3Dd9ftDfUn7KUVLS2Xkbztfu+HxaN0Q0/HL3yX6/L2D3jGpOwgDHO74LB1qCvHQ==", 122 | "requires": { 123 | "html-entities": "1.2.1", 124 | "m3u8stream": "0.4.2", 125 | "miniget": "1.5.0", 126 | "sax": "1.2.4" 127 | } 128 | } 129 | } 130 | } 131 | --------------------------------------------------------------------------------