0

I'm currently working on a discord bot (python 3.8.10) that plays music in a voice channel.

I have a music queue and a function that plays the first song in the queue, deletes it and then calls itself when the song ends.

The problem is that lambda functions must be non-await and I really don't know how to avoid this problem.

Thank you for your helping

# plays next song in the queue
    # this function can be called from
        # the play command if the user adds a song to the music queue (and the bot is not playing anything)
        # the play_music() function when the previous song ends
        # the skip command (called by the user)
    async def play_music(self, ctx):
        try:
            if len(self.music_queue) > 0:
                # music queue is a list, each element composed by a playlist (dictionary) and a voice channel
                # so [0] means the first song, [0] means the playlist, ['source'] the value of source in the dictionary
                song_url = self.music_queue[0][0]['source']
                self.now_playing = self.music_queue[0]
                # removes the first element because it is about to be played
                self.music_queue.pop(0)
                if not self.voice_channel.is_playing():
                    # here's the error!!!
                    self.voice_channel.play(discord.FFmpegPCMAudio(song_url, **self.FFMPEG_OPTIONS), after = lambda e: self.play_music(ctx))
                # transforms the volume
                self.voice_channel.source = discord.PCMVolumeTransformer(self.voice_channel.source, volume=self.volume)
                # gets the time stamp of the playing song
                self.music_position = (datetime.datetime.now() - datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()
                self.is_playing = True
            else:
                self.is_playing = False
        except youtube_dl.DownloadError or HTTPError:
            # TODO: send message
            print('download error')
            return

The exception I get is:

RuntimeWarning: coroutine 'music_cog.play_music' was never awaited

PS: strange thing is, it works anyway, although I get an error!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Liuk23
  • 58
  • 7
  • 2
    A warning is not an error. Look at the message carefully, and provide a complete stack trace – Mad Physicist Jan 24 '22 at 20:50
  • That's true, thank you. Does never awaiting a function cause any problem or can I just ignore the warning? – Liuk23 Jan 24 '22 at 21:00
  • @Liuk23, no, not if you don't have to depend on the result of the `await`ed coroutine, for example, a situation where the next line of code prints the result of the coroutine. If that's not the situation, you can just ignore the warning. Maybe [this](https://stackoverflow.com/a/70827648/16136190) can help. – The Amateur Coder Jan 25 '22 at 04:34

1 Answers1

1

I actually found a solution here: how-to-use-await-in-a-python-lambda

In my case, that's how I rewrote my code:

self.voice_channel.play(discord.FFmpegPCMAudio(song_url, **self.FFMPEG_OPTIONS),
                                        after = lambda ctx: (await self.play_music(ctx) for _ in '_').__anext__())
Liuk23
  • 58
  • 7