Воспроизведение очереди звуковых дорожек в discord.py

#python #discord.py

#python #discord.py

Вопрос:

Итак, я создаю этот музыкальный дискорд-бот на discord.py . Этот бот просто воспроизводит плейлист из локальных файлов mp3 на моем компьютере. Итак, у меня есть функция, которая воспроизводит очередь, и она выглядит следующим образом:

 def play_song(ctx, voice):
    if len(queue) == 0:
        print('All the songs have been played')
        create_queue()
        return

    song_ = queue[0][len('songs/'):-16]
    voice.play(discord.FFmpegPCMAudio(queue[0]), after=lambda e: play_song(ctx, voice))
    print(f'Now playing {song_}')
    del queue[0]
 

И я хочу преобразовать эту функцию в асинхронную функцию, потому что я хочу иметь возможность отправлять сообщения и выполнять другие действия в discord.py внутри этой функции.
Проблема, с которой я сталкиваюсь, является результатом этой строки:

 voice.play(discord.FFmpegPCMAudio(queue[0]), after=lambda e: play_song(ctx, voice))
 

Если я сделаю эту функцию асинхронной, мне придется поместить оператор await, и если я это сделаю, это будет так:

 voice.play(discord.FFmpegPCMAudio(queue[0]), after=lambda e: await play_song(ctx, voice))
 

Проблема в том, что это выдает мне ошибку:
"await outside of async function"
Итак, я также попытался использовать asyncio.run() , а затем после первой песни он выдает мне огромный список ошибок, что мне делать дальше?

Ответ №1:

Попробуйте использовать async def play_song(ctx, voice): в верхней части. Вы не можете await внутри нефункционального async .

Комментарии:

1. await outside async function Ошибка возникает, когда функция является асинхронной, если бы это было не так, мне бы не понадобилось ожидание, я думаю, это потому, что функция after не является асинхронной

2. await Находится внутри вашей лямбда-функции, которой нет async .

Ответ №2:

Я нашел ответ на свой собственный вопрос. Ответ заключается в том, чтобы использовать asyncio.Event() , я сделал это так:

 async def play_song(ctx, voice):
    global stop_playing, pos_in_q, time_from_song
    event = asyncio.Event()
    event.set()
    while True:
        await event.wait()
        event.clear()
        if len(queue) == pos_in_q - 1:
            await ctx.send('Party is over! use the `.arse-play` to play again.')
            print('Party is over!')
            create_queue()
            break
        if stop_playing is True:
            stop_playing = False
            break

        song_ = queue[pos_in_q][len('songs/'):]
        voice.play(discord.FFmpegPCMAudio(queue[pos_in_q]), after=lambda e: event.set())
        print(f'Now playing {song_}')
        time_from_song = time.time()
        pos_in_q  = 1