使用discord.FFmpegPCMAudio结合youtube_dl出现ffmpeg文件未找到错误
Discord机器人播放音频失败问题
我用Python开发Discord机器人,执行脚本后输入!play...指令,机器人能进入语音频道,但终端提示INFO discord.player ffmpeg进程22136以返回码4294967294成功终止,导致ffmpeg进程终止,无法播放音频。
播放命令代码片段
@bot.command(name='play') async def play_song(ctx, *, song): query = f'{song} official video' ydl_options = {'format': 'bestaudio', 'noplaylist': True, 'extract_flat': True} with youtube_dl.YoutubeDL(ydl_options) as ydl: info = ydl.extract_info(f"ytsearch:{query}", download=False) if 'entries' in info: url = info['entries'][0]['url'] title = info['entries'][0]['title'] voice_channel = ctx.author.voice if not voice_channel: await ctx.send("Devi essere in un canale vocale per poter riprodurre una canzone!") return vc = await voice_channel.channel.connect() await ctx.send(f"Inizio a riprodurre '{title}'.") vc.play(discord.FFmpegPCMAudio(url)) songs_queue.append((url, title)) else: await ctx.send("Nessun risultato trovato per la canzone specificata.")
标准错误输出
Error while running ffmpeg. Here is some information: ffmpeg version N-111719-gb98ee1a355-20230808 Copyright (c) 2000-2023 the FFmpeg developers built with gcc 13.1.0 (crosstool-NG 1.25.0.196_227d99d) configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable- libtheora --enable-libvpx --enable-libwebp --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --disable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-ldexeflags= --extra-libs=-lgomp --extra-version=20230808 libavutil 58. 15.100 / 58. 15.100 libavcodec 60. 23.100 / 60. 23.100 libavformat 60. 10.100 / 60. 10.100 libavdevice 60. 2.101 / 60. 2.101 libavfilter 9. 10.100 / 9. 10.100 libswscale 7. 3.100 / 7. 3.100 libswresample 4. 11.100 / 11.100 libpostproc 57. 2.100 / 57. 2.100 [in#0 @ 000001ef8f484300] Error opening input: No such file or directory Error opening input file 9QZMjFC_RgY. Error opening input files: No such file or directory
Python堆栈跟踪
Traceback: NoneType: None
请求协助解决该问题。
解决方案
问题根源
错误日志显示Error opening input file 9QZMjFC_RgY,说明传给FFmpeg的不是有效的音频流URL,而是YouTube视频ID。这是因为配置了extract_flat: True,该参数会让youtube-dl仅提取元数据(如视频ID、标题),不会获取真实的媒体流URL。
修复步骤
- 调整youtube-dl配置:移除
extract_flat: True参数(或设为False),让工具完整提取可播放的音频流URL。 - 添加FFmpeg必要参数:针对YouTube音频流,需添加参数处理HTTPS连接和音频格式,避免播放中断。
- 保留播放器引用:若
vc.play创建的播放器对象无引用,会被Python垃圾回收机制销毁,导致FFmpeg进程意外终止,需显式保存该对象。
修改后的代码
@bot.command(name='play') async def play_song(ctx, *, song): query = f'{song} official video' # 移除extract_flat,添加音频提取配置 ydl_options = { 'format': 'bestaudio/best', 'noplaylist': True, 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], 'quiet': True } with youtube_dl.YoutubeDL(ydl_options) as ydl: info = ydl.extract_info(f"ytsearch:{query}", download=False) if 'entries' in info: info = info['entries'][0] url = info['url'] title = info['title'] voice_channel = ctx.author.voice if not voice_channel: await ctx.send("你需要先加入一个语音频道才能播放音乐!") return # 检查是否已连接语音频道,避免重复连接 vc = ctx.voice_client if not vc: vc = await voice_channel.channel.connect() await ctx.send(f"开始播放:'{title}'.") # 添加FFmpeg参数,处理音频流的重连和格式 ffmpeg_options = { 'options': '-vn', 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5' } # 保存播放器对象,防止被垃圾回收 player = discord.FFmpegPCMAudio(url, **ffmpeg_options) vc.play(player) songs_queue.append((url, title)) else: await ctx.send("未找到指定的歌曲。")
额外注意事项
- 确保系统已正确安装FFmpeg,且Python能找到其执行路径。若路径未配置,可在
FFmpegPCMAudio中指定executable参数,如discord.FFmpegPCMAudio(url, executable="path/to/ffmpeg", **ffmpeg_options)。 - youtube-dl已停止维护,建议改用
yt-dlp(youtube-dl的分支),兼容性更强。安装命令:pip install yt-dlp,代码中只需将import youtube_dl改为import yt_dlp as youtube_dl即可。
内容的提问来源于stack exchange,提问作者Retr0
相关产品推荐
相关产品推荐

