部署在Heroku的discord.py播放命令遇Opus加载目录错误
解决Heroku上discord.py加载Opus时的
OSError: opus: cannot read file data: Is a directory错误 这个错误我之前在部署discord.py机器人到Heroku时也碰到过,根源在于你手动指定的Opus加载路径在Heroku环境中不适用,让我一步步帮你解决:
问题根源
Heroku的Python buildpack已经默认预装了Opus库,但你写的discord.opus.load_opus("opus")会让程序尝试读取名为"opus"的系统目录(而不是实际的库文件),这就导致了那个目录读取错误。
两种解决方法
方法1:最简单的方案——移除手动加载代码
从discord.py v1.3版本开始,库会自动检测并加载系统中的Opus库,完全不需要你手动调用load_opus。直接删掉discord.opus.load_opus("opus")这一行,机器人启动时会自动完成Opus的加载,在Heroku上能完美运行。
方法2:指定正确的Opus库路径(适合旧版discord.py)
如果你还在使用v1.3之前的discord.py版本,那就需要指定Heroku上Opus库的绝对路径。Heroku上的Opus库位于/usr/lib/libopus.so,修改代码为:
discord.opus.load_opus("/usr/lib/libopus.so")
给你的Play命令提几个优化点
除了Opus的问题,你的play命令还有一些细节可以优化,避免在Heroku上出现其他报错:
- 没有判断用户是否在语音频道,如果用户没进频道,
voice会是None,调用is_playing()会直接崩溃 - 没有处理
youtube_dl的异常,比如无效URL、私有视频等情况 - 没有处理机器人当前在其他语音频道的情况
优化后的代码参考:
@client.command() async def play(ctx, url): # 先检查用户是否在语音频道里 if not ctx.author.voice: return await ctx.send("你得先加入一个语音频道才能点歌哦!") YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'} FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'} # 获取当前服务器的语音客户端,没有的话就加入用户所在频道 voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if not voice: voice = await ctx.author.voice.channel.connect() # 如果机器人在其他频道,就移到用户所在频道 elif voice.channel != ctx.author.voice.channel: await voice.move_to(ctx.author.voice.channel) if not voice.is_playing(): try: with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl: info = ydl.extract_info(url, download=False) audio_url = info['formats'][0]['url'] voice.play(discord.FFmpegPCMAudio(audio_url, **FFMPEG_OPTIONS)) await ctx.send(f"🎵 正在播放: {info['title']}") except Exception as err: await ctx.send(f"播放出错啦: {str(err)}") else: await ctx.send("当前正在播放歌曲,请先暂停或等这首歌结束哦!")
内容的提问来源于stack exchange,提问作者Onur
相关产品推荐
相关产品推荐

