Discord音乐机器人play命令自动入队问题:无法批量添加歌曲
Discord音乐机器人批量加歌队列卡顿问题修复
你的代码核心问题出在play_queue的递归实现和play命令的触发逻辑上:
- 递归调用
play_queue会阻塞Discord.py的事件循环,导致新的play命令无法被处理,自然没法批量添加歌曲。 - 每次用户发送
play命令都会直接触发play_queue,会重复弹出队列元素,造成逻辑冲突。
修正后的代码实现
首先重写播放逻辑,用voice_client.play的after回调替代递归:
async def play_next(self, ctx: discord.ext.commands.context.Context): if not self.queue: return # 获取下一首音频资源 audio = await self.get_audio(self.queue.pop(0)) vc = ctx.voice_client # 定义播放完成后的回调函数 def after_playing(error): if error: print(f"播放出错: {error}") # 在事件循环中启动下一首播放 self.bot.loop.create_task(self.play_next(ctx)) # 开始播放并绑定回调 vc.play(audio, after=after_playing) await self.send_playing(ctx)
然后修改play命令,仅在当前无播放任务时启动播放流程:
@commands.command(name="play", pass_ctx=True) async def play(self, ctx: discord.ext.commands.context.Context, url=""): await self.handle_connected(ctx) self.queue.append(url) vc = ctx.voice_client if not vc.is_playing(): # 当前无播放,启动播放流程 await self.play_next(ctx) else: # 已在播放,发送队列提示 await ctx.send(f"已将歌曲加入队列,当前队列长度: {len(self.queue)}")
关键改动说明
- 用
after回调替代递归:vc.play的after参数会在当前音频播放完毕后自动触发,此时再处理下一首,不会阻塞事件循环,新的play命令能正常被接收处理。 - 拆分职责:
play命令只负责添加歌曲到队列,仅在无播放任务时启动播放流程,避免重复触发播放逻辑导致队列元素被错误弹出。 - 异步安全处理:通过
bot.loop.create_task确保回调中的异步操作在事件循环中执行,避免线程问题。
内容的提问来源于stack exchange,提问作者Noft
相关产品推荐
相关产品推荐

