You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Discord机器人报错:CommandNotFound,play命令未找到

Discord机器人play命令找不到的问题排查与修复

我跟着教程做了个Discord机器人,输入命令时一直报错:discord.ext.commands.errors.CommandNotFound: Command "play" is not found。机器人已经在服务器显示在线,权限也给全了,反复检查代码没找到问题,求帮忙。下面是我的文件代码:

main.py

import discord
from discord.ext import commands
import os

from help_cog import help_cog
from music_cog import music_cog

bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())

bot.remove_command("help")

bot.add_cog(help_cog(bot))
bot.add_cog(music_cog(bot))

bot.run(os.getenv("TOKEN"))

music_cog.py

import discord
from discord.ext import commands

from yt_dlp import YoutubeDL

import yt_dlp as youtube_dl

class music_cog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

        self.is_playing = False
        self.is_paused = False

        self.music_queue = []
        self.YDL_OPTIONS = {"format": "bestaudio", "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "192",}]}
        self.FFMPEG_OPTIONS = {"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", "options": "-vn"}

        self.vc = None
        print("Success")

    def search_yt(self, item):
        with YoutubeDL(self.YDL_OPTIONS) as ydl:
            try:
                info = ydl.extract_info(f"ytsearch:{item}", download=False)["entries"][0]
            except Exception:
                return False
        return {"source": info["url"], "title": info["title"]}

    def play_next(self):
        if len(self.music_queue) > 0:
            self.is_playing = True

            m_url = self.music_queue[0][0]["source"]

            self.music_queue.pop(0)

            self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
        else:
            self.is_playing = False

    async def play_music(self, ctx):
        if len(self.music_queue) > 0:
            self.is_playing = True
            m_url = self.music_queue[0][0]["source"]

            if self.vc == None or not self.vc.is_connected():
                self.vc = await self.music_queue[0][1].connect()

                if self.vc == None:
                    await ctx.send("Could not connect to the voice channel")
                    return
            else:
                await self.vc.move_to(self.music_queue[0][1])
            
            self.music_queue.pop(0)

            self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())

        else:
            self.is_playing = False

    @commands.command(name="play", aliases=["p", "playing"], help="Play the selected song from YouTube")
    async def play(self, ctx, *args):
        query = " ".join(args)

        voice_channel = ctx.author.voice.channel
        if voice_channel is None:
            await ctx.send("Connect to a voice channel!")
        elif self.is_paused:
            self.vc.resume()
        else:
            song = self.search_yt(query)
            if type(song) == type(True):
                await ctx.send("Could not download the song. Incorrect format, try a different keyword")
            else:
                await ctx.send("Song added to queue")
                self.music_queue.append([song, voice_channel])

                if self.is_playing == False:
                    await self.play_music(ctx)
    
    @commands.command(name="pause", help="Pauses the current song being played")
    async def pause(self, ctx, *args):
        if self.is_playing:
            self.is_playing = False
            self.is_paused = True
            self.vc.pause()
        elif self.is_paused:
            self.is_playing = True
            self.is_paused = False
            self.vc.resume()

    @commands.command(name="resume", aliases=["r"], help="Resumes playing the current song")
    async def resume(self, ctx, *args):
        if self.is_paused:
            self.is_playing = True
            self.is_paused = False
            self.vc.resume()
        
    @commands.command(name="skip", aliases=["s"], help="Skips the currently played song")
    async def skip(self, ctx, *args):
        if self.vc != None and self.vc:
            self.vc.stop()
            await self.play_music(ctx)

    @commands.command(name="queue", aliases=["q"], help="Displays all the songs currently in queue")
    async def queue(self, ctx):
        retval = ""

        for i in range(0, len(self.music_queue)):
            if i > 4: break
            retval += self.music_queue[i][0]["title"] + "\n"

        if retval != "":
            await ctx.send(retval)
        else:
            await ctx.send("No music in the current queue")
    
    @commands.command(name="clear", aliases=["c", "bin"], help="Stops the current song and clears the queue")
    async def clear(self, ctx, *args):
        if self.vc != None and self.is_playing:
            self.vc.stop()
        self.music_queue = []
        await ctx.send("Music queue cleared")

    @commands.command(name="leave", aliases=["disconnect", "l", "d"], help="Kick the bot from the voice channel")
    async def leave(self, ctx):
        self.is_playing = False
        self.is_paused = False
        await self.vc.disconnect()

help_cog.py

import discord
from discord.ext import commands

class help_cog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

        self.help_message = """
        Help message
"""

        self.text_channel_text = []
    
    @commands.Cog.listener()
    async def on_ready(self):
        for guild in self.bot.guilds:
            for channel in guild.text_channels:
                self.text_channel_text.append(channel)

        await self.send_to_all(self.help_message)

    async def send_to_all(self, msg):
        for text_channel in self.text_channel_text:
            await text_channel.send(msg)
        
    @commands.command(name="help", help="Displays all the available commands")
    async def help(self, ctx):
        await ctx.send(self.help_message)

问题排查与修复方案

1. 确认Cog是否成功加载

在main.py中添加就绪事件日志,检查cog加载状态:

@bot.event
async def on_ready():
    print(f'已登录为 {bot.user.name} (ID: {bot.user.id})')
    print('------')
    # 打印已加载的cog列表
    print(f"已加载的Cog: {list(bot.cogs.keys())}")

运行后如果控制台没显示music_cog和help_cog,说明文件路径错误,确保help_cog.py、music_cog.py和main.py在同一目录下。

2. 修复help_cog的on_ready异常

help_cog的on_ready方法会遍历所有文本频道发消息,若频道权限不足或服务器数量多,会抛出异常中断程序。修改该方法添加异常捕获:

@commands.Cog.listener()
async def on_ready(self):
    for guild in self.bot.guilds:
        for channel in guild.text_channels:
            self.text_channel_text.append(channel)
    # 捕获发送消息的异常,避免程序崩溃
    try:
        await self.send_to_all(self.help_message)
    except Exception as e:
        print(f"发送帮助消息失败: {e}")

或者直接注释掉await self.send_to_all(self.help_message),先测试命令是否可用。

3. 检查命令前缀和输入格式

确保输入命令时使用正确的前缀?,比如输入?play 歌曲名,而非直接输入play。

4. 开启Discord后台的特权意图

登录Discord开发者后台,进入Bot页面,开启Privileged Gateway Intents下的「服务器成员意图」和「消息内容意图」,否则机器人无法接收命令消息。

5. 修复music_cog的语音连接异常

play_music方法中连接语音频道可能抛出异常,添加捕获逻辑避免程序中断:

async def play_music(self, ctx):
    if len(self.music_queue) > 0:
        self.is_playing = True
        m_url = self.music_queue[0][0]["source"]

        if self.vc == None or not self.vc.is_connected():
            try:
                self.vc = await self.music_queue[0][1].connect()
            except Exception as e:
                await ctx.send(f"连接语音频道失败: {e}")
                self.music_queue.pop(0)
                self.is_playing = False
                return

            if self.vc == None:
                await ctx.send("无法连接到语音频道")
                return
        else:
            try:
                await self.vc.move_to(self.music_queue[0][1])
            except Exception as e:
                await ctx.send(f"切换语音频道失败: {e}")
                self.music_queue.pop(0)
                self.is_playing = False
                return
        
        self.music_queue.pop(0)

        self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())

    else:
        self.is_playing = False

内容的提问来源于stack exchange,提问作者Skely

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:05:55