discord.py中FFmpeg播放器播放完成后自动退出的实现问题
解决Discord机器人FFmpeg Player的after参数错误与非循环状态检测问题
看起来你遇到了Discord.py音效机器人开发里的两个常见问题,我来一步步帮你梳理解决方案:
一、修复after=voice_client.disconnect()的TypeError问题
你触发错误的核心原因有两点:
- 你直接写了
voice_client.disconnect(),这会立刻执行断开连接的操作,而不是把函数本身传递给after参数——after需要的是一个可调用的函数对象,而非函数执行后的返回值。 create_ffmpeg_player的after回调会自动传入一个参数(播放出错时是错误对象,播放完成则为None),但voice_client.disconnect()不需要任何参数,因此出现了“参数数量不匹配”的报错。
正确写法有两种:
1. Lambda表达式包装(简单场景推荐)
用lambda忽略回调传递的参数,直接调用断开连接方法:
soundboard_player = voice_client.create_ffmpeg_player("doh.mp3", after=lambda error: voice_client.disconnect()) soundboard_player.start() await client.send_message(message.channel, "Playing DOH...")
2. 自定义回调函数(适合需要错误处理的场景)
如果想捕获播放过程中的错误,可以单独写一个处理函数:
def handle_play_finish(error): if error: print(f"播放音效时出现错误: {error}") # 无论是否出错,播放完成后断开连接 voice_client.disconnect() soundboard_player = voice_client.create_ffmpeg_player("doh.mp3", after=handle_play_finish) soundboard_player.start() await client.send_message(message.channel, "Playing DOH...")
二、非循环式的播放状态检测与手动停止方案
你提到用is_done()会陷入循环、无法响应STOP命令——其实完全不需要用循环检测状态,我们可以结合全局变量保存播放器实例和独立的STOP命令来实现手动终止,同时用after回调处理自动断开逻辑。
示例代码:
# 全局变量保存当前正在播放的播放器实例 current_player = None # 播放音效的命令 @client.command() async def play_doh(ctx): global current_player # 先检查用户是否在语音频道内 if not ctx.author.voice: await ctx.send("你需要先加入一个语音频道才能播放音效!") return voice_channel = ctx.author.voice.channel voice_client = await voice_channel.connect() # 创建播放器并绑定after回调 current_player = voice_client.create_ffmpeg_player( "doh.mp3", after=lambda e: voice_client.disconnect() ) current_player.start() await ctx.send("Playing DOH...") # 手动停止音效的命令 @client.command() async def stop(ctx): global current_player # 检查是否有正在播放的音效,且机器人处于连接状态 if current_player and ctx.voice_client and ctx.voice_client.is_connected(): current_player.stop() await ctx.voice_client.disconnect() await ctx.send("音效已停止播放!") else: await ctx.send("当前没有正在播放的音效哦!")
这样实现的优势:
- 无需循环检测
is_done(),播放完成后after回调会自动断开连接 - 用户随时可以发送
!stop命令终止播放,不会被循环阻塞 - 全局变量
current_player帮我们跟踪当前播放状态,避免重复播放冲突
内容的提问来源于stack exchange,提问作者Rastasplif
相关产品推荐
相关产品推荐

