discord.js开发Discord音乐机器人 实现指定次数运行命令添加歌曲
实现修改方案
参数逻辑调整
首先在语音频道校验逻辑后添加参数处理代码,校验用户输入的添加数量合法性,设置单次添加上限避免滥用,无参数时默认添加1首。
逻辑封装
将单次获取随机歌曲、添加到队列的逻辑封装为独立函数,方便循环调用。
队列逻辑调整
仅在队列不存在的首次调用时初始化播放队列、执行加入语音频道和播放逻辑,后续循环添加的歌曲直接推入队列即可。
完整修改后代码
run: async function (client, message, args) { let channel = message.member.voice.channel; if (!channel) return sendError("你需要先加入语音频道才能使用播放命令!", message.channel); // 参数处理 const MAX_ADD_COUNT = 10; // 单次最多添加10首,可自行调整数值 let addCount = 1; if (args[0]) { const inputNum = parseInt(args[0]); if (isNaN(inputNum) || inputNum < 1) { return sendError("请输入有效的正整数作为参数,示例:`!command 4`", message.channel); } addCount = Math.min(inputNum, MAX_ADD_COUNT); } const lofiSongs = ["listen before i go billie","Billie Eilish ~ No Time To Die Slowed to Perfection","Billie Eilish - Six Feet Under ","Chelsea Cutler - Crazier Things","All Kids Are Depressed (Slowed to Perfection)","Close To You- The Carpenters (ukulele cover) | Reneé Dominique","the hills || slowed","Powfu - Death Bed (Slowed To Perfection)","maroon 5 - memories (slowed + reverb)","Ashe - Moral Of The Story (Slowed + Lyrics)","Olivia Rodrigo - traitor (Lyrics)","kina - can we kiss forever [slowed + reverb]","Claire Rosinkranz - Backyard Boy (Lyrics)","comethru - jeremy zucker cover by kimswizzled","[DOXTAPE] Maddox(마독스) - At My Worst (Pink Sweat$ Cover)","Be Alright by Dean Lewis | acoustic cover by Jada Facer","The One That Got Away by Katy Perry | cover by Jada Facer","Let Her Go - Passenger (Official Video Cover by Jasmine Thompson)","Can't Help Falling In Love | Elvis Presley (cover)","IT'S YOU - ALI GATIE[slowed + reverb]starmilk","All Kids Are Depressed (Slowed to Perfection)","billie eilish khalid - lovely","Duncan Laurence - Arcade","yellow","Heartbreak Anniversary","dancing with your ghout","heater tate macrae","hold on","watch billie eilish","martin and gina slowed reverb","Kali Uchis - telepatía (Cover by Lesha)","leaving on a jet plane macarone project","fly me to the moon yungrythm","close to you renee dominnique","blue moon jaritenph remix","run away","let me down slowely","little do you know","gnash feat. Olivia o'brien - I hate u, I love u (Consoul Trainin Remix)","ocaen eyes","hostage","remendy of broken heart","jocelyn floers","CKay - Love Nwantiti (Acoustic Version)","Tate McRae - friends don’t look at friends that way"]; var serverQueue = message.client.queue.get(message.guild.id); // 封装获取随机歌曲逻辑 const getRandomSong = async () => { const randomLofi = lofiSongs[Math.floor(Math.random() * lofiSongs.length)]; const searched = await yts.search(randomLofi); const songInfo = searched.videos[0]; return { id: songInfo.videoId, title: Util.escapeMarkdown(songInfo.title), views: String(songInfo.views).padStart(10, " "), url: songInfo.url, ago: songInfo.ago, img: songInfo.image, req: message.author, duration: songInfo.duration }; } // 封装播放逻辑 const play = async (song) => { const queue = message.client.queue.get(message.guild.id); if (!song) { message.client.queue.delete(message.guild.id); return; } let stream = null; if (song.url.includes("youtube.com")) { stream = await ytdl(song.url); stream.on("error", function (er) { if (er) { if (queue) { queue.songs.shift(); play(queue.songs[0]); return sendError(`播放发生意外错误,错误类型:\`${er}\``, message.channel); } } }); } queue.connection.on("disconnect", () => message.client.queue.delete(message.guild.id)); const dispatcher = queue.connection.play(ytdl(song.url, { quality: "highestaudio", highWaterMark: 1 << 25, type: "opus" })).on("finish", () => { const shiffed = queue.songs.shift(); if (queue.loop === false) { queue.songs.push(shiffed); } play(queue.songs[0]); }); dispatcher.setVolumeLogarithmic(queue.volume / 100); let thing = new MessageEmbed() .setAuthor("PussyMusic 开始播放") .setImage(song.img) .setColor("#fffdd0") .addField("歌曲名称", song.title, true) .addField("播放量", song.views, true) .addField("请求人", song.req.tag, true) .setFooter(`PussyMusic`); queue.textChannel.send(thing); }; // 循环添加指定数量的歌曲 const addedSongs = []; for (let i = 0; i < addCount; i++) { const song = await getRandomSong(); addedSongs.push(song); if (serverQueue) { serverQueue.songs.push(song); } else { // 首次添加无队列时初始化队列 const queueConstruct = { textChannel: message.channel, voiceChannel: channel, connection: null, songs: [], volume: 80, playing: true, loop: true, }; message.client.queue.set(message.guild.id, queueConstruct); queueConstruct.songs.push(song); serverQueue = queueConstruct; } } // 如果是首次初始化队列,执行加入频道播放逻辑 if (serverQueue.songs.length === addedSongs.length) { try { const connection = await channel.join(); serverQueue.connection = connection; play(serverQueue.songs[0]); } catch (error) { console.error(`无法加入语音频道: ${error}`); message.client.queue.delete(message.guild.id); await channel.leave(); return sendError(`无法加入语音频道: ${error}`, message.channel); } } // 发送添加成功提示 let successEmbed = new MessageEmbed() .setAuthor("歌曲已添加到队列") .setColor("#fffdd0") .setDescription(`成功添加 ${addCount} 首lofi歌曲到播放队列`) .setFooter(`如需单首播放提示可自行修改本部分逻辑`); return message.channel.send(successEmbed); }
注意事项
- 可自行修改
MAX_ADD_COUNT的数值调整单次最大添加数量 - 代码删除了你原来冗余的URL匹配逻辑(你原本的逻辑就是固定搜索随机歌曲,该逻辑无实际作用)
- 如果你需要每添加一首歌曲就发送一次提示,可将提示逻辑移到循环内的
serverQueue.songs.push(song)之后
内容的提问来源于stack exchange,提问作者Commander1An
相关产品推荐
相关产品推荐

