使用discord.py开发YouTube音乐机器人遇OSError错误求助
问题描述
开发了一个具备YouTube音乐播放功能的discord.py机器人,机器人可正常加入语音频道,但执行playy命令时报错:
Command 'playy' raised an exception: OSError: ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
原youtube-dl网站已无法访问,尝试重装、添加系统环境变量等方法后问题依旧。相关代码如下:
@tree.command(name = "playy", description = "Frančesko začne hrát vybranou hudbu!y") async def test(interaction: discord.Interaction, id: str): search = "morpheus tutorials discord bot python" channel_id = int(id) voice_channel = client.get_channel(channel_id) g = await voice_channel.connect() search = search.replace(" ", "+") html = urllib.request.urlopen("https://www.youtube.com/results?search_query=" + search) video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode()) song = pafy.new(video_ids[0]) audio = song.getbestaudio() source = FFmpegPCMAudio(audio.url, **FFMPEG_OPTIONS) g.play(source)
修复方案
核心问题是youtube-dl已停止维护,且pafy依赖的youtube-dl无法正常工作,需替换为活跃维护的yt-dlp并调整代码逻辑:
安装必要依赖
卸载旧的youtube-dl和pafy,安装yt-dlp及配套库:pip uninstall youtube-dl pafy -y pip install yt-dlp替换代码逻辑
移除pafy和手动解析YouTube搜索结果的逻辑,改用yt-dlp直接处理搜索与音频提取,调整后的代码示例:import yt_dlp from discord import FFmpegPCMAudio # yt-dlp配置 YDL_OPTIONS = { 'format': 'bestaudio/best', 'noplaylist': True, 'quiet': True, 'extractaudio': True, 'audioformat': 'mp3', } FFMPEG_OPTIONS = { 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn' } @tree.command(name = "playy", description = "Frančesko začne hrát vybranou hudbu!y") async def test(interaction: discord.Interaction, id: str): # 连接语音频道 channel_id = int(id) voice_channel = client.get_channel(channel_id) voice_client = await voice_channel.connect() # 搜索并获取音频流 search_query = "morpheus tutorials discord bot python" with yt_dlp.YoutubeDL(YDL_OPTIONS) as ydl: info = ydl.extract_info(f"ytsearch:{search_query}", download=False)['entries'][0] audio_url = info['url'] source = FFmpegPCMAudio(audio_url, **FFMPEG_OPTIONS) # 启动播放 voice_client.play(source) await interaction.response.send_message(f"正在播放: {info['title']}")关键调整说明
- 用
ytsearch:前缀让yt-dlp直接处理搜索请求,无需手动解析HTML提取视频ID - 给FFmpeg添加重连参数,避免播放中途因网络问题中断
- 完全移除对pafy的依赖,直接通过yt-dlp获取音频流地址
- 用
内容的提问来源于stack exchange,提问作者TheLiveYT
相关产品推荐
相关产品推荐

