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

如何将协程用作闭包实现Discord音乐机器人队列功能?

解决Discord音乐机器人队列递归播放的问题

首先明确:disnake中VoiceClient.play()的after参数只接受同步函数,不能直接传入协程。要执行异步逻辑,需要在同步回调里通过机器人的事件循环创建异步任务。同时你的原代码存在队列重复添加的bug(同一首歌被append两次),下面是修正后的完整实现:

修改后的代码

async def play(self, inter: disnake.CmdInter, url):
    """Plays a song from a given YouTube URL."""
    async with inter.channel.typing():
        player = await YTDLSource.from_url(
            url, loop=self.bot.loop, stream=True
        )
        # 获取当前语音客户端
        voice_client = self.bot.voice_clients[0] if self.bot.voice_clients else None
        
        # 将歌曲信息存入队列(仅添加一次)
        self.queue.append({"channel": inter.channel, "player": player})
        
        if not voice_client or not voice_client.is_playing():
            # 无正在播放的歌曲,直接启动播放流程
            await self.play_next()
            await inter.send(f"Now playing: `{player.title}`")
        else:
            # 已有歌曲播放,提示队列位置
            queue_pos = len(self.queue)
            await inter.send(f"Added `{player.title}` to queue (Nr. {queue_pos})")

async def play_next(self):
    """递归播放队列中的下一首歌"""
    if not self.queue:
        # 队列为空,终止播放流程
        return
    
    # 取出队列首项歌曲
    next_song = self.queue.pop(0)
    channel = next_song["channel"]
    player = next_song["player"]
    
    def after_playing(error):
        # 同步回调函数,通过事件循环启动异步的下一首播放
        if error:
            print(f"播放出错: {error}")
        self.bot.loop.create_task(self.play_next())
    
    # 启动播放并绑定结束回调
    self.bot.voice_clients[0].play(player, after=after_playing)
    # 发送当前播放提示
    await channel.send(f"Now playing: `{player.title}`")

关键说明

  1. 队列结构优化:将原有的[频道, URL]结构改为存储已解析的player对象,避免重复解析同一URL,提升性能。
  2. 修复重复添加bug:原代码中try和except块均执行了append操作,导致同一首歌被加入队列两次,现在调整为仅添加一次。
  3. 同步回调转异步逻辑:after_playing是同步函数,通过self.bot.loop.create_task()将异步的play_next()包装成可在同步环境中执行的任务,实现递归播放。
  4. 基础错误处理:回调中加入错误打印,方便排查播放过程中的异常问题。

内容的提问来源于stack exchange,提问作者Asgard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:15:57