Discord.js声音,玩家完成事件



我正在尝试学习discord.js,所以我想学习音乐机器人是如何工作的。下面的代码是我的镜头和一切工作,但我有一个问题与我的队列。

我找不到播放器。在"finish"或";以何种;事件。因此,当歌曲结束时,我想调用播放歌曲的递归方法,但我不知道如何获得正确的事件。

我试过使用player.on(AudioPlayerStatus.Idle)事件并从中做出一些东西,但效果不太好。

如果有人对我做错了什么或如何改进下面的代码有任何建议,我将不胜感激。

const queue = new Map();
module.exports = {
name: "play",
aliases: ["skip", "stop", "leave"],
async execute(message, args, cmd, client, Discord) {
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) {
return message.channel.send({
content: "You need to be in a channel to execute this command!",
});
}
const permissions = voiceChannel.permissionsFor(message.member);
if (!(permissions.has('CONNECT')) || !(permissions.has('SPEAK'))) {
return message.channel.send({
content: "You don't have the correct permissions!",
});
}
const serverQueue = queue.get(message.guild.id);
if (cmd == "play") {
if (!(args.length)) {
return message.channel.send({
content: "Invalid song link!",
});
}
let song = {};
if (ytdl.validateURL(args[0])) {
const songInfo = await ytdl.getInfo(args[0]);
song = { title: songInfo.videoDetails.title, url: songInfo.videoDetails.video_url }
} else {
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) {
song = { title: video.title, url: video.url }
} else {
message.channel.send({
content: `No video results found!`
})
}
}
if (!(serverQueue)) {
const queueConstructor = {
voiceChannel: voiceChannel,
textChannel: message.channel,
connection: null,
player: null,
songs: [],
}
queue.set(message.guild.id, queueConstructor);
queueConstructor.songs.push(song);
try {
const connection = await joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.member.voice.channel.guild.id,
adapterCreator: message.member.voice.channel.guild.voiceAdapterCreator,
});
queueConstructor.connection = connection;
const player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Pause
}
});
queueConstructor.player = player;
videoPlayer(message.guild, queueConstructor.songs[0]);
} catch (error) {
queue.delete(message.guild.id);
message.channel.send({
content: `There was an error connecting!`
})
throw error;
}
} else {
serverQueue.songs.push(song);
console.log(serverQueue.songs);
return message.channel.send({
content: `${song.title} added to the queue!`
})
}
} else if (cmd == "skip") {
// TODO
} else if (cmd == "leave") {
// TODO
}
}
}
const videoPlayer = async (guild, song) => {
const songQueue = queue.get(guild.id);
if (!(song)) {
songQueue.player.stop();
songQueue.connection.destroy();
queue.delete(guild.id);
return;
}
const stream = await ytdl(song.url, { filter: "audioonly" });
const songStream = await (createAudioResource(stream));
const subscription = songQueue.connection.subscribe(songQueue.player);
const dispatcher = songQueue.player.play(createAudioResource(stream)).on("finish", () => {
songQueue.songs.shift();
songQueue.playing = false;
videoPlayer(guild, songQueue.songs[0]);
songQueue.textChannel.send({
content: `Now playing: ${song.title}`
});
});
}
player.addListener("stateChange", (oldOne, newOne) => {
if (newOne.status == "idle") {
console.log("The song finished");
}
});

使用事件stateChange。当语音状态从oldOne变为newOne时调用。(例如:玩->
newOne{ status: "playing | idle | buffering | ..." }

最新更新