I'm an amateur and I have this music bot setup but not sure how to implement a queue feature which would add videos in an array to be played after one song is finished. Do I have to reformat the code so that there is a queue function before everything or is there a simple fix?
Below is my code,
module.exports = {
name: 'play',
description: 'Joins and plays video from youtube',
async execute(message, args) {
const voiceChannel = message.member.voice.channel;
if(!voiceChannel) return message.channel.send('Join a channel to play a song');
const permissions = voiceChannel.permissionsFor(message.client.user);
if(!permissions.has('CONNECT')) return message.channel.send('You dont have permission to use this function');
if(!permissions.has('SPEAK')) return message.channel.send('You dont have permission to use this function');
if(!args.length) return message.channel.send('You need to send a second argument');
//Set up play function for link
const validURL = (str) =>{
var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
if(!regex.test(str)){
return false;
} else {
return true;
}
}
if(validURL(args[0])){
const connection = await voiceChannel.join();
const stream = ytdl(args[0], {filter: 'audioonly'});
connection.play(stream, {seek: 0, volume: 1})
.on('finish', () =>{
voiceChannel.leave();
message.channel.send('Leaving Channel!');
});
await message.reply('Now Playing Link')
return
}
//Set up play function for youtube search w/ keywords
const connection = await voiceChannel.join();
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > 1)? videoResult.videos[0] : null;
}
const video = await videoFinder(args.join(' '));
if(video){
const stream = ytdl(video.url, {filter: 'audioonly'});
connection.play(stream, {seek: 0, volume: 1})
.on('finish', () =>{
voiceChannel.leave();
});
await message.reply(`Now Playing ***${video.title}*** ${video.duration}*** ${video.thumbnail}`)
} else {
message.channel.send('No video results found.');
}
}
}
module.exports = {
name: 'play',
description: 'Joins and plays video from youtube',
queues: {},
voiceConnections: {},
execute() {
if (!this.voiceConnections[guildId]) {
// setup voiceConnections[guildId]
this.voiceConnections[guildId].on('finish', () => {
this.voiceConnections[guildId].play(this.queues[guildId].pop())
}
}
if (track already playing in voice connection) {
this.queues[guildId].push(newTrackDetails);
} else {
// play the track
}
}
}
Some pseudocode. Idea: Each guild has its own queue and voice channel connection. The queue object format looks something like {'guildId1': [...queue tracks details here]}