Wolf_Yout
@Wolf_Yout

Как правильно сделать сообщение «Сейчас играет» при каждом новом треке?

Код:
async def play(ctx):
        voice_state = ctx.guild.voice_client
        if not voice_state:
            error = await Song.join_channel(ctx)
            if error:
                return error
        voice_state = ctx.guild.voice_client
        if voice_state.is_playing():
            return "alreadyPlay"
        ids = []
        names = []
        requesters = []
        alis = []
        authors = []
        positions = []
        with sqlite3.connect("database.db") as db:
            c = db.cursor()
            for n, r, a, i, ai, ly, g, p in c.execute("SELECT * FROM songs WHERE guild = ?", (ctx.guild.id,)):
                ids.append(i)
                names.append(n)
                requesters.append(r)
                alis.append(ai)
                authors.append(a)
                positions.append(p)
        if not os.path.isfile(f"songs/{ids[0]}.mp3"):
            Song.download_track(ctx, {'id': ids[0]})
        voice_state.play(disnake.FFmpegPCMAudio(f"songs/{ids[0]}.mp3"), after=lambda e: Song.init_after(ctx))
        voice_state.is_playing()
        embed = disnake.Embed(title=names[0],color=0x228b22)
        embed.add_field(name=lang(ctx,"Главный автор:"),value=authors[0])
        embed.add_field(name=lang(ctx,"Предложил:"),value=f"<@{requesters[0]}>")
        embed.add_field(name=lang(ctx,"Источник:"),value="<:yandexMusic:1056924402790436934> Yandex Music\n")
        embed.add_field(name=lang(ctx,"Ссылка:"),value=f"[**{lang(ctx,'Это кликабельная ссылка!')}**](https://music.yandex.ru/album/{alis[0]}/track/{ids[0]})")
        embed.add_field(name=lang(ctx,"Позиция:"),value=positions[0])
        await ctx.channel.send(embed=embed)
        return None

Сообщение отправляется только при самом первом добавлении:
image.png
После этого каждый раз когда надо отправить сообщение, вместо сообщения в консоли появляется ошибка:
Traceback (most recent call last):
  File "/home/container/.local/lib/python3.9/site-packages/disnake/player.py", line 742, in _call_after
    self.after(error)
  File "/home/container/main.py", line 191, in <lambda>
    voice_state.play(disnake.FFmpegPCMAudio(f"songs/{ids[0]}.mp3"), after=lambda e: Song.init_after(ctx))
  File "/home/container/main.py", line 163, in init_after
    asyncio.run(Song.my_after(ctx))
  File "/usr/local/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/home/container/main.py", line 160, in my_after
    await Song.play(ctx)
  File "/home/container/main.py", line 199, in play
    await ctx.channel.send(embed=embed)
  File "/home/container/.local/lib/python3.9/site-packages/disnake/abc.py", line 1638, in send
    data = await state.http.send_message(
  File "/home/container/.local/lib/python3.9/site-packages/disnake/http.py", line 342, in request
    async with self.__session.request(method, url, **kwargs) as response:
  File "/home/container/.local/lib/python3.9/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
  File "/home/container/.local/lib/python3.9/site-packages/aiohttp/client.py", line 467, in _request
    with timer:
  File "/home/container/.local/lib/python3.9/site-packages/aiohttp/helpers.py", line 700, in __enter__
    raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task

Как сделать отправку этого сообщения правильно?
  • Вопрос задан
  • 107 просмотров
Пригласить эксперта
Ответы на вопрос 1
@romazhan
Ошибка указывает, что возникла проблема при запуске функции `Song.my_after` с помощью `asyncio.run`. Возможно, эта функция не является асинхронной, или вы не находитесь в асинхронном контексте при вызове `init_after`.

Попробуйте обернуть `Song.my_after` в `asyncio.create_task`, чтобы запустить ее как асинхронное задание:
async def init_after(ctx):
    asyncio.create_task(Song.my_after(ctx))

Вы можете запустить только асинхронные функции с помощью `create_task`. Если `Song.my_after` является синхронной функцией, вам нужно будет преобразовать ее в асинхронную с помощью декоратора `@asyncio.coroutine`, или с помощью `async def` в Python 3.5 и выше.

Чтобы отправлять сообщение «Сейчас играет» при каждом новом треке, вы можете добавить отправку сообщения в функцию `play`, которую вы написали:
async def play(ctx):
    # ...
    await ctx.send("Сейчас играет: {}".format(names[0]))

Также вы можете отправлять это сообщение в функции `init_after`, которая вызывается после окончания воспроизведения текущего трека:
async def init_after(ctx):
    # ...
    await ctx.send("Сейчас играет: {}".format(names[0]))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы