@Nikitonz
начинающий прогер в сфере бэкэнда

Некорректное переключение аудио. Где может крыться проблема?

Ошибка происходит в методе next_track_callback, play_next.
При нажатии на кнопку play next происходит вызов next_track_callback.

Ожидаемый результат:
Добавить в очередь несколько композиций
Нажать кнопку переключения трека
Аудио останавливается, из очереди достается ссылка на следующий трек, корректируется отображаемый embed

Фактический результат:
После нажатия кнопки переключения трека, происходит переключение аудио и корректирование эмбеда не менее 2х раз.
Подозреваю, что проблема в работе либо voice_client.stop(), либо в параметре after метода voice_client.play(after = ...)

def play_next(self):

        self.voice_client.pause()
        self.voice_client.stop().  #проблема тут

        if self.music_queue.__len__() > 0:
            print("next comp")
            track_name, url = self.music_queue[0]['title'], self.music_queue[0]['url']
            if self.embed.fields.__len__() == 0:
                self.embed.add_field(name="Playing now", value=track_name, inline=True)
            else:
                self.embed.set_field_at(index=0, name="Playing now", value=track_name, inline=True)
            print("before = " + str(len(self.music_queue)))
            self.music_queue.pop(0)
            print("after = " + str(len(self.music_queue)))
            try:
                #after next_track_callback was called, and play_next called, track switches twice
                self.que_fetch()
                FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
                source = disnake.PCMVolumeTransformer(disnake.FFmpegPCMAudio(source=url, **FFMPEG_OPTIONS,executable=r"dependencies\FFMPEG\bin\ffmpeg.exe"))

                self.voice_client.play(source= source, after=lambda e: self.play_next())#или здесь
                self.is_playing = True

            except disnake.ClientException as e:
                print("player playing!:    ", e)
            except Exception as e:
                print(e)


        else:
            print("stopping!")
            self.embed.clear_fields()
            coro = self.stopall()
            asyncio.run_coroutine_threadsafe(coro=coro, loop=self.bot.loop).result()

            return


Работа кнопки
async def next_track_callback(self, interaction: disnake.Interaction):
        await interaction.response.defer()
        self.play_next()

В консоли ошибок нет
  • Вопрос задан
  • 122 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Umys
Для решения этой проблемы я предлагаю обернуть вызов self.play_next() в after в функцию для предотвращения непосредственного вызова. И работать с asyncio, чтобы вызов коллбэк функции был корректным.

Попробуйте обновить вашу функцию play_next следующим образом:

async def play_next(self):
self.voice_client.pause()
self.voice_client.stop()

if self.music_queue.__len__() > 0:
print("next comp")
track_name, url = self.music_queue[0]['title'], self.music_queue[0]['url']
if self.embed.fields.__len__() == 0:
self.embed.add_field(name="Playing now", value=track_name, inline=True)
else:
self.embed.set_field_at(index=0, name="Playing now", value=track_name, inline=True)
print("before = " + str(len(self.music_queue)))
self.music_queue.pop(0)
print("after = " + str(len(self.music_queue)))
try:
self.que_fetch()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
source = disnake.PCMVolumeTransformer(disnake.FFmpegPCMAudio(source=url, **FFMPEG_OPTIONS,executable=r"dependencies\FFMPEG\bin\ffmpeg.exe"))

def play_next_callback(e):
coro = self.play_next()
future = asyncio.run_coroutine_threadsafe(coro, self.bot.loop)
future.result()

self.voice_client.play(source= source, after=play_next_callback)
self.is_playing = True

except disnake.ClientException as e:
print("player playing!: ", e)
except Exception as e:
print(e)

else:
print("stopping!")
self.embed.clear_fields()
coro = self.stopall()
asyncio.run_coroutine_threadsafe(coro=coro, loop=self.bot.loop).result()

return

Также обновите вашу функцию next_track_callback до версии с префиксом "async":

async def next_track_callback(self, interaction: disnake.Interaction):
await interaction.response.defer()
await self.play_next()

Попробуйте)
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы