Автоматизация очередей в боте Python Discord

0

Вопрос

Это код, который у меня есть:

@commands.command(pass_context=True, aliases= ["aq"])
async def add_queue(self, ctx, *, url):
  a = ctx.message.guild.id
  b = servers[a]
  global queue
  try: 
    b[len(b)] = url 
    user = ctx.message.author.mention
    await ctx.send(f'``{url}`` was added to the queue by {user}!')
  except:
    await ctx.send(f"Couldnt add {url} to the queue!")

@commands.command(pass_context=True, aliases= ["qp"], case_insensitive=True)
async def pq(self,ctx, number):
  a = ctx.message.guild.id
  b = servers[a]
  if int(number) in b:
    source = b[int(number)]
    self.cur_song_id = int(number)
    await ctx.send(f"**Now Playing:** {source}")
    await self.transformer(ctx, source)
    
async def transformer(self,ctx, url):
  player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)
  if not ctx.message.author.voice:
    await ctx.send("You are not connected to a voice channel!")
    return
  elif ctx.voice_client and ctx.voice_client.is_connected():
    print('Already connected to voice')
    pass
  else:
    channel = ctx.message.author.voice.channel
    await ctx.send(f'Connected to ``{channel}``')
    await channel.connect()
  ctx.voice_client.play(player)

Я могу создать отдельную очередь для каждого сервера и добавлять в нее песни с помощью команды:

-aq song_name

пример очереди:

Your current queue is {0: 'abcdefu', 1: 'stereo hearts', 2: 'shivers'}

Я могу воспроизводить песни в очереди с помощью команды:

-pq 0 or -pq 1 or -pq 2

Но проблема в том, что бот воспроизводит только одну песню и останавливается после ее завершения, и я хочу, чтобы бот воспроизводил следующую песню после завершения текущей песни и продолжал до тех пор, пока не будет воспроизведена последняя песня в очереди.

Пожалуйста, помогите мне с этим....

заранее спасибо!!!

2
0

Во-первых, ваш словарь ({0: 'abcdefu', 1: 'stereo hearts', 2: 'shivers'}) действительно может быть просто списком, так как ключи-это в основном просто индексы.

Во-вторых, у меня нет никакого опыта работы со звуком в discord.py но мне кажется, что ваш pq функция на самом деле не переходит к следующей песне. Он называет transformer действуйте один раз, и все. Кажется, что на самом деле все, что вам нужно сделать, это просто пройти по очереди и воспроизвести каждую песню. Вот некоторый psuedocode, который может быть полезен:

@commands.command()
async def play_queue(self,ctx,number=0):
  for num in range(number,len(queue)):
    song = queue[num]
    # play the song

Невыполнение обязательств number=0 это позволило бы воспроизводить всю очередь, если бы номер не был указан.

2021-11-23 18:41:58

Привет, Во-первых, извините за столь поздний ответ, ноутбук сломался. Во всяком случае, я пытался сделать это раньше. Проблема в том, что цикл не будет ждать завершения первой песни, он просто увеличивает итератор, пока первая песня все еще воспроизводится, что приводит к ошибке, в которой говорится, что ЗВУК УЖЕ ВОСПРОИЗВОДИТСЯ.
xBatmanx

Ну ладно, я понимаю. Существует параметр play функция, вызываемая after(discordpy.readthedocs.io/en/latest/...). Он предназначен для обработки ошибок, но, похоже, обычно используется либо для повторения песни, либо для воспроизведения другой. Также ознакомьтесь с этим постом. Это показывает действительно простой способ использования after параметр, соответствующий вашей ситуации
Roopesh-J

Да, я действительно понял это позже той ночью!. Спасибо, что приложили усилия, чтобы помочь! Действительно ценю это.
xBatmanx

Лучший ответ

0

Итак, чтобы решить свою проблему, я реализовал этот код, и он работает.

Я передал свою очередь, которая является словарем, в функцию transformer, и число, которое по умолчанию равно 0 (для воспроизведения очереди с самого начала).

И используя after параметр в функции воспроизведения, я продолжал вызывать функцию и продолжал повторять число до тех пор, пока оно меньше длины очереди.

Он автоматически воспроизводит песни в очереди.

Я знаю, что этот код работает, но, если можно внести какие-либо улучшения, я открыт для предложений.

async def transformer(self,ctx, number, que):
  player = await YTDLSource.from_url(que[number], loop=self.bot.loop,stream=True)
  await ctx.send(f"**Now Playing:** {que[number]}")
  ctx.voice_client.play(player, after=lambda e: asyncio.run_coroutine_threadsafe(self.transformer(ctx,number+1 , que),self.bot.loop) if number < len(que) else ctx.voice_client.pause())

Спасибо!.

2021-12-03 06:39:41

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................