Discord Bot调用ffmpeg时遇subprocess.py权限拒绝错误的解决求助
Discord Bot 权限错误问题排查与解决
问题描述
Discord Bot 在调用 subprocess.py 时抛出 PermissionError: [WinError 5] Access is denied,推测与 ffmpeg 相关。完整报错回溯如下:
Traceback (most recent call last): File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\interactions\client\client.py", line 1900, in __dispatch_interaction response = await callback File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\interactions\client\client.py", line 1771, in _run_slash_command return await command(ctx, **ctx.kwargs) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\interactions\models\internal\command.py", line 132, in __call__ await self.call_callback(self.callback, context) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\interactions\models\internal\application_commands.py", line 802, in call_callback return await self.call_with_binding(callback, ctx) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\interactions\models\internal\callback.py", line 43, in call_with_binding return await callback(*args, **kwargs) File "C:\Users\myuser\OneDrive\Desktop\button.py", line 38, in press voice_client.play(discord.FFmpegPCMAudio(executable=r"C:\Users\myuser\OneDrive\Desktop\ffmpeg-6.1-essentials_build\bin", source=audiosource)) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.Bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\discord\player.py", line 290, in __init__ super().__init__(source, executable=executable, args=args, **subprocess_kwargs) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\discord\player.py", line 166, in __init__ self._process = self._spawn_process(args, **kwargs) File "C:\Users\myuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.bunch_of_numbers\LocalCache\local-packages\Python310\site-packages\discord\player.py", line 180, in _spawn_process process = subprocess.Popen(args, creationflags=CREATE_NO_WINDOW, **subprocess_kwargs) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.bunch_of_numbers\lib\subprocess.py", line 971, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.bunch_of_numbers\lib\subprocess.py", line 1456, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args, PermissionError: [WinError 5] Access is denied
原代码:
import interactions import discord from discord import FFmpegPCMAudio import tracemalloc ffmpegexec = r"C:\Users\myuser\OneDrive\Desktop\ffmpeg-6.1-essentials_build\bin\ffmpeg.exe" audiosource = r"C:\Users\myuser\Downloads\seatbelt-online-audio-converter.mp3" source = discord.FFmpegPCMAudio(audiosource) token = "my_token" bot = interactions.Client(token=token) tracemalloc.start() @interactions.slash_command( name="joinvc", description="starts the game" ) async def joinvc(ctx: interactions.ComponentContext): await ctx.send("Joining vc. Please make sure you are currently in a vc!") vc = ctx.author.voice.channel await vc.connect() @interactions.slash_command( name="press", description="Press the button" ) async def press(ctx: interactions.ComponentContext): await ctx.send(f"{ctx.author.mention} has pressed the button") vc = ctx.author.voice.channel voice_client = await vc.connect() # Connect to the voice channel voice_client.play(discord.FFmpegPCMAudio(executable=r"C:\Users\myuser\OneDrive\Desktop\ffmpeg-6.1-essentials_build\bin", source=audiosource)) bot.start(token)
需求:实现 /press 命令触发 Bot 在语音频道播放指定音频。
问题原因与解决步骤
1. FFmpeg 路径错误
报错核心是给 executable 参数传了 ffmpeg 的文件夹路径,而非 ffmpeg.exe 完整路径。Windows 无法直接执行文件夹,导致权限报错。
- 修正:将
executable参数替换为已定义的ffmpegexec变量(完整的ffmpeg.exe路径)。
2. 代码缩进错误
voice_client.play() 语句位于 press 函数外部,Bot 启动时会立即执行,此时 voice_client 未定义,必然报错。
- 修正:将该语句缩进,放入
press函数内部,确保连接语音频道后再调用播放方法。
3. 避免重复连接语音频道
若用户已通过 /joinvc 让 Bot 进入频道,/press 中再次调用 await vc.connect() 会触发重复连接错误。
- 优化:先检查 Bot 是否已在目标频道连接,已连接则直接获取现有
voice_client,未连接再执行连接操作。
4. 权限与路径优化
- 避免将 ffmpeg 放在 OneDrive 路径下,同步过程可能导致文件访问异常,建议移至本地非同步文件夹(如
C:\ffmpeg\bin\ffmpeg.exe)。 - 确保 Python 和 ffmpeg 以管理员权限运行,规避 Windows 权限限制。
修正后的完整代码
import interactions import discord from discord import FFmpegPCMAudio import tracemalloc # 替换为你的ffmpeg.exe完整路径,建议移到非OneDrive目录 ffmpegexec = r"C:\Users\myuser\OneDrive\Desktop\ffmpeg-6.1-essentials_build\bin\ffmpeg.exe" audiosource = r"C:\Users\myuser\Downloads\seatbelt-online-audio-converter.mp3" token = "your_bot_token_here" bot = interactions.Client(token=token) tracemalloc.start() @interactions.slash_command(name="joinvc", description="让Bot加入语音频道") async def joinvc(ctx: interactions.ComponentContext): if not ctx.author.voice: await ctx.send("你需要先加入一个语音频道!") return vc = ctx.author.voice.channel # 检查是否已连接 if ctx.guild.voice_client: await ctx.send("Bot已经在语音频道里了!") return await vc.connect() await ctx.send("已加入语音频道!") @interactions.slash_command(name="press", description="触发播放音频") async def press(ctx: interactions.ComponentContext): if not ctx.author.voice: await ctx.send("你需要先加入一个语音频道!") return vc = ctx.author.voice.channel voice_client = ctx.guild.voice_client # 如果未连接则先连接 if not voice_client or not voice_client.is_connected(): voice_client = await vc.connect() # 使用正确的ffmpeg路径播放音频 audio_player = FFmpegPCMAudio(source=audiosource, executable=ffmpegexec) voice_client.play(audio_player) await ctx.send(f"{ctx.author.mention} 触发了音频播放!") bot.start(token)
内容的提问来源于stack exchange,提问作者Kronik71
相关产品推荐
相关产品推荐

