Skip to content

Commit

Permalink
refactor: music system
Browse files Browse the repository at this point in the history
  • Loading branch information
eritislami committed Apr 30, 2022
1 parent 2bb49d4 commit 3d57a80
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 369 deletions.
99 changes: 9 additions & 90 deletions commands/play.js
@@ -1,21 +1,11 @@
import {
createAudioPlayer,
getVoiceConnection,
joinVoiceChannel,
NoSubscriberBehavior
} from "@discordjs/voice";
import https from "https";
import YouTubeAPI from "simple-youtube-api";
import Scdl from "soundcloud-downloader";
import ytdl from "ytdl-core";
import { play } from "../include/play.js";
import { generateQueue } from "../utils/queue.js";
import { config } from "../utils/config.js";
import { getSong } from "../music/getSong.js";
import { startQueue } from "../music/startQueue.js";
import { i18n } from "../utils/i18n.js";
import { videoPattern, playlistPattern, scRegex, mobileScRegex } from "../utils/patterns.js";
import { mobileScRegex, playlistPattern, videoPattern } from "../utils/patterns.js";
import { generateQueue } from "../utils/queue.js";

const { SOUNDCLOUD_CLIENT_ID, YOUTUBE_API_KEY } = config;
const youtube = new YouTubeAPI(YOUTUBE_API_KEY);
const scdl = Scdl.create();

export default {
Expand All @@ -26,6 +16,7 @@ export default {
permissions: ["CONNECT", "SPEAK", "ADD_REACTIONS", "MANAGE_MESSAGES"],
async execute(message, args) {
const { channel } = message.member.voice;

if (!channel) return message.reply(i18n.__("play.errorNotChannel")).catch(console.error);

const queue = message.client.queue.get(message.guild.id);
Expand All @@ -40,9 +31,7 @@ export default {
.reply(i18n.__mf("play.usageReply", { prefix: message.client.prefix }))
.catch(console.error);

const search = args.join(" ");
const url = args[0];
const urlValid = videoPattern.test(args[0]);

// Start the playlist if playlist url was provided
if (
Expand All @@ -69,58 +58,9 @@ export default {
return message.reply("Following url redirection...").catch(console.error);
}

let songInfo = null;
let song = null;

if (urlValid) {
try {
songInfo = await ytdl.getInfo(url);
song = {
title: songInfo.videoDetails.title,
url: songInfo.videoDetails.video_url,
duration: songInfo.videoDetails.lengthSeconds
};
} catch (error) {
console.error(error);
return message.reply(error.message).catch(console.error);
}
} else if (scRegex.test(url)) {
try {
const trackInfo = await scdl.getInfo(url, SOUNDCLOUD_CLIENT_ID);
song = {
title: trackInfo.title,
url: trackInfo.permalink_url,
duration: Math.ceil(trackInfo.duration / 1000)
};
} catch (error) {
console.error(error);
return message.reply(error.message).catch(console.error);
}
} else {
try {
const results = await youtube.searchVideos(search, 1, { part: "id" });

if (!results.length) {
message.reply(i18n.__("play.songNotFound")).catch(console.error);
return;
}

songInfo = await ytdl.getInfo(results[0].url);
song = {
title: songInfo.videoDetails.title,
url: songInfo.videoDetails.video_url,
duration: songInfo.videoDetails.lengthSeconds
};
} catch (error) {
console.error(error);
const song = await getSong({ message, args });

if (error.message.includes("410")) {
return message.reply(i18n.__("play.songAccessErr")).catch(console.error);
} else {
return message.reply(error.message).catch(console.error);
}
}
}
if (!song) return message.reply(i18n.__("common.errorCommand")).catch(console.error);

if (queue) {
queue.songs.push(song);
Expand All @@ -131,31 +71,10 @@ export default {
}

const queueConstruct = generateQueue(message.channel, channel);

queueConstruct.songs.push(song);
message.client.queue.set(message.guild.id, queueConstruct);

try {
queueConstruct.player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Pause
}
});

queueConstruct.connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator
});

play(queueConstruct.songs[0], message);
} catch (error) {
console.error(error);
message.client.queue.delete(message.guild.id);

getVoiceConnection(channel.guild.id).destroy();
message.client.queue.set(message.guild.id, queueConstruct);

return message.reply(i18n.__mf("play.cantJoinChannel", { error: error })).catch(console.error);
}
startQueue({ message, channel });
}
};
105 changes: 14 additions & 91 deletions commands/playlist.js
@@ -1,20 +1,8 @@
import {
createAudioPlayer,
getVoiceConnection,
joinVoiceChannel,
NoSubscriberBehavior
} from "@discordjs/voice";
import { MessageEmbed } from "discord.js";
import YouTubeAPI from "simple-youtube-api";
import Scdl from "soundcloud-downloader";
import { play } from "../include/play.js";
import { generateQueue } from "../utils/queue.js";
import { config } from "../utils/config.js";
import { getPlaylist } from "../music/getPlaylist.js";
import { startQueue } from "../music/startQueue.js";
import { i18n } from "../utils/i18n.js";

const { MAX_PLAYLIST_SIZE, SOUNDCLOUD_CLIENT_ID, YOUTUBE_API_KEY } = config;
const youtube = new YouTubeAPI(YOUTUBE_API_KEY);
const scdl = Scdl.create();
import { generateQueue } from "../utils/queue.js";

export default {
name: "playlist",
Expand All @@ -24,7 +12,7 @@ export default {
permissions: ["CONNECT", "SPEAK", "ADD_REACTIONS", "MANAGE_MESSAGES"],
async execute(message, args) {
const { channel } = message.member.voice;
const serverQueue = message.client.queue.get(message.guild.id);
const queue = message.client.queue.get(message.guild.id);

if (!args.length)
return message
Expand All @@ -33,65 +21,27 @@ export default {

if (!channel) return message.reply(i18n.__("playlist.errorNotChannel")).catch(console.error);

if (serverQueue && channel.id !== serverQueue.channel.id)
if (queue && channel.id !== queue.channel.id)
return message
.reply(i18n.__mf("play.errorNotInSameChannel", { user: message.client.user.username }))
.catch(console.error);

const search = args.join(" ");
const pattern = /^.*(youtu.be\/|list=)([^#\&\?]*).*/gi;
const url = args[0];
const urlValid = pattern.test(args[0]);

const queueConstruct = generateQueue(message.channel, channel);
const { playlist, videos } = await getPlaylist({ message, args });

let playlist = null;
let videos = [];

if (urlValid) {
try {
playlist = await youtube.getPlaylist(url, { part: "snippet" });
videos = await playlist.getVideos(MAX_PLAYLIST_SIZE || 10, { part: "snippet" });
} catch (error) {
console.error(error);
return message.reply(i18n.__("playlist.errorNotFoundPlaylist")).catch(console.error);
}
} else if (scdl.isValidUrl(args[0])) {
if (args[0].includes("/sets/")) {
message.reply(i18n.__("playlist.fetchingPlaylist"));
playlist = await scdl.getSetInfo(args[0], SOUNDCLOUD_CLIENT_ID);
videos = playlist.tracks.map((track) => ({
title: track.title,
url: track.permalink_url,
duration: track.duration / 1000
}));
}
if (queue) {
queue.songs.push(...videos);
} else {
try {
const results = await youtube.searchPlaylists(search, 1, { part: "id" });
playlist = results[0];
videos = await playlist.getVideos(MAX_PLAYLIST_SIZE, { part: "snippet" });
} catch (error) {
console.error(error);
return message.reply(error.message).catch(console.error);
}
}
const queueConstruct = generateQueue(message.channel, channel);
queueConstruct.songs.push(...videos);

const newSongs = videos
.filter((video) => video.title != "Private video" && video.title != "Deleted video")
.map((video) => {
return {
title: video.title,
url: video.url,
duration: video.durationSeconds
};
});
message.client.queue.set(message.guild.id, queueConstruct);

serverQueue ? serverQueue.songs.push(...newSongs) : queueConstruct.songs.push(...newSongs);
startQueue({ message, channel });
}

let playlistEmbed = new MessageEmbed()
.setTitle(`${playlist.title}`)
.setDescription(newSongs.map((song, index) => `${index + 1}. ${song.title}`).join("\n"))
.setDescription(videos.map((song, index) => `${index + 1}. ${song.title}`).join("\n"))
.setURL(playlist.url)
.setColor("#F8AA2A")
.setTimestamp();
Expand All @@ -106,32 +56,5 @@ export default {
embeds: [playlistEmbed]
})
.catch(console.error);

if (!serverQueue) {
message.client.queue.set(message.guild.id, queueConstruct);

try {
queueConstruct.player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Pause
}
});

queueConstruct.connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator
});

play(queueConstruct.songs[0], message);
} catch (error) {
console.error(error);
message.client.queue.delete(message.guild.id);

getVoiceConnection(channel.guild.id).destroy();

return message.reply(i18n.__mf("play.cantJoinChannel", { error: error })).catch(console.error);
}
}
}
};
2 changes: 1 addition & 1 deletion commands/skip.js
Expand Up @@ -11,7 +11,7 @@ export default {
if (!queue) return message.reply(i18n.__("skip.errorNotQueue")).catch(console.error);
if (!canModifyQueue(message.member)) return i18n.__("common.errorNotChannel");

queue.player.stop();
queue.player.stop(true);

queue.textChannel.send(i18n.__mf("skip.result", { author: message.author })).catch(console.error);
}
Expand Down

0 comments on commit 3d57a80

Please sign in to comment.