如何不使用ctx实现Discord机器人音频播放功能
解决方法
你报错的核心原因是message对象本身不直接挂载voice_client属性,命令框架中的ctx.voice_client是框架封装的、从当前交互所属服务器(guild)提取语音客户端的逻辑,你基于on_message开发时手动提取该对象即可,无需引入命令框架。
修改后的完整代码如下:
async def playnext(self, message): # 过滤私聊消息场景 if not message.guild: await message.channel.send("该功能仅可在Discord服务器中使用") return # 手动从服务器对象获取语音客户端,等价于ctx.voice_client voice_client = message.guild.voice_client # 队列空校验 if not self.songQ: await message.channel.send("Queue is empty") return # 语音连接状态校验,避免空指针报错 if not voice_client or not voice_client.is_connected(): await message.channel.send("机器人未加入任何语音频道") return self.nuses += 1 voice_client.play( discord.PCMVolumeTransformer( discord.FFmpegPCMAudio(pafy.new(self.songQ[0]).getbestaudio().url) ), after=lambda error: self.removeplay(message) )
额外注意事项
- 如果你需要让机器人同时在多个服务器正常运行,需要将
songQ按服务器ID做隔离存储,不要所有服务器共用同一个队列,避免出现串歌、队列混乱的问题。 - 确保运行环境已经正确安装FFmpeg并配置到系统环境变量中,否则调用
FFmpegPCMAudio时会触发额外报错。 - 建议给
after回调的removeplay方法增加异常捕获逻辑,避免单首歌曲播放出错时整个播放队列卡住。
内容的提问来源于stack exchange,提问作者user15308825
相关产品推荐
相关产品推荐

