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

Discord机器人加入语音频道后程序停滞问题求助

Discord机器人!play命令连接语音频道后停滞的排查与修复

核心问题排查与修复步骤

1. 补全缺失的依赖模块

你的代码中使用了os、random、asyncio三个模块但未导入,这会导致执行到对应逻辑时抛出NameError,在异步环境下未捕获的异常会静默阻塞后续代码运行。

在代码开头添加导入语句:

import os
import random
import asyncio

2. 添加异常捕获,定位具体错误

在play命令函数中加入异常捕获,直接暴露执行过程中的错误,避免静默停滞:

@bot.command(name='play')
async def play(ctx):
    vc = None
    try:
        voice_channel = ctx.author.voice.channel
        vc = await voice_channel.connect()

        print('Connected')

        # 检查music目录是否存在
        if not os.path.exists('music'):
            await ctx.send("未找到music目录!")
            return

        # 随机选曲
        music_files = os.listdir('music')
        if not music_files:
            await ctx.send("music目录中无音频文件!")
            return
        random_song = os.path.join('music', random.choice(music_files))

        # 播放音频(指定FFmpeg路径如果系统未配置环境变量)
        vc.play(discord.FFmpegPCMAudio(random_song), after=lambda e: print('播放错误:', e) if e else None)
        await ctx.send(f'正在播放: {random_song}')

        # 等待播放结束
        while vc.is_playing():
            await asyncio.sleep(1)

        # 断开连接
        await vc.disconnect()
        await ctx.send(f'播放结束: {random_song}')
    except Exception as e:
        await ctx.send(f"命令执行出错:{str(e)}")
        print(f"错误详情:{str(e)}")
        if vc and vc.is_connected():
            await vc.disconnect()

3. 验证FFmpeg安装与可访问性

discord.FFmpegPCMAudio依赖系统安装的FFmpeg:

  • 确认已安装FFmpeg(Windows从官网下载,Linux用包管理器安装)
  • 若未将FFmpeg加入系统环境变量,需在代码中指定其路径:
vc.play(discord.FFmpegPCMAudio(executable="/usr/bin/ffmpeg", source=random_song), after=lambda e: print('播放错误:', e) if e else None)

(路径根据你的系统实际情况调整)

4. 优化语音连接与播放逻辑

  • 连接后短暂等待确保连接稳定:
vc = await voice_channel.connect()
await asyncio.sleep(0.5)  # 等待连接初始化完成
  • 替换循环等待为回调触发,避免阻塞事件循环:
    将原有的while循环等待逻辑改为通过after回调处理播放结束后的操作(注意回调为同步函数,需用事件循环创建异步任务):
@bot.command(name='play')
async def play(ctx):
    vc = None
    try:
        voice_channel = ctx.author.voice.channel
        vc = await voice_channel.connect()
        await asyncio.sleep(0.5)
        print('Connected')

        if not os.path.exists('music'):
            await ctx.send("未找到music目录!")
            await vc.disconnect()
            return

        music_files = os.listdir('music')
        if not music_files:
            await ctx.send("music目录中无音频文件!")
            await vc.disconnect()
            return
        random_song = os.path.join('music', random.choice(music_files))

        # 定义播放完成后的回调
        def after_playing(error):
            async def cleanup():
                if vc.is_connected():
                    await vc.disconnect()
                await ctx.send(f'播放结束: {random_song}')
                if error:
                    print(f"播放错误: {error}")
            # 用bot的事件循环执行异步清理逻辑
            bot.loop.create_task(cleanup())

        vc.play(discord.FFmpegPCMAudio(random_song), after=after_playing)
        await ctx.send(f'正在播放: {random_song}')

    except Exception as e:
        await ctx.send(f"命令执行出错:{str(e)}")
        print(f"错误详情:{str(e)}")
        if vc and vc.is_connected():
            await vc.disconnect()

5. 确认Discord开发者后台的Intents设置

虽然代码中使用了Intents().all(),但需确保Discord开发者后台中已开启Voice Members和Guilds相关权限,否则可能导致语音连接异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:05:01