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

Discord.py音乐机器人被手动断开连接后无法播放音乐如何解决

discord.py音乐机器人手动断开后无法播放解决方案

问题根因

  • 你当前使用的on_disconnect事件不属于语音连接事件,是机器人整体与Discord网关断开时才会触发,且该事件本身没有ctx入参,你写的回调逻辑永远不会被触发。
  • 手动从Discord客户端踢出机器人后,你本地存储的voice_states缓存仍保留了过期的无效语音客户端实例,重连后播放逻辑调用的是旧实例,因此无法输出音频;而歌曲队列信息存储在你的voice_state对象中,因此now指令仍可正常读取展示。

修复步骤

  1. 替换错误的事件监听,改为监听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]
  1. 优化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]
    
    # 后续保留你原有加入频道、解析歌曲、播放的逻辑
    # ...
  1. 可选补充:如果重连时仍有异常,可在加入频道的逻辑中增加旧连接清理步骤:
# 原有加入语音频道的逻辑替换为以下代码
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:54:05