我在Discord Bot上有一个Looping命令,您可以在其中重复在语音通道中播放歌曲。尽管当我运行命令时,它会显示一条消息,提示它会循环播放当前歌曲:
但是,当歌曲结束时(应该再次重复播放),机器人将与语音通道断开连接。它使用YTDL-Core。关于如何解决这个任何想法? Repeat.JS
let { RichEmbed } = require('discord.js')
const config = require('../../config.json')
exports.run = async(client, msg, args) => {
const serverQueue = client.queue.get(msg.guild.id);
if (!msg.member.voiceChannel) return msg.channel.send('You are not in a voice channel!');
if(!serverQueue) return msg.channel.send('Not playing anything right now');
if(serverQueue.voiceChannel.id !== msg.member.voiceChannel.id) return msg.channel.send(`You must be in **${serverQueue.voiceChannel.name}** to loop the queue`);
serverQueue.loop = !serverQueue.loop;
client.queue.set(msg.guild.id, serverQueue);
if(serverQueue.loop) return msg.channel.send('** Repeated current queue!**');
return msg.channel.send('** Unrepeated current queue!**');
}
exports.conf = {
aliases: ['loop'],
cooldown: "3"
}
exports.help = {
name: "repeat",
description: "Repeat the queue",
usage: "repeat"
}
Queue.JS
const { RichEmbed } = require('discord.js');
const { chunk } = require('../../util.js');
exports.run = async (client, msg, args) => {
try{
const serverQueue = client.queue.get(msg.guild.id);
if(!serverQueue) return msg.channel.send('**Music |** There is no music playing!\n\nPlay some music with **n!play <YouTube URL>** or **n!play <word>**.');
let queues = [];
serverQueue.songs.forEach((x, i) => {
if(i !== 0){
queues.push(x);
}
});
const embed = new RichEmbed()
.setColor('0xd677ff');
if(!queues || queues.length < 1) return msg.channel.send(`**Music |** **Now playing »** **${serverQueue.songs[0].title}**`, {embed: embed.setDescription('**Music |** **There are no songs in the queue**')});
if(queues.length > 10){
let index = 0;
queues = queues.map((x, i) => `\`${i +1}\`. __**[${x.title}](${x.url})**__ **by** *${msg.author.username}*`);
queues = chunk(queues, 10);
embed.setAuthor('Music ', 'https://i.imgur.com/s6OpKNC.jpg')
embed.setDescription(queues[index].join('\n'));
embed.setFooter(`Page ${index+1} of ${queues.length}`);
const queuesMess = await msg.channel.send(`**Music |** **Now playing »** ${serverQueue.songs[0].title}`, {embed: embed});
await queuesMess.react('⬅');
await queuesMess.react('');
await queuesMess.react('➡');
awaitReactions();
function awaitReactions(){
const filter = (rect, usr)=> ['⬅', '➡'].includes(rect.emoji.name) && usr.id === msg.author.id;
queuesMess.createReactionCollector(filter, {time: 30000, max: 1})
.on('collect', col => {
if(col.emoji.name === '') return queuesMess.delete();
if(col.emoji.name === '⬅') index--;
if(col.emoji.name === '➡') index++;
index = ((index % queues.length) + queues.length) % queues.length;
embed.setAuthor('Music ', 'https://i.imgur.com/s6OpKNC.jpg')
embed.setDescription(queues[index].join('\n'));
embed.setFooter(`Page ${index+1} of ${queues.length}`);
queuesMess.edit(`**Music |** **Now playing »** ${serverQueue.songs[0].title}`, {embed: embed});
return awaitReactions();
});
}
}else{
embed.setDescription(queues.map((x, i) => `\`${i +1}\`. __**[${x.title}](${x.url})**__ **by** *${msg.author.username}*`).join('\n'));
return msg.channel.send(`**Music |** **Now playing »** ${serverQueue.songs[0].title}`, {embed: embed});
}
}catch(e){
return msg.channel.send(`**Music |** **Error Occured** :( \`\`\`${e.stack}\`\`\`try again later`);
}
}
exports.conf = {
aliases: [],
cooldown: "3"
}
exports.help = {
name: "queue",
description: "Show music queue in this server",
usage: "queue"
}
Main.JS
const Discord = require('discord.js')
const YouTube = require('simple-youtube-api');
const ytdl = require('ytdl-core');
const queue = new Map();
const client = new Discord.Client({disableEveryone: true});
const api = require("./app");
const fs = require('fs' );
let config = require('./config.json');
var servers = {};
let prefix = config.prefix;
const youtube = new YouTube(config.youtube_api);
const {Util, RichEmbed } = require('discord.js')
const stations = require('./stations.json')
const SBL = require("spacebots");
const DiscordBotListAPI = require('dbl-api');
const DBL = require("dblapi.js");
const dbl = new DBL('DBL CODE',client);
const Owner = config.Owner;
const util = require('./util.js')
const { get } = require('node-superfetch');
const { load } = require('cheerio');
const number = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣'];
var guild = {};
client.config = config;
client.util = util
client.queue = queue
client.on("ready", () => {
console.log(`Starting Nate Bot Version » 5.0`)
})
client.config = config;
fs.readdir("./events/", (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
const event = require(`./events/${file}`);
let eventName = file.split(".")[0];
client.on(eventName, event.bind(null, client));
});
});
client.commands = new Discord.Collection();
fs.readdir('./commands/', (err, categories) => {
if (err) console.log(err);
console.log(`NateBot » Found total ${categories.length} category.`);
categories.forEach(category => {
fs.readdir(`./commands/${category}`, (err, files) => {
console.log(`NateBot » Found total ${files.length} command from ${category}.`)
if (err) console.log(err);
let commands = new Array();
files.forEach(file => {
//delete require.cache[require.resolve(`./commands/${category}/${file}`)];
if (!file.endsWith('.js')) return;
let prop = require(`./commands/${category}/${file}`);
let cmdName = file.split('.')[0];
client.commands.set(cmdName, prop)
})
})
})
})
/*
fs.readdir("./commands/admin/", (err, files) =>{
if(err) return console.error(err);
files.forEach(file => {
if(!file.endsWith(".js")) return;
let props = require(`./commands/admin/${file}`);
let commandName = file.split(".")[0];
client.commands.set(commandName, props);
});
});*/
exports.handleVideo = handleVideo
exports.queue = queue;
exports.youtube = youtube;
exports.queue = queue
exports.youtube = youtube;
exports.ytdl = ytdl;
exports.guild = guild;
exports.config = config;
client.on("message", async message =>{
if(message.author.bot) return;
if(message.channel.type === "dm") return;
var args2 = message.content.substring(config.prefix.length).split(" ");
if (!message.content.startsWith(config.prefix)) return;
var searchString = args2.slice(0).join(' ');
var url = args2[1] ? args2[1].replace(/<(.+)>/g, '$1') : '';
var serverQueue = queue.get(message.guild.id);
switch (args2[0].toLowerCase()) {
case "skip":
if (!message.member.voiceChannel) return message.channel.send(' **Music |** You must connect to a Voice Channel.');
if (!serverQueue) return message.channel.send('**Music |** There is no music playing!\n\nPlay some music with **n!play <YouTube URL>** or **n!play <word>**.');
serverQueue.connection.dispatcher.end('NateBot » Skip command has been used!');
const embed = new Discord.RichEmbed()
.setColor('#0xa8a8a8')
.setAuthor('Music ', 'https://i.imgur.com/Fm1edxi.png')
.setDescription('Song Successfully Skipped ⏩')
message.channel.send({embed});
return undefined;
break;
case "np":
if (!serverQueue) return message.channel.send('**Music |** There is no music playing!\n\nPlay some music with **n!play <YouTube URL>** or **n!play <word>**.');
let nowplayingemb = new Discord.RichEmbed()
.setColor('#0x76d6ff')
.setAuthor('Music ', 'https://i.imgur.com/Fm1edxi.png')
.setThumbnail("https://thumbs.gfycat.com/UnkemptWhiteKakapo-small.gif")
.setDescription('**Now Playing** ')
.addField('Song Name', `**${serverQueue.songs[0].title}**`, true)
return message.channel.send(nowplayingemb);
break;
case "queue":
if (!serverQueue) return message.channel.send('**Music |** There is no music playing right now!\n\nPlay some music with **n!play <YouTube URL>** or **n!play <word>**.');
let queueemb = new Discord.RichEmbed()
.setAuthor('Music ', 'https://i.imgur.com/s6OpKNC.jpg')
.setTitle(`**Queue for ${message.guild.name}**`)
.setDescription(`${serverQueue.songs.map(song => `**»** [${song.title}](https://www.youtube.com/watch?v=${song.id}})`).join('\n')}`)
.setColor(`0xd677ff`)
return message.channel.send(queueemb)
break;
case "leave":
if (!message.member.voiceChannel) return message.channel.send('**Music |** You must connect to a Voice Channel.');
let stopemb = new Discord.RichEmbed()
.setColor(0xff7777)
.setAuthor(`Music `, 'https://i.imgur.com/Fm1edxi.png')
.setDescription("Successfully Disconnected... ❌");
message.guild.me.voiceChannel.leave();
return message.channel.send(stopemb)
break;
}
})
async function handleVideo(video, message, voiceChannel, playlist = false) {
var serverQueue = queue.get(message.guild.id);
// console.log(video);
var song = {
id: video.id,
title: video.title,
url: `https://www.youtube.com/watch?v=${video.id}`,
channel: video.channel.title,
durationm: video.duration.minutes,
durations: video.duration.seconds,
durationh: video.duration.hours,
publishedAt: video.publishedAt,
};
if (!serverQueue) {
var queueConstruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true,
loop: true
};
queue.set(message.guild.id, queueConstruct);
queueConstruct.songs.push(song);
try {
var connection = await voiceChannel.join();
var listener = await voiceChannel.join();
connection.on('error', console.error);
queueConstruct.connection = connection;
play(message.guild, queueConstruct.songs[0]);
} catch (error) {
queue.delete(message.guild.id);
return message.channel.send(`**Music |** **Error Occured** ${error}`);
}
} else {
serverQueue.songs.push(song);
//console.log(serverQueue.songs);
if (playlist) return undefined;
let queueemb = new Discord.RichEmbed()
.setAuthor('Music ', 'https://i.imgur.com/s6OpKNC.jpg')
.setTitle(`**Song Successfully Queued!** `)
.setColor(`#0xd677ff`)
.addField(`**Uploader**`, `${song.channel}`, true)
.addField(`**Video ID**`, song.id , true)
.setFooter(`Published » ${song.publishedAt}`)
.addField(`**Duration**`, `**\`${song.durationh}\`** Hours, **\`${song.durationm}\`** Minutes and **\`${song.durations}\`** Seconds`, true)
.setDescription(`[${song.title}](https://www.youtube.com/watch?v=${song.id}})`)
.setThumbnail(`https://i.ytimg.com/vi/${song.id}/sddefault.jpg`)
.setColor(`0xd677ff`)
return message.channel.send(queueemb).then(msg => {
message.delete(10000)
})
}
return undefined;
}
function play(guild, song) {
var serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
//console.log(serverQueue.songs);
const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
.on('end', reason => {
if (reason === 'NateBot » Stream is not generating quickly enough.') console.log('NateBot » Song ended.');
else console.log(reason);
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on('error', error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
let playingemb = new Discord.RichEmbed()
.setAuthor('Music ', 'https://i.imgur.com/s6OpKNC.jpg')
.setTitle(`**Now Playing!** `)
.setColor(`0x76d6ff`)
.addField(`**Uploader**`, `${song.channel}`, true)
.addField(`**Video ID**`, song.id , true)
.setFooter(`Published » ${song.publishedAt}`)
.addField(`**Duration**`, `**\`${song.durationh}\`** Hours, **\`${song.durationm}\`** Minutes and **\`${song.durations}\`** Seconds`, true)
.setThumbnail(`https://i.ytimg.com/vi/${song.id}/sddefault.jpg`)
.setDescription(`[${song.title}](https://www.youtube.com/watch?v=${song.id}})`)
serverQueue.textChannel.send(playingemb);
}
// Optional events
dbl.on('posted', () => {
console.log('Server count posted!');
console.log('NateBot » Server count posted!');
})
client.login(config.Token);
dbl.on('error', e => {
console.log(`Oops! ${e}`);
console.log(`NateBot » Oops! ${e}`);
})
api.startApp(client);
client.login(config.Token);
谢谢
答案 0 :(得分:0)
尽管您正在设置队列的循环选项,但我看不到在其他任何地方使用它。使队列重复的一种简单解决方案是再次添加结束队列中的歌曲。例如...
if (serverQueue.loop === true) serverQueue.songs.push(serverQueue.songs.shift());
else serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
如果应该循环队列,上面的代码从数组的开头删除该元素,并将其添加到结尾。这样,它将继续按顺序重复播放歌曲。如果队列不应该循环播放,则只需删除第一首歌曲就可以了。