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

Discord.py机器人无法播放音频问题求助

Discord机器人播放音效问题修复

核心问题分析

你的noor命令存在两个关键问题:

  1. 错误使用await调用vc.play():play()方法不是异步协程,不需要加await,加了反而会导致代码卡住,因为它不会返回可等待对象。
  2. 播放未完成就强制断开:即使播放启动成功,你紧接着调用disconnect(),机器人会直接断开语音频道,根本没机会播放音效。

另外代码缺少异常处理逻辑,比如用户不在语音频道时会触发报错,也没有对播放过程中的错误进行捕获。

修复方案

方案1:等待播放完成后自动断开(推荐)

利用vc.wait_until_ready()等待播放启动,再通过回调函数在播放结束后断开连接:

import discord
from discord.ext import commands
import logging
import asyncio

handler = logging.FileHandler(filename='abyssal_log.log', encoding='utf-8', mode='w')

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='/', intents=intents)
token = # Omitted

@bot.event
async def on_ready():
    print('Ready')

@bot.command()
async def hello(ctx):
    await ctx.send("Hello!")

@bot.command()
async def jabberjoin(ctx):
    await ctx.author.voice.channel.connect()
    print('Bot joined')

@bot.command()
async def jabberleave(ctx):
    await ctx.voice_client.disconnect()
    print('Bot left')

@bot.command()
async def noor(ctx):
    # 检查用户是否在语音频道
    if not ctx.author.voice:
        await ctx.send("你得先加入一个语音频道啊!")
        return
    
    # 处理已连接的情况
    vc = ctx.voice_client
    if not vc:
        vc = await ctx.author.voice.channel.connect()
    elif vc.is_playing():
        vc.stop()  # 停止当前播放的音频
    
    try:
        # 加载音频文件,确保路径正确
        source = discord.FFmpegPCMAudio('noor.mp3')
        # 播放完成后的回调函数,负责断开连接
        def after_playing(error):
            if error:
                print(f"播放出错:{error}")
            # 异步执行断开操作
            asyncio.run_coroutine_threadsafe(vc.disconnect(), bot.loop)
        
        vc.play(source, after=after_playing)
        await vc.wait_until_ready()  # 等待播放启动
        print('Noored')
    except Exception as e:
        print(f"音频加载/播放失败:{e}")
        await vc.disconnect()

bot.run(token, log_handler=handler)

方案2:固定时长等待(适合已知音效时长的场景)

如果你清楚noor.mp3的准确时长,可以直接用asyncio.sleep()等待对应时间后断开:

@bot.command()
async def noor(ctx):
    if not ctx.author.voice:
        await ctx.send("请先加入语音频道!")
        return
    
    vc = await ctx.author.voice.channel.connect()
    try:
        source = discord.FFmpegPCMAudio('noor.mp3')
        vc.play(source)
        await vc.wait_until_ready()
        # 假设音效时长为3秒,根据实际时长调整
        await asyncio.sleep(3)
        await vc.disconnect()
        print('Noored')
    except Exception as e:
        print(f"出错:{e}")
        await vc.disconnect()

额外注意事项

  • 音频文件路径:确保noor.mp3和机器人脚本在同一目录,或者使用绝对路径(比如C:/bots/noor.mp3或/home/user/bots/noor.mp3)。
  • FFmpeg路径配置:若系统PATH未正确配置FFmpeg,可以在FFmpegPCMAudio中指定可执行文件路径:discord.FFmpegPCMAudio('noor.mp3', executable='C:/ffmpeg/bin/ffmpeg.exe')。
  • 权限检查:确认机器人拥有加入语音频道和发言的权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:33:11