Discord音乐机器人join命令失效及播放列表/队列功能添加求助
Discord音乐机器人问题修复与功能扩展
一、修复"Command 'join' is not found"错误
这个问题核心是你的Cog未被正确加载到机器人客户端,或主文件配置缺失,具体修复步骤如下:
确保Cog被正确加载
- 如果音乐Cog代码单独存放在
music.py中,主文件(如main.py)需显式加载扩展:import discord from discord.ext import commands # 启用必要权限,否则无法读取命令或获取语音频道信息 intents = discord.Intents.default() intents.message_content = True intents.voice_states = True client = commands.Bot(command_prefix='?', intents=intents) @client.event async def on_ready(): print(f'Logged in as {client.user}') # 加载音乐Cog await client.load_extension('music') # 'music'为Cog文件名(不含.py) client.run('你的机器人Token') - 若所有代码在同一文件,需在创建客户端后手动调用
setup函数:# ... 你的music Cog代码 ... intents = discord.Intents.default() intents.message_content = True intents.voice_states = True client = commands.Bot(command_prefix='?', intents=intents) # 加载Cog setup(client) @client.event async def on_ready(): print(f'Logged in as {client.user}') client.run('你的机器人Token')
- 如果音乐Cog代码单独存放在
检查Discord开发者门户权限
确保在开发者门户中启用Message Content Intent和Voice States Intent,否则机器人无法正常读取命令或获取语音状态。
二、添加队列与播放列表功能
以下是基于你原有代码扩展的完整实现:
import discord from discord.ext import commands import youtube_dl from collections import deque class music(commands.Cog): def __init__(self, client): self.client = client self.queue = deque() # 用双端队列存储待播放歌曲 @commands.command() async def join(self,ctx): if ctx.author.voice is None: await ctx.send("You're not in a voice channel!") voice_channel = ctx.author.voice.channel if ctx.voice_client is None: await voice_channel.connect() else: await ctx.voice_client.move_to(voice_channel) @commands.command() async def disconnect(self,ctx): await ctx.voice_client.disconnect() @commands.command() async def play(self, ctx, *, url): # 检查用户是否在语音频道 if ctx.author.voice is None: await ctx.send("You're not in a voice channel!") return # 机器人不在频道则自动加入 if ctx.voice_client is None: await ctx.author.voice.channel.connect() FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'} YDL_OPTIONS = {'format': "bestaudio", 'extract_flat': True} # extract_flat用于解析播放列表 with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl: info = ydl.extract_info(url, download=False) # 判断是否为播放列表 if 'entries' in info: # 遍历添加所有列表歌曲到队列 valid_entries = [entry for entry in info['entries'] if entry] for entry in valid_entries: song_url = entry['url'] if 'url' in entry else entry['webpage_url'] self.queue.append((song_url, entry['title'])) await ctx.send(f"Added {len(valid_entries)} songs from playlist to queue!") else: # 单首歌曲加入队列 song_url = info['url'] if 'url' in info else info['webpage_url'] self.queue.append((song_url, info['title'])) await ctx.send(f"Added '{info['title']}' to queue!") # 当前无播放任务则启动播放 if not ctx.voice_client.is_playing(): await self.play_next(ctx) async def play_next(self, ctx): if self.queue: song_url, song_title = self.queue.popleft() FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'} source = await discord.FFmpegOpusAudio.from_probe(song_url, **FFMPEG_OPTIONS) # 播放完成后自动触发下一首 ctx.voice_client.play(source, after=lambda e: self.client.loop.create_task(self.play_next(ctx))) await ctx.send(f"Now playing: '{song_title}'") else: await ctx.send("Queue is empty! No more songs to play.") @commands.command() async def skip(self, ctx): if ctx.voice_client and ctx.voice_client.is_playing(): ctx.voice_client.stop() await ctx.send("Skipped current song!") else: await ctx.send("No song is playing right now!") @commands.command() async def queue(self, ctx): if not self.queue: await ctx.send("Queue is empty!") return # 格式化队列信息 queue_msg = "Current queue:\n" for idx, (_, title) in enumerate(self.queue, 1): queue_msg += f"{idx}. '{title}'\n" await ctx.send(queue_msg) @commands.command() async def pause(self,ctx): await ctx.voice_client.pause() await ctx.channel.send("Paused") @commands.command() async def resume(self,ctx): await ctx.voice_client.resume() await ctx.channel.send("Resume") def setup(client): client.add_cog(music(client))
功能说明
- 队列管理:用
deque实现高效的歌曲入队/出队,支持查看队列(?queue)、跳过歌曲(?skip) - 播放列表解析:自动识别YouTube播放列表,将所有歌曲批量加入队列
- 自动续播:当前歌曲播放完成后,自动播放队列中的下一首
内容的提问来源于stack exchange,提问作者Him
相关产品推荐
相关产品推荐

