You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:54:23