Automatyzacja kolejek bot Python Discord

0

Pytanie

Jest to kod, który mam:

@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)

Mogę tworzyć osobne kolejki dla każdego serwera i dodać w niej utwory za pomocą polecenia:

-aq song_name

przykład kolejki:

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

Mogę odtwarzać utwory w kolejce za pomocą polecenia:

-pq 0 or -pq 1 or -pq 2

Ale problem w tym, że bot odtwarza tylko jedną piosenkę i zatrzymuje się po jego zakończeniu, i chcę, aby bot odgrywało następny utwór po zakończeniu bieżącego utworu i kontynuował, dopóki nie zostanie odtworzony najnowsza piosenka w kolejce.

Proszę, pomóż mi z tym....

z góry dziękuję!!!

2
0

Po pierwsze, twój słownik ({0: 'abcdefu', 1: 'stereo hearts', 2: 'shivers'}) naprawdę może być tylko listą, ponieważ klucze-to w zasadzie tylko indeksy.

Po drugie, nie mam żadnego doświadczenia w pracy z dźwiękiem w discord.py ale wydaje mi się, że twój pq funkcja faktycznie nie przechodzi do następnego utworu. Nazywa transformer działaj jeden raz, i to wszystko. Wydaje się, że właściwie wszystko, co musisz zrobić, to po prostu przejść po kolei i odtworzyć każdą piosenkę. Oto niektóre psuedocode, który może być przydatny:

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

Niewywiązanie się z zobowiązań number=0 to pozwoliło by odtwarzać całą kolei, jeśli pokój nie został określony.

2021-11-23 18:41:58

Witam, Po pierwsze, przepraszam za tak późną odpowiedź, laptop się zepsuł. W każdym razie starałem się zrobić to wcześniej. Problem w tym, że cykl nie będzie czekać na zakończenie pierwszej piosenki, to po prostu zwiększa iterator, aż pierwsza piosenka wciąż odtwarzany, co prowadzi do błędu, w którym czytamy, że DŹWIĘK JUŻ jest ODTWARZANY.
xBatmanx

No dobrze, rozumiem. Istnieje opcja play wywołana funkcja after(discordpy.readthedocs.io/pl/latest/...). Jest on przeznaczony do obsługi błędów, ale wygląda na to, zazwyczaj stosowana do powtarzania utworu, albo do odtwarzania inny. Także zapoznać się z tym postem. To pokazuje bardzo prosty sposób użycia after parametr odpowiadający twojej sytuacji
Roopesh-J

Tak, naprawdę zrozumiałem to później, tej samej nocy!. Dziękuję, że dołożyliśmy starań, aby pomóc! Naprawdę to doceniam.
xBatmanx

Najlepsza odpowiedź

0

Tak więc, aby rozwiązać swój problem, dodałem ten kod i działa.

Przekazałem swoją kolej, która jest słownik, w funkcji transformer, i liczba, która domyślnie wynosi 0 (do odtwarzania w kolejce od samego początku).

I za pomocą after parametr do funkcji odtwarzania, ja nadal wywoływać funkcję i powtarzałem: liczba, aż ono mniej długości kolejki.

Automatycznie odtwarza utwory w kolejce.

Wiem, że ten kod działa, ale, jeśli można wprowadzić jakieś ulepszenia, jestem otwarty na propozycje.

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())

Dziękuję!.

2021-12-03 06:39:41

W innych językach

Ta strona jest w innych językach

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