Discord bot播放mp3仅对先于其加入语音频道的用户生效,如何修复
问题根源
你当前代码的核心问题是while voice_client.is_playing(): continue这个空轮询逻辑完全阻塞了Discord.py的异步事件循环,导致框架没法处理以下必要逻辑:
- 新用户加入语音频道后的语音流同步握手
- 定期向Discord语音服务器发送心跳包维持会话状态
- 后续音频数据包的正常调度发送
小概率关联问题为FFmpegOpusAudio配置异常、语音客户端未主动广播讲话状态,导致新加入用户无法识别到bot的音频流。
修复方案
1. 替换阻塞轮询为非阻塞等待
将空循环替换为带asyncio.sleep的非阻塞等待,主动让出事件循环资源给框架处理其他语音事件:
import asyncio if voice_client: audio_source = await discord.FFmpegOpusAudio.from_probe('motd.mp3') voice_client.play(audio_source) # 每0.1秒检查一次播放状态,期间让出事件循环 while voice_client.is_playing(): await asyncio.sleep(0.1)
2. 手动触发语音讲话状态(可选适配低版本框架)
部分旧版本discord.py/py-cord不会自动向新加入用户同步bot的讲话状态,可在播放前手动触发:
import asyncio if voice_client: # 主动发送讲话状态包,让新加入用户可接收音频流 await voice_client.ws.speak() audio_source = await discord.FFmpegOpusAudio.from_probe('motd.mp3') voice_client.play(audio_source) while voice_client.is_playing(): await asyncio.sleep(0.1)
3. 依赖校验
确保你使用的discord.py/py-cord为最新稳定版,且系统已正确安装libopus依赖,避免底层语音转发bug。
额外注意事项
如果你要实现新用户加入频道时自动触发播放的逻辑,每次播放都需要重新生成FFmpegOpusAudio实例,不要复用之前创建的音频源对象,避免FFmpeg单源流耗尽导致的无输出问题。
内容的提问来源于stack exchange,提问作者CrazyCarlton
相关产品推荐
相关产品推荐

