woomy/utils/music.js

224 lines
5.6 KiB
JavaScript
Raw Normal View History

2020-04-20 04:52:50 +00:00
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
2020-04-20 03:02:10 +00:00
2020-04-13 04:28:53 +00:00
const ytdl = require('ytdl-core-discord')
const fetch = require('node-fetch')
const { MessageEmbed } = require('discord.js')
const { utc } = require('moment')
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.queue = {}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.createTimestamp = function (s) {
2020-04-20 09:19:32 +00:00
if (s < 1) {
return 'LIVE'
} else if (s >= 3600) {
2020-04-19 10:10:52 +00:00
return utc(s * 1000).format('HH:mm:ss')
} else {
return utc(s * 1000).format('mm:ss')
2020-03-30 16:01:13 +00:00
}
2020-04-19 10:10:52 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.getGuild = function (id) {
let guild = exports.queue[id]
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
if (!guild) {
guild = {}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
guild.queue = []
2020-04-20 09:19:32 +00:00
guild.playing = false
guild.paused = false
guild.dispatcher = null
guild.skippers = []
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.queue[id] = guild
2020-04-13 04:28:53 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
return guild
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.getLinkFromID = function (id) {
return 'https://www.youtube.com/watch?v=' + id
}
2020-04-15 05:43:31 +00:00
exports.getVideoByQuery = async function (client, query) {
2020-04-19 10:10:52 +00:00
let res
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
try {
const id = await ytdl.getURLVideoID(query)
res = await fetch(`${client.config.endpoints.invidious}v1/videos/${id}`)
2020-04-19 10:10:52 +00:00
} catch (err) {
res = await fetch(`${client.config.endpoints.invidious}v1/search?q=${encodeURIComponent(query)}`)
2020-04-19 10:10:52 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
const parsed = await res.json()
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
if (parsed) {
const videos = parsed
if (videos) {
return videos
2020-04-09 07:54:18 +00:00
} else {
2020-04-13 04:28:53 +00:00
return false
}
2020-04-19 10:10:52 +00:00
} else {
return false
2020-04-13 04:28:53 +00:00
}
2020-04-19 10:10:52 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
exports.play = async function (client, message, query, ignoreQueue) {
const guild = exports.getGuild(message.guild.id)
2020-04-22 08:00:19 +00:00
guild.message = message
2020-04-09 07:54:18 +00:00
2020-04-21 09:14:49 +00:00
if (!message.member.voice.channel && !guild.voiceChannel) {
2020-04-19 10:10:52 +00:00
return message.reply('You have to be connected to a voice channel to use this command!')
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
const vc = message.member.voice.channel
2020-04-13 04:28:53 +00:00
2020-04-19 10:10:52 +00:00
let video
let videos
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
if (!ignoreQueue) {
videos = await exports.getVideoByQuery(client, query)
2020-04-19 10:10:52 +00:00
if (!videos[1]) {
if (!videos[0]) {
video = videos
} else {
video = videos[0]
2020-04-15 05:43:31 +00:00
}
2020-04-13 04:28:53 +00:00
}
2020-04-19 10:10:52 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
if (videos || ignoreQueue) {
if (!ignoreQueue) {
// Fix the bot if somehow broken
// music "playing", nothing in queue
if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) {
2020-04-22 09:00:57 +00:00
guild.queue = []
2020-04-19 10:10:52 +00:00
guild.playing = false
2020-04-22 09:00:57 +00:00
guild.paused = false
2020-04-19 10:10:52 +00:00
guild.dispatcher = null
2020-04-22 09:00:57 +00:00
guild.skippers = []
2020-04-19 10:10:52 +00:00
// music not playing, something is in queue
} else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) {
guild.queue = []
}
2020-04-12 09:07:01 +00:00
2020-04-19 10:10:52 +00:00
if (!video) {
let output = ''
let i = 0
for (i = 0; i < 5; i++) {
if (!videos[i]) break
output += `\`${i + 1}:\` **[${videos[i].title}](https://www.youtube.com/watch?v=${videos[i].videoId})** \`[${exports.createTimestamp(videos[i].lengthSeconds)}]\`\n`
}
2020-04-15 05:43:31 +00:00
2020-04-19 10:10:52 +00:00
const embed = new MessageEmbed()
embed.setTitle('Please reply with a number `1-' + i + '` to select which song you want to add to the queue.')
embed.setColor(client.embedColour(message.guild))
embed.setDescription(output)
let selection = await client.awaitReply(message, embed)
selection = Number(selection)
switch (selection) {
case 1:
video = videos[0]
break
case 2:
if (videos[1]) {
video = videos[1]
} else {
return message.channel.send('Invalid choice.')
}
break
case 3:
if (videos[2]) {
video = videos[2]
} else {
return message.channel.send('Invalid choice.')
}
break
case 4:
if (videos[3]) {
video = videos[3]
} else {
return message.channel.send('Invalid choice.')
}
break
case 5:
if (videos[4]) {
video = videos[4]
} else {
return message.channel.send('Invalid choice.')
}
break
default:
return message.channel.send('Invalid choice.')
}
2020-04-19 10:10:52 +00:00
}
2020-04-19 10:10:52 +00:00
if (!video && videos[0]) {
video = videos[0]
} else if (!video) {
video = videos
2020-04-13 04:28:53 +00:00
}
2020-04-09 07:54:18 +00:00
2020-04-19 10:10:52 +00:00
// Add video to queue
2020-04-20 09:19:32 +00:00
guild.queue.push({ video: video, requestedBy: message.author })
2020-04-19 10:10:52 +00:00
}
2020-04-13 04:28:53 +00:00
// Figure out if the bot should add it to queue or play it right now
2020-04-19 10:10:52 +00:00
if (guild.playing) {
message.reply('added **' + video.title + '** to the queue')
} else {
guild.playing = true
2020-04-09 07:54:18 +00:00
2020-04-21 09:14:49 +00:00
guild.voiceChannel = vc
2020-04-12 09:07:01 +00:00
2020-04-19 10:10:52 +00:00
const connection = await vc.join()
2020-04-14 13:13:00 +00:00
2020-04-19 10:10:52 +00:00
const v = guild.queue[0]
2020-04-11 14:30:08 +00:00
2020-04-19 10:10:52 +00:00
guild.dispatcher = connection.play(await ytdl(exports.getLinkFromID(v.video.videoId), { highWaterMark: 1024 * 1024 * 32 }), { type: 'opus' })
guild.dispatcher.setVolume(0.25)
2020-04-12 09:07:01 +00:00
2020-04-19 10:10:52 +00:00
message.channel.send('Playing **' + v.video.title + '**')
2020-04-12 09:07:01 +00:00
2020-04-19 10:10:52 +00:00
// play next in queue on end
guild.dispatcher.once('finish', () => {
guild.queue.shift()
guild.playing = false
2020-04-12 09:07:01 +00:00
2020-04-19 10:10:52 +00:00
if (guild.queue.length > 0) {
2020-04-20 09:19:32 +00:00
exports.play(client, message, null, true)
2020-04-19 10:10:52 +00:00
} else {
2020-04-22 09:00:57 +00:00
guild.queue = []
guild.playing = false
guild.paused = false
2020-04-19 10:10:52 +00:00
guild.dispatcher = null
2020-04-22 09:00:57 +00:00
guild.skippers = []
2020-04-19 10:10:52 +00:00
connection.disconnect()
}
})
2020-04-13 04:28:53 +00:00
}
2020-04-19 10:10:52 +00:00
} else {
return message.reply('failed to find the video!')
2020-04-13 04:28:53 +00:00
}
2020-04-19 10:10:52 +00:00
}
2020-04-11 14:45:47 +00:00
2020-04-19 10:10:52 +00:00
exports.setVolume = function (guild, target) {
const g = exports.getGuild(guild.id)
2020-04-11 14:45:47 +00:00
2020-04-19 10:10:52 +00:00
if (g.dispatcher) {
g.dispatcher.setVolume(target)
2020-04-13 04:28:53 +00:00
}
2020-04-19 10:10:52 +00:00
}
2020-04-12 09:24:58 +00:00
2020-04-19 10:10:52 +00:00
exports.skip = function (guild, reason) {
const g = exports.getGuild(guild.id)
2020-04-12 09:24:58 +00:00
2020-04-19 10:10:52 +00:00
if (g.dispatcher) {
g.dispatcher.end(reason)
2020-04-13 04:28:53 +00:00
}
2020-03-30 16:01:13 +00:00
}