Python开发Discord Spotify音乐机器人无法播放且提示应用未响应
Discord Spotify音乐机器人播放问题修复
核心问题分析
你的机器人出现「应用未响应」且无法播放音乐,主要由以下代码逻辑错误导致:
交互响应超时与重复响应
- Discord要求Slash命令必须在3秒内完成首次响应,你的代码在循环中多次调用
await interaction.response.send_message(),且存在长时间阻塞操作,直接触发超时提示。 interaction.response.send_message()仅能调用一次,后续发送消息需使用await interaction.followup.send()。
- Discord要求Slash命令必须在3秒内完成首次响应,你的代码在循环中多次调用
Spotify播放列表数据判断错误
sp.playlist_tracks()返回的结果中,歌曲列表存储在results['items']而非results['item'],错误的键名导致播放逻辑无法执行。
阻塞事件循环
while voice_client.is_playing(): pass是同步阻塞代码,会卡住机器人的事件循环,导致无法处理任何后续请求,包括交互响应。
Spotify链接无法被解析
- Youtube-DL(或yt-dlp)无法直接处理Spotify歌曲URL,需通过「歌曲名+艺术家」的关键词去Youtube搜索音频资源。
Pause命令逻辑错误
- 当前Pause命令实际执行断开语音连接,而非暂停播放;且函数名使用
self会覆盖内置变量,引发冲突。
- 当前Pause命令实际执行断开语音连接,而非暂停播放;且函数名使用
修复后的代码示例
import discord import asyncio from discord import app_commands import spotipy from spotipy.oauth2 import SpotifyClientCredentials import yt_dlp as youtube_dl # 推荐使用yt-dlp,Youtube-DL已停止维护 # 初始化Spotify客户端(请配置你的Client ID和Secret) sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials( client_id="你的Client ID", client_secret="你的Client Secret" )) @tree.command(name='play', description='播放Spotify播放列表', guild=guild_id) async def play(interaction: discord.Interaction, playlist_uri: str): # 先发送延迟响应,避免Discord超时 await interaction.response.defer(ephemeral=False) # 清理已存在的语音连接 if interaction.guild.voice_client is not None: await interaction.guild.voice_client.disconnect() # 检查用户是否在语音频道 try: channel = interaction.user.voice.channel except AttributeError: await interaction.followup.send("你需要先加入一个语音频道!") return voice_client = await channel.connect() # 获取Spotify播放列表内容 try: results = sp.playlist_tracks(playlist_uri) except Exception as e: await interaction.followup.send(f"获取播放列表失败:{str(e)}") await voice_client.disconnect() return if not results['items']: await interaction.followup.send("播放列表中没有歌曲") await voice_client.disconnect() return # 遍历播放列表歌曲 for item in results['items']: track = item['track'] if not track: continue track_name = track['name'] artist_name = track['artists'][0]['name'] search_query = f"{track_name} {artist_name} audio" # 搜索并获取Youtube音频链接 ydl_opts = { 'format': 'bestaudio/best', 'noplaylist': True, 'quiet': True, 'extract_flat': True, } try: with youtube_dl.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(f"ytsearch:{search_query}", download=False) if not info['entries']: await interaction.followup.send(f"未找到歌曲:{track_name} - {artist_name}") continue audio_url = info['entries'][0]['url'] except Exception as e: await interaction.followup.send(f"获取音频链接失败:{str(e)}") continue # 播放音频,使用回调处理播放结束 def after_playing(error): if error: print(f"播放出错:{error}") await interaction.followup.send(f"正在播放:{track_name} - {artist_name}") voice_client.play(discord.FFmpegPCMAudio(audio_url), after=after_playing) # 异步等待歌曲播放完成,避免阻塞事件循环 while voice_client.is_playing(): await asyncio.sleep(1) # 播放完成后断开连接 await voice_client.disconnect() await interaction.followup.send("播放列表已播放完毕") @tree.command(name='pause', description='暂停/恢复播放音乐', guild=guild_id) async def pause(interaction: discord.Interaction): voice_client = interaction.guild.voice_client if voice_client and voice_client.is_playing(): voice_client.pause() await interaction.response.send_message("已暂停播放") elif voice_client and voice_client.is_paused(): voice_client.resume() await interaction.response.send_message("已恢复播放") else: await interaction.response.send_message("当前没有正在播放的音乐")
额外注意事项
- 安装依赖:
pip install discord.py spotipy yt-dlp ffmpeg-python - 需单独安装FFmpeg并配置到系统环境变量
- 确保Spotify开发者账号已正确配置权限,能访问目标播放列表
内容的提问来源于stack exchange,提问作者kazuya
相关产品推荐
相关产品推荐

