Reputation: 876
[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"))
Upvotes: 0
Views: 356
Reputation: 2102
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.
Upvotes: 1