【发布时间】:2021-03-26 08:20:36
【问题描述】:
我有一个 Discord 机器人,我希望它播放本地音乐。虽然只用一个文件就可以了,但当我尝试播放更多歌曲时,一切都崩溃了。
client.on('voiceStateUpdate', ((oldState, newState) => { //Call it when a user enter a voice channel
if (!oldState.channel && newState.member.user !== bot) { //Discard the bot
if (newState.channelID === l5r_roleplay.id) { //If it's the right vocal channel do things
counter++; //Counter is use to check when start playing music and when everyone has left. Basically is a counter for the active members inside the vocal channel
if (counter === 1) { //It starts playing music when the first member join the vocal channel
l5r_roleplay.join().then(connection => {
let i = 0;
shuffle(music_array); //Function to shuffle array
console.log("Now playing: " + music_array[i])
connection.play(music_array[i], {volume: 0.2});
});
}
}
} else if (!newState.channel && oldState.member.user !== bot) { //Someone left
if (oldState.channelID === l5r_roleplay.id) {
counter--;
if (counter < 0) counter = 0;
if (counter === 0) {
l5r_roleplay.leave();
}
}
}
}));
上面的代码是有效的,因为它只播放第一首歌曲(music_array 是一个字符串数组,其中每个字符串都是歌曲名称(+路径))
我想让它一个接一个地播放数组中的所有歌曲。
我尝试将它放在 for 循环、while 循环和外部函数中。我还尝试使用返回的 StreamDispatcher 来处理歌曲何时结束并增加处理程序中的循环/while 变量,但没有。
行为很简单。如果我放一个循环,它只会在控制台中打印,而不会播放歌曲。
一个带有简单 for 循环、调度程序和控制台输出的示例
for (let i = 0; i < music_array.length;) {
console.log("Now playing: " + music_array[i])
const dispatcher = connection.play(music_array[i], {volume: 0.2})
dispatcher.on('speaking', value => {
if (!value) i++
})
}
输出:
[nodemon] starting `node index.js`
---- < Online e operativo >
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
Now playing: ./backbone/l5r/music/The Samurai's Virtue.mp3
【问题讨论】:
-
dispatcher.on()是一种非阻塞方法,这意味着它不会延迟for循环执行的每次迭代。这意味着循环将重复数百次并每次都保持在i = 0,直到机器人开始/停止说话(并且机器人只会在几秒钟后这样做,给循环足够的时间来执行数百次而@ 987654327@ 仍为 0)。虽然这在技术上并不是一个无限循环,但它同样会出现问题,因为它会尝试播放同一首歌曲多少次。您肯定需要使用递归循环。 -
所以没有音乐播放的原因是因为循环试图在几毫秒内播放数百次“武士的美德”。在机器人停止说话之前,它不会停止尝试这样做。但因为它一直触发歌曲播放,歌曲每次都从头开始,所以机器人也可能永远无法停止说话。如果是这样的话,这确实是一个无限循环。如果不是这样,关于这个问题,这个循环仍然可以被视为一个无限循环。如前所述,递归循环将能够解决这个问题,并且是最好的解决方案。
标签: node.js discord discord.js audio-player playlist