Discord.py调用voice.play()无响应、YouTube音频无法播放且FFmpeg进程异常终止的问题排查
看起来你的代码里存在几个关键问题,直接导致了音频无法播放、FFmpeg进程异常退出(返回码3436169992),我来一步步帮你排查修复:
1. 致命的音频源赋值错误(最核心问题)
你代码最后创建音频源的这一行完全写错了:
source = discord.FFmpegPCMAudio(source=source)
这里你把未定义的source变量作为参数传给了discord.FFmpegPCMAudio,相当于没有传入任何有效的音频流URL,FFmpeg自然无法处理,直接异常退出。
正确的写法是使用你之前从yt-dlp获取的url,同时必须传入你定义好的FFMPEG_OPTIONS(否则可能出现流断开、无法重连的问题):
source = discord.FFmpegPCMAudio(url, **FFMPEG_OPTIONS)
2. 语音频道连接逻辑的缺失与错误
你的代码里有个未定义的变量voice_channel,直接调用await voice_channel.connect()会报错,而且没有检查用户是否在语音频道里。修复这部分逻辑:
# 先检查用户是否在语音频道 if not ctx.author.voice: await ctx.send("你需要先加入一个语音频道才能让我播放音频哦!") return voice_channel = ctx.author.voice.channel voice = ctx.guild.voice_client # 处理连接逻辑 if not voice: voice = await voice_channel.connect() elif voice.channel != voice_channel: # 如果机器人在其他频道,可选择移动或者提示 await voice.move_to(voice_channel) # 停止当前正在播放的音频(如果有的话) if voice.is_playing(): voice.stop()
3. FFmpeg返回码3436169992的根源
这个返回码本质是FFmpeg进程因为无效的输入源(也就是你之前错误的source变量)而异常终止。当你修复了音频源的问题后,这个错误码应该会自动消失。如果之后还出现类似错误,可以检查:
- yt-dlp获取的
url是否有效(你已经加了print(url),可以手动复制到浏览器或者FFmpeg里测试能不能播放) - FFmpeg是否正确安装在你的服务器环境中(确保系统PATH里有FFmpeg,或者在
discord.FFmpegPCMAudio里指定executable参数指向FFmpeg的路径)
4. yt-dlp配置与播放逻辑的适配优化
你的ydl_opts里配置了FFmpegExtractAudio转MP3,但因为你用了download=False,这个后处理器其实不会生效——它只在下载本地文件时工作。不过这不影响在线播放,因为你只需要获取流媒体URL,这点没问题。
但可以优化yt-dlp的错误处理,比如在解析链接时捕获更具体的异常:
# 替换原来的链接判断逻辑 try: # 用requests.head代替get,更快判断是否是有效链接 response = requests.head(arg, allow_redirects=True) response.raise_for_status() info = ydl.sanitize_info(ydl.extract_info(arg, download=False)) except (requests.exceptions.RequestException, yt_dlp.utils.DownloadError) as e: print(f"链接解析失败,转为搜索:{e}") info = ydl.extract_info(f"ytsearch:{arg}", download=False)["entries"][0]
5. 增加播放错误回调,方便调试
给voice.play()加上错误回调函数,能直接看到播放过程中出现的具体错误,不用只靠FFmpeg的返回码猜问题:
async def play_error(error): if error: print(f"播放过程中出现错误:{str(error)}") await ctx.send(f"播放出错了:{str(error)}") # 注意要使用异步兼容的回调,这里用lambda包装 voice.play(source, after=lambda e: asyncio.run_coroutine_threadsafe(play_error(e), self.bot.loop))
最后总结
先把最核心的音频源赋值错误修复,再补全语音连接的逻辑,这两个问题解决后,基本就能正常播放了。如果还有问题,把ydl_opts里的quiet: True改成False,打开yt-dlp的日志,结合错误回调的信息,就能快速定位到流解析或者FFmpeg的具体问题。




