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

如何在discord.py中使用wait_for()实现等待语音播放停止?

解决Discord机器人等待语音播放结束的问题

我完全理解你的需求——你想要阻塞式地等待语音播放结束后再执行后续操作,而不是用after回调直接跳转到指定逻辑。直接用bot.wait_for(voice.stop())肯定行不通,因为bot.wait_for()需要监听的是Discord的事件名称(比如'message'、'reaction_add'),而voice.stop()是主动停止播放的方法,根本不是一个事件。下面给你两种靠谱的解决方案:

方案一:用asyncio.Event实现优雅等待(推荐)

这个方法其实会用到after回调,但只是用它来触发一个“播放结束”的信号,后续逻辑依然在主协程里按顺序执行,完美符合你的需求:

import asyncio
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

@bot.command()
async def play(ctx, audio_url):
    # 连接到用户的语音频道
    if not ctx.author.voice:
        return await ctx.send("你得先加入一个语音频道呀!")
    voice_channel = ctx.author.voice.channel
    voice = await voice_channel.connect()

    # 创建一个事件对象,用来标记播放状态
    play_finished = asyncio.Event()

    def on_play_end(error):
        # 不管播放成功还是出错,都触发事件
        play_finished.set()
        # 可选:播放结束后自动断开连接(也可以放到主协程里做)
        if voice.is_connected():
            asyncio.create_task(voice.disconnect())

    # 开始播放,用after回调触发结束事件
    voice.play(discord.FFmpegPCMAudio(audio_url), after=on_play_end)

    # 在这里阻塞,直到播放结束
    await play_finished.wait()

    # 播放结束后,执行你想要的任何操作
    await ctx.send("🎵 播放结束!现在可以执行后续步骤啦~")

bot.run("你的机器人Token")

这个方案的优点:

  • 不会阻塞事件循环,wait()是异步等待,机器人在等待期间依然能响应其他命令
  • 能处理播放出错的情况(比如音频文件损坏),避免主协程一直挂起
  • 逻辑清晰,主协程的流程是线性的,比嵌套在after里好维护

方案二:轮询检查播放状态(不推荐但简单)

如果你完全不想碰after回调,可以用轮询的方式定期检查voice.is_playing()状态,但这种方法不够优雅,而且如果播放意外中断(比如机器人被踢出频道),可能会导致循环卡住:

@bot.command()
async def play(ctx, audio_url):
    if not ctx.author.voice:
        return await ctx.send("先加入语音频道哦!")
    voice_channel = ctx.author.voice.channel
    voice = await voice_channel.connect()

    voice.play(discord.FFmpegPCMAudio(audio_url))

    # 每秒检查一次是否还在播放
    while voice.is_playing():
        await asyncio.sleep(1)

    # 播放结束后的操作
    await ctx.send("🎵 播放结束!")
    await voice.disconnect()

注意事项

  • 不管用哪种方法,都要确保处理语音连接的异常情况(比如用户中途离开频道、机器人失去连接)
  • 如果你的机器人需要处理多个播放任务,记得每个任务用独立的asyncio.Event对象,避免信号混乱

内容的提问来源于stack exchange,提问作者Sathvik K S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:07:42