How can I resolve the error 'str' object has no attribute 'is_paused' in discord.py?

huangapple go评论77阅读模式
英文:

How can I resolve the error 'str' object has no attribute 'is_paused' in discord.py?

问题

以下是您要翻译的内容:

[2023-02-19 05:14:12] [ERROR] discord.ext.commands.bot: Ignoring exception in command play
Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 229, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\toto\PycharmProjects\pythonProject\music_bot-main\main.py", line 101, in play
elif self.is_paused:
AttributeError: 'str' object has no attribute 'is_paused'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 1349, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 1023, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 238, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'is_paused'

import discord
from discord.ext import commands
import os
import asyncio

import all of the cogs

from help_cog import help_cog

from music_cog import music_cog

intents = discord.Intents.all()
client = commands.Bot(command_prefix='.', intents=intents)

@client.event
async def on_ready():
print(f'Logged in as {client.user} (ID: {client.user.id})')
print('------')

remove the default help command so that we can write out own

client.remove_command('help')

register the class with the bot

bot.add_cog(help_cog(bot))

client.add_cog(music_cog(client))

code du bot

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

    # all the music related stuff
    self.is_playing = False
    self.is_paused = False

    # 2d array containing [song, channel]
    self.music_queue = []
    self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
    self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
                           'options': '-vn'}

    self.vc = None

# searching the item on youtube
def search_yt(self, item):
    with YoutubeDL(self.YDL_OPTIONS) as ydl:
        try:
            info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0]
        except Exception:
            return False

    return {'source': info['formats'][0]['url'], 'title': info['title']}

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

        # get the first url
        m_url = self.music_queue[0][0]['source']

        # remove the first element as you are currently playing it
        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

# infinite loop checking
async def play_music(self, ctx):
    if len(self.music_queue) > 0:
        self.is_playing = True

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

        # try to connect to voice channel if you are not already connected
        if self.vc == None or not self.vc.is_connected():
            self.vc = await self.music_queue[0][1].connect()

            # in case we fail to 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])

        # remove the first element as you are currently playing it
        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

@client.command(name="play", aliases=["p", "playing"], help="Plays a selected song from youtube")
async def play(ctx, self, *args):
query = " ".join(args)

voice_channel = ctx.author.voice.channel
if voice_channel is None:
    # you need to be connected so that the bot knows where to go
    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 another keyword. This could be due to playlist or a livestream format.")
    else:
        await ctx.send("Song added to the queue")
        self.music_queue.append([song, voice_channel])

        if self.is_playing == False:
            await self.play_music(ctx)

@client.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_paused = False
self.is_playing = True
self.vc.resume()

@client.command(name="resume", aliases=["r"], help="Resumes playing with the discord bot")
async def resume(self, ctx, *args):
if self.is_paused:
self.is_paused = False
self.is_playing = True
self.vc.resume()

@client.command(name="skip", aliases=["s"], help="Skips the current song being played")
async def skip(self, ctx):
if self.vc != None and self.vc:
self.vc.stop()
# try to play next in the queue if it exists
await self.play_music(ctx)

@client.command(name="queue", aliases=["q"], help="Displays the current songs in queue")
async def queue(self, ctx):
retval = ""
for i in range(0, len(self.music_queue)):
# display a max of 5 songs in the current queue
if (i > 4): break
retval += self.music_queue[i][0]['title'] + "\n"

if retval != "":
    await ctx.send(retval)
else:
英文:

> [2023-02-19 05:14:12] [ERROR ] discord.ext.commands.bot: Ignoring exception in command play
Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 229, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\toto\PycharmProjects\pythonProject\music_bot-main\main.py", line 101, in play
elif self.is_paused:
AttributeError: 'str' object has no attribute 'is_paused'

> The above exception was the direct cause of the following exception:

>Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 1349, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 1023, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 238, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'is_paused'

import discord
from discord.ext import commands
import os
import asyncio

# import all of the cogs
# from help_cog import help_cog
# from music_cog import music_cog

intents = discord.Intents.all()
client = commands.Bot(command_prefix='.', intents=intents)

@client.event
async def on_ready():
    print(f'Logged in as {client.user} (ID: {client.user.id})')
    print('------')


# remove the default help command so that we can write out own
client.remove_command('help')


# register the class with the bot
# bot.add_cog(help_cog(bot))
# client.add_cog(music_cog(client))
# code du bot
class music_cog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

        # all the music related stuff
        self.is_playing = False
        self.is_paused = False

        # 2d array containing [song, channel]
        self.music_queue = []
        self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
        self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
                               'options': '-vn'}

        self.vc = None

    # searching the item on youtube
    def search_yt(self, item):
        with YoutubeDL(self.YDL_OPTIONS) as ydl:
            try:
                info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0]
            except Exception:
                return False

        return {'source': info['formats'][0]['url'], 'title': info['title']}

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

            # get the first url
            m_url = self.music_queue[0][0]['source']

            # remove the first element as you are currently playing it
            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

    # infinite loop checking
    async def play_music(self, ctx):
        if len(self.music_queue) > 0:
            self.is_playing = True

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

            # try to connect to voice channel if you are not already connected
            if self.vc == None or not self.vc.is_connected():
                self.vc = await self.music_queue[0][1].connect()

                # in case we fail to 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])

            # remove the first element as you are currently playing it
            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


@client.command(name="play", aliases=["p", "playing"], help="Plays a selected song from youtube")
async def play(ctx, self, *args):
    query = " ".join(args)

    voice_channel = ctx.author.voice.channel
    if voice_channel is None:
        # you need to be connected so that the bot knows where to go
        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 another keyword. This could be due to playlist or a livestream format.")
        else:
            await ctx.send("Song added to the queue")
            self.music_queue.append([song, voice_channel])

            if self.is_playing == False:
                await self.play_music(ctx)


@client.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_paused = False
        self.is_playing = True
        self.vc.resume()


@client.command(name="resume", aliases=["r"], help="Resumes playing with the discord bot")
async def resume(self, ctx, *args):
    if self.is_paused:
        self.is_paused = False
        self.is_playing = True
        self.vc.resume()


@client.command(name="skip", aliases=["s"], help="Skips the current song being played")
async def skip(self, ctx):
    if self.vc != None and self.vc:
        self.vc.stop()
        # try to play next in the queue if it exists
        await self.play_music(ctx)


@client.command(name="queue", aliases=["q"], help="Displays the current songs in queue")
async def queue(self, ctx):
    retval = ""
    for i in range(0, len(self.music_queue)):
        # display a max of 5 songs in the current 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 queue")


@client.command(name="clear", aliases=["c", "bin"], help="Stops the music and clears the queue")
async def clear(self, ctx):
    if self.vc != None and self.is_playing:
        self.vc.stop()
    self.music_queue = []
    await ctx.send("Music queue cleared")


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


@client.command()
async def bonjour(ctx):
    await ctx.send("Bonjour")


# start the bot with our token

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

答案1

得分: 1

你在很多非类方法中都加入了self参数。所以self最终变成了你的context对象,而ctx是命令参数。只需从那些不需要self的方法中移除self。也就是说,那些不属于类的每个方法。

async def play(ctx, *args):
    ...


async def pause(ctx, *args):
    ...


async def resume(ctx, *args):
    ...


async def skip(ctx):
    ...


async def queue(ctx):
    ...


async def clear(ctx):
    ...


async def dc(ctx):
    ...

以上是需要更改的部分。

英文:

You've given lots of non-class methods the self parameter. So self ends up being your context object and ctx the command argument. Just remove self from the methods that don't need it. ie, every method that doesn't belong to a class.

async def play(ctx, *args):
    ...


async def pause(ctx, *args):
    ...


async def resume(ctx, *args):
    ...


async def skip(ctx):
    ...


async def queue(ctx):
    ...


async def clear(ctx):
    ...


async def dc(ctx):
    ...

Above are the ones that need changing.

huangapple
  • 本文由 发表于 2023年2月19日 12:22:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497969.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定