Discord.py音乐机器人被手动断开连接后无法播放音乐如何解决
discord.py音乐机器人手动断开后无法播放解决方案
问题根因
- 你当前使用的
on_disconnect事件不属于语音连接事件,是机器人整体与Discord网关断开时才会触发,且该事件本身没有ctx入参,你写的回调逻辑永远不会被触发。 - 手动从Discord客户端踢出机器人后,你本地存储的
voice_states缓存仍保留了过期的无效语音客户端实例,重连后播放逻辑调用的是旧实例,因此无法输出音频;而歌曲队列信息存储在你的voice_state对象中,因此now指令仍可正常读取展示。
修复步骤
- 替换错误的事件监听,改为监听
on_voice_state_update事件,检测机器人被手动断开的场景并清理缓存:
@bot.event async def on_voice_state_update(member, before, after): # 仅处理机器人自身的语音状态变更 if member.id != bot.user.id: return # 匹配「之前在语音频道、当前已退出频道」的场景 if before.channel is not None and after.channel is None: guild_id = before.channel.guild.id if guild_id in bot.voice_states: target_state = bot.voice_states[guild_id] if target_state.is_playing(): await target_state.stop() target_state.songs.clear() del bot.voice_states[guild_id]
- 优化
play指令的语音客户端校验逻辑,避免调用过期实例:
在你的原有play指令开头加入以下校验逻辑:
@bot.command(name='play') async def play(ctx, *, query): # 校验当前服务器语音客户端有效性 current_voice = ctx.guild.voice_client guild_id = ctx.guild.id # 缓存存在但实际语音客户端已断开,直接清理缓存 if guild_id in bot.voice_states and (current_voice is None or not current_voice.is_connected()): del bot.voice_states[guild_id] # 后续保留你原有加入频道、解析歌曲、播放的逻辑 # ...
- 可选补充:如果重连时仍有异常,可在加入频道的逻辑中增加旧连接清理步骤:
# 原有加入语音频道的逻辑替换为以下代码 current_voice = ctx.guild.voice_client user_channel = ctx.author.voice.channel if current_voice is None: current_voice = await user_channel.connect() else: if not current_voice.is_connected(): await current_voice.disconnect() current_voice = await user_channel.connect() elif current_voice.channel != user_channel: await current_voice.move_to(user_channel)
内容的提问来源于stack exchange,提问作者Vasiliy Peshko
相关产品推荐
相关产品推荐

