Python开发Discord音乐机器人执行play命令报AttributeError故障求助
问题修复方案
错误根因
报错AttributeError: 'NoneType' object has no attribute 'stop'的核心原因是调用?play命令时,机器人未加入当前服务器的任何语音频道,此时ctx.voice_client返回空值,不存在stop方法可以调用。
修复步骤
1. 修正使用流程
必须先运行?join命令让机器人进入你所在的语音频道,再调用?play命令播放音乐,不要直接触发播放命令。
2. 给play命令增加前置校验逻辑
为了避免忘记调用join就触发播放的报错,可以直接在play命令开头增加自动校验、自动加入频道的逻辑,修改后的代码如下:
@commands.command() async def play(self,ctx,url): # 新增前置校验 if ctx.voice_client is None: if ctx.author.voice is None: await ctx.send("你需要先进入语音频道再使用播放命令") return # 自动加入用户所在语音频道 await ctx.author.voice.channel.connect() # 原有逻辑保留 ctx.voice_client.stop() FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'} YDL_OPTIONS = {'format': "bestaudio"} vc = ctx.voice_client with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl: info = ydl.extract_info(url, download=False) url2 = info['formats'][0]['url'] source = await discord.FFmpegOpusAudio.from_probe(url2,**FFMPEG_OPTIONS) vc.play(source)
注意这里同时修正了你原有FFMPEG配置的拼写错误:原参数名before_option是单数错误写法,正确写法为复数before_options,否则FFMPEG重连参数不会生效,会出现播放卡顿、中断的问题。
3. 给其他命令同步增加空值校验
其他涉及ctx.voice_client调用的命令(disconnect、pause、resume)都需要增加同样的空值校验,避免同类报错,示例如下:
@commands.command() async def disconnect(self,ctx): if ctx.voice_client is None: await ctx.send("机器人当前未加入任何语音频道") return await ctx.voice_client.disconnect() @commands.command() async def pause(self,ctx): if ctx.voice_client is None: await ctx.send("机器人当前未加入任何语音频道") return await ctx.voice_client.pause() await ctx.send("paused ") @commands.command() async def resume(self,ctx): if ctx.voice_client is None: await ctx.send("机器人当前未加入任何语音频道") return await ctx.voice_client.resume() await ctx.send("resume ")
优化建议
youtube_dl已经停止维护,对Youtube新的视频格式兼容性很差,建议替换为维护活跃的yt-dlp:
- 执行
pip install yt-dlp安装依赖 - 将music.py中的
import youtube_dl修改为import yt_dlp即可,其余调用逻辑无需改动。
内容的提问来源于stack exchange,提问作者Slopolot
相关产品推荐
相关产品推荐

