summaryrefslogtreecommitdiff
path: root/server/src/utils/Play.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/utils/Play.ts')
-rw-r--r--server/src/utils/Play.ts138
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