[feat]: Add queue command

This commit is contained in:
Sweetbread 2023-05-09 23:24:00 +03:00
parent e29a81f165
commit 84960e00eb

View File

@ -10,34 +10,32 @@ from discord.ext import commands
from bot import db from bot import db
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
# TODO: locale # TODO: locale
class Music(commands.Cog, name="Музыка"): class Music(commands.Cog, name="Музыка"):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.query = {} self.queue = {}
def play_(self, inter, url): def play_(self, inter, info):
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
try: try:
URL = info['url'] URL = info['url']
except: except:
URL = url URL = url
logger.debug(URL) logger.debug(URL)
with open("tmp/tmp.log", 'w') as f:
f.write(dumps(info))
audio_source = discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS) audio_source = discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS)
inter.guild.voice_client.play(audio_source, after=lambda error: self.next_(inter, error)) inter.guild.voice_client.play(audio_source, after=lambda error: self.next_(inter, error))
asyncio.run_coroutine_threadsafe(self.send_embed_(inter, info, url), self.bot.loop) asyncio.run_coroutine_threadsafe(self.send_embed_(inter, info), self.bot.loop)
async def send_embed_(self, inter, info, url): async def send_embed_(self, inter, info):
embed = discord.Embed ( embed = discord.Embed (
title=info["title"], title=info["title"],
url=url, url=info['url'],
description=info["description"] description=info["description"]
) )
embed.set_author ( embed.set_author (
@ -50,8 +48,8 @@ class Music(commands.Cog, name="Музыка"):
except: except:
await inter.channel.send(embed=embed) await inter.channel.send(embed=embed)
async def end_of_query_(self, inter): async def end_of_queue_(self, inter):
await inter.response.send_message("В очереди больше не осталось песен") await inter.channel.send("В очереди больше не осталось песен")
@app_commands.command(description="Plays music from popular platforms") @app_commands.command(description="Plays music from popular platforms")
@app_commands.describe(url="URL from Youtube/RuTube and other platforms") @app_commands.describe(url="URL from Youtube/RuTube and other platforms")
@ -64,36 +62,36 @@ class Music(commands.Cog, name="Музыка"):
return return
if inter.guild.voice_client is None: if inter.guild.voice_client is None:
await channel.connect() await channel.connect()
self.queue[channel.id] = {
"adder": inter.user.id,
"cur_pos": 0,
"queue": [],
"context": inter,
"skip_policy": "everyone"
}
elif inter.user.voice.channel != inter.guild.voice_client.channel: elif inter.user.voice.channel != inter.guild.voice_client.channel:
await inter.response.send_message(f"Занято каналом {inter.guild.voice_client.channel.mention}") await inter.response.send_message(f"Занято каналом {inter.guild.voice_client.channel.mention}")
return return
client = inter.guild.voice_client client = inter.guild.voice_client
if url=="": with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
url = self.query[str(channel.id)][0] info = ydl.extract_info(url, download=False)
del self.query[str(channel.id)][0]
if str(channel.id) not in self.query.keys(): self.queue[channel.id]["queue"].append({'requester': inter.user.id, 'url': url, 'info': info})
self.query[str(channel.id)] = {
"requester_id": inter.user.id,
"music_pos": 0,
"query": [],
"context": inter
}
self.query[str(channel.id)]["query"].append(url)
if client.is_playing() or client.is_paused(): if client.is_playing() or client.is_paused():
logger.debug("\n".join(self.query[str(channel.id)]['query']))
await inter.response.send_message("Добавлена новая песня в очередь") await inter.response.send_message("Добавлена новая песня в очередь")
return return
else: else:
inter.guild.voice_client.stop() inter.guild.voice_client.stop()
self.play_(inter, url) self.play_(inter, info)
@app_commands.command() @app_commands.command()
async def stop(self, inter): async def stop(self, inter):
queue = self.queue[inter.user.voice.channel.id]
queue['cur_pos'] = len(queue['queue'])-1
inter.guild.voice_client.stop() inter.guild.voice_client.stop()
await inter.response.send_message("Остановлено") await inter.response.send_message("Остановлено")
@ -114,21 +112,41 @@ class Music(commands.Cog, name="Музыка"):
@app_commands.command() @app_commands.command()
async def next(self, inter): async def next(self, inter):
self.next_(inter) inter.guild.voice_client.stop()
@app_commands.command(name='queue')
async def _queue(self, inter):
queue = self.queue[inter.user.voice.channel.id]
text = ''
for pos, item in enumerate(queue['queue']):
if queue['cur_pos'] == pos: text += '>>> '
else: text += ' '
text += f"{pos+1}. "
text += item['info']['title']
text += '\n - Запросил: ' + self.bot.get_user(item['requester']).name
text += '\n'
await inter.response.send_message(f"```\n{text}\n```")
def next_(self, inter, error=None): def next_(self, inter, error=None):
logger.debug("\n....".join(["Query:"]+self.query[str(inter.user.voice.channel.id)]['query'])) if error:
logger.error(error)
return
inter.guild.voice_client.stop() inter.guild.voice_client.stop()
query = self.query[str(inter.user.voice.channel.id)]
query["music_pos"] = query["music_pos"] + 1
logger.debug((len(query["query"]), query["music_pos"]))
if len(query["query"]) == query["music_pos"]:
asyncio.run_coroutine_threadsafe(self.end_of_query_(inter), self.bot.loop)
logger.debug([query["music_pos"]]) queue = self.queue[inter.user.voice.channel.id]
url = query["query"][query["music_pos"]] queue["cur_pos"] += 1
self.play_(inter, url) logger.debug((len(queue["queue"]), queue["cur_pos"]))
if len(queue["queue"]) == queue["cur_pos"]:
asyncio.run_coroutine_threadsafe(self.end_of_queue_(inter), self.bot.loop)
return
#logger.debug([query["music_pos"]])
info = queue["queue"][queue["cur_pos"]]['info']
self.play_(inter, info)
async def setup(bot): async def setup(bot):