Discord.py Переписать - ASyncIO put () в очереди не работает должным образом - PullRequest
0 голосов
/ 04 ноября 2019

Ошибка вывода

AttributeError: 'member_descriptor' object has no attribute 'put'

В настоящее время у меня есть класс MusicPlayer, позволяющий моему боту воспроизводить музыку так, как мне хотелось бы. Я верю, что моя команда вызывает проблему, но я не уверен. Я никогда не слышал об элементе member_descriptor, и при его поиске, похоже, не так уж много об этой ошибке. Я хотел бы просто добавить песни в очередь и воспроизводить их в таком порядке, если их нет в очереди, следует просто воспроизвести их.

Ниже приведены мои класс и команда. Любая помощь очень ценится!

ОБНОВЛЕНО

Класс MusicPlayer

class MusicPlayer():
    __slots__ = ("client", "_guild", "_ctxs", "_channel", "_cog", "np", "volume", "current", "colour", "task")
    queue = asyncio.Queue()
    next = asyncio.Event()

    def __init__(self, ctx, client):

        self.client = client
        self._guild = ctx.guild
        self._ctxs = ctx
        self._channel = ctx.channel
        self._cog = ctx.cog

        self.np = None
        self.volume = defaultvolume
        self.current = None
        self.colour = self.client.defaultcolour

        self.task = self.client.loop.create_task(self.player_loop())

    async def player_loop(self):
        await self.client.wait_until_ready()

        while True:
            self.next.clear()

            try:
                async with timeout(300):
                    self.current = await queue.get()
            except asyncio.CancelledError:
                return
            except asyncio.TimeoutError:
                guild = self._guild
                vc = guild.voice_client
                self.destroy(guild)
                if not vc: return
                await self._ctxs.send(":point_right: **I disconnected myself from the **`{}`** voice channel as I was not playing audio for 5 minutes!**".format(vc.channel.name))
                return
            except:
                self.destroy(self._guild)
                await self._ctxs.send(":thumbsdown: **Error: getting next song failed!** Please retry later!")
                return

            self._ctxs.voice_client.play(self.current, after=lambda: self.client.loop.call_soon_threadsafe(next.set))
            self.current.volume = self.volume
            thumbnail = self.current.thumbnail if self.current.thumbnail else self.client.user.avatar_url
            self.colour = await self.client.get_average_colour(thumbnail)
            embednps = discord.Embed(colour=self.colour)
            embednps.add_field(name="Now Playing", value=f"```{self.current.title}```", inline=False)
            embednps.add_field(name="Link", value=f"[URL]({self.current.web_url})", inline=True)
            embednps.add_field(name="Duration", value=self.client.time_from_seconds(self.current.duration), inline=True)
            embednps.add_field(name="Channel", value=f"{self.current.uploader}", inline=False)
            embednps.set_thumbnail(url=f"{thumbnail}")
            embednps.set_footer(text=f"Requested by {self.current.requester}", icon_url=self.current.requester.avatar_url)
            self.np = await self._channel.send(embed=embednps)

            await next.wait()
            print("Terminated")

            # Cleanup player
            self.current.cleanup()
            self.current = None

    async def add_song(self, player):
        return await self.queue.put(player)

    def destroy(self, guild):
        return self.client.loop.create_task(self._cog.cleanup(guild))

Команда воспроизведения

    @commands.command(aliases=['yt', 'youtube'])
    async def play(self, ctx, *, url=None):
        await ctx.message.delete()
        channel = ctx.message.author.voice.channel

        if url is None:
            await ctx.send("Music: Please specify a Youtube URL. Syntax (!play {URL})", delete_after=7)
            return

        if ctx.guild.voice_client is None:
            if not ctx.author.voice:
                await ctx.send("Music: Please join a Voice Channel or use join command.", delete_after=7)
                return
            await channel.connect()
        else:
            if not ctx.author.voice:
                await ctx.send("Music: Please join a Voice Channel or use join command.", delete_after=7)
                return
            if ctx.guild.voice_client.channel != ctx.message.author.voice.channel:
                await ctx.guild.voice_client.move_to(channel)

        async with ctx.typing():
            player = await YTDLSource.from_url(url, loop=self.client.loop, stream=True)

            if ctx.guild.voice_client.is_playing():
                await MusicPlayer.add_song(MusicPlayer, player)
                await ctx.send('Music: {} has now been added to the Queue'.format(player.title), delete_after=7)
                return

            voice_channel = ctx.guild.voice_client
            voice_channel.play(player, after=lambda: self.client.loop.call_soon_threadsafe(MusicPlayer.next.set))
            await ctx.send('Music: Now playing {}'.format(player.title), delete_after=7)

1 Ответ

1 голос
/ 04 ноября 2019

Класс MusicPlayer имеет дескриптор queue, который создается __slots__. Вы получаете доступ к этому дескриптору напрямую, когда вы делаете MusicPlayer.queue вместо доступа к атрибуту экземпляра, который вы делаете с music_player.queue.

. В какой-то момент вам нужно создать объект MusicPlayer изваш класс и используйте его вместо самого класса.

...