Search code examples
pythondiscorddiscord.pyqueueaudio-player

SyntaxError: 'await' outside async function


So i'm trying to add a queue to my bot. but it gives me the error in the title.

This is the command to add something to the queue:

@commands.command()
    async def remove(self, ctx, number):
        global queue

        try:
            del (queue[int(number)])
            await ctx.send(f'Your queue is now `{queue}!`')

        except:
            await ctx.send("Your queue is either **empty** or **out of range**")

And this is my code to play the queue (I tried it a different way but idk how to play the next song if the current one stops if its not in a function, so yeah thats why its like in a def)

        def queuePlayer():
            YDL_OPTIONS = {'format': "bestaudio"}
            vc = ctx.voice_client
            FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
            with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
                global queue
                info = ydl.extract_info(f"ytsearch:{queue[0]}", download=False)
                if 'entries' in info:
                    video = info['entries'][0]
                else:
                    video = info
                url2 = video['formats'][0]['url']

                def convert(seconds):
                    seconds = seconds % (24 * 3600)
                    hour = seconds // 3600
                    seconds %= 3600
                    minutes = seconds // 60
                    seconds %= 60
                    return "%d:%02d:%02d" % (hour, minutes, seconds)

                print(video)
                video_url = video['url']
                print(video_url)
                source = await discord.FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
                vc.play(source)
                del (queue[0])
                print(video['title'])
                track = video['title']
                artist = video['channel']
                duration = video['duration']
                durationConv = convert(duration)
                thumbnail = video['thumbnail']
                embedVar = discord.Embed(title="Now playing", description=":notes: {}".format(track), color=0x00ff00)
                embedVar.add_field(name="Artist", value=":microphone: {}".format(artist), inline=False)
                embedVar.add_field(name="Duration", value=f":hourglass_flowing_sand: `{durationConv}`", inline=False)
                embedVar.set_thumbnail(url=thumbnail)
                await ctx.send(embed=embedVar)
                t = duration
                while t:
                    time.sleep(1)
                    t -= 1
                    print(t)
                print("TIMER REACHED 0")
                if t == 0:
                    print("T IS 0")
                    await ctx.send("Playing next!")
                queuePlayer()
        queuePlayer()

Solution

  • discord's api uses an asynchronous library, so it calls the library's functions with 'await.' that fetches the data you're using from the discord server. you use this with 'async def' when you're writing a command that goes through the client. the reason you're getting that error is because you're trying to use 'await' in a regular python function (defined with 'def' instead of 'async def.') it doesn't work because there's nothing to await, and as it's a regular (synchronous) function instead of an async function, you won't be able to call it in discord, and since you cant call it there won't be any context to send the message to.

    for what you're trying to do, i suggest changing it from 'def' to 'async def' and adding the @commands.command(), then fiddling with it from there. sometimes it takes a while to get right, but more often than not you'll get there in the end!