diff options
Diffstat (limited to 'server/src/utils/Play.ts')
| -rw-r--r-- | server/src/utils/Play.ts | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/server/src/utils/Play.ts b/server/src/utils/Play.ts new file mode 100644 index 0000000..507cc0c --- /dev/null +++ b/server/src/utils/Play.ts @@ -0,0 +1,138 @@ +import { Message } from "discord.js"; +import { AkairoClient } from "discord-akairo"; +import ytdlDiscord from 'ytdl-core-discord'; +import * as scdl from 'soundcloud-downloader'; +import { StreamDispatcher } from "discord.js"; +import { MessageCollector } from "discord.js"; +import Util from '../utils/Utils'; + +module.exports = { + async play(song, client: AkairoClient, msg: Message) { + const { PRUNING, SOUNDCLOUD_CLIENT_ID } = require('../Config'); + const queue = client.queue.get(msg.guild.id); + + if (!song) { + queue.channel.leave(); + client.queue.delete(msg.guild.id); + return queue.channel.send('Music queue ended.'); // catch + } + + let stream = null; + + try { + if (song.url.includes('youtube.com')) { + stream = await ytdlDiscord(song.url, { highWaterMark: 1 << 25 }); + } else if (song.url.includes('soundcloud.com') && SOUNDCLOUD_CLIENT_ID) { + stream = await scdl.downloadFormat(song.url, scdl.FORMATS.OPUS, SOUNDCLOUD_CLIENT_ID); + } + } catch (error) { + if (queue) { + queue.songs.shift(); + module.exports.play(queue.songs[0], msg); + } + + // error + return msg.channel.send(`Error: ${error.message ? error.message : error}`); + } + + queue.connection.on('disconnect', () => client.queue.delete(msg.guild.id)); + + const type = song.url.includes('youtube.com') ? 'opus' : 'ogg/opus'; + const dispatcher: StreamDispatcher = queue.connection + .play(stream, { type: type }) + .on('finish', () => { + if (collector && !collector.ended) collector.stop(); + + if (queue.loop) { + let lastSong = queue.songs.shift(); + queue.songs.push(lastSong); + // export + } else { + queue.songs.shift(); + // export + } + }) + .on('error', (err) => { + // error + queue.songs.shift(); + module.exports.play(queue.songs[0], msg); + }); + dispatcher.setVolumeLogarithmic(queue.volume / 100); + + try { + var playingMessage = await queue.channel.send(`Started playing: **${song.title}** ${song.url}`); + await playingMessage.react("⏭"); + await playingMessage.react("⏯"); + await playingMessage.react("🔁"); + await playingMessage.react("⏹"); + } catch (error) { + // error + } + + const filter = (reaction, user) => user.id !== client.user.id; + var collector: MessageCollector = playingMessage.createReactionCollector(filter, { + time: song.duration > 0 ? song.duration * 1000 : 600000 + }); + + collector.on('collect', (reaction, user) => { + if (!queue) return; + const member = msg.guild.member(user); + + switch (reaction.emoji.name) { + case "⏭": + queue.playing = true; + reaction.users.remove(user).catch(console.error); + if (!Util.canModifyQueue(member)) return; + queue.connection.dispatcher.end(); + queue.textChannel.send(`${user} ⏩ skipped the song`).catch(console.error); + collector.stop(); + break; + + case "⏯": + reaction.users.remove(user).catch(console.error); + if (!Util.canModifyQueue(member)) return; + if (queue.playing) { + queue.playing = !queue.playing; + queue.connection.dispatcher.pause(true); + queue.textChannel.send(`${user} ⏸ paused the music.`).catch(console.error); + } else { + queue.playing = !queue.playing; + queue.connection.dispatcher.resume(); + queue.textChannel.send(`${user} ▶ resumed the music!`).catch(console.error); + } + break; + + case "🔁": + reaction.users.remove(user).catch(console.error); + if (!Util.canModifyQueue(member)) return; + queue.loop = !queue.loop; + queue.textChannel.send(`Loop is now ${queue.loop ? "**on**" : "**off**"}`).catch(console.error); + break; + + case "⏹": + reaction.users.remove(user).catch(console.error); + if (!Util.canModifyQueue(member)) return; + queue.songs = []; + queue.textChannel.send(`${user} ⏹ stopped the music!`).catch(console.error); + try { + queue.connection.dispatcher.end(); + } catch (error) { + console.error(error); + queue.connection.disconnect(); + } + collector.stop(); + break; + + default: + reaction.users.remove(user).catch(console.error); + break; + } + }); + + collector.on('end', () => { + playingMessage.reactions.removeAll(); // catch + if (PRUNING && playingMessage && !playingMessage.deleted) + playingMessage.delete({ timeout: 3000 }); // catch + }); + } +}
\ No newline at end of file |