This repository has been archived on 2025-01-28. You can view files and clone it, but cannot push or open issues or pull requests.
natsuko/cogs/music.py

136 lines
4.7 KiB
Python
Raw Normal View History

2023-05-03 19:53:01 +03:00
import discord
import yt_dlp as youtube_dl
import functools
import asyncio
from loguru import logger
from json import dumps
2023-05-06 23:53:55 +03:00
from discord import app_commands
2023-05-03 19:53:01 +03:00
from discord.ext import commands
from bot import db
2023-05-06 23:53:55 +03:00
# TODO: locale
2023-05-03 19:53:01 +03:00
class Music(commands.Cog, name="Музыка"):
def __init__(self, bot):
self.bot = bot
self.query = {}
2023-05-06 23:53:55 +03:00
def play_(self, inter, url):
2023-05-03 19:53:01 +03:00
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:
URL = info['url']
except:
URL = url
logger.debug(URL)
with open("tmp/tmp.log", 'w') as f:
2023-05-03 19:53:01 +03:00
f.write(dumps(info))
audio_source = discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS)
2023-05-06 23:53:55 +03:00
inter.guild.voice_client.play(audio_source, after=lambda error: self.next_(inter, error))
2023-05-03 19:53:01 +03:00
2023-05-07 01:15:06 +03:00
asyncio.run_coroutine_threadsafe(self.send_embed_(inter, info, url), self.bot.loop)
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
async def send_embed_(self, inter, info, url):
2023-05-03 19:53:01 +03:00
embed = discord.Embed (
title=info["title"],
url=url,
description=info["description"]
)
embed.set_author (
name=info["uploader"],
url=info["uploader_url"]
)
embed.set_thumbnail( url=info["thumbnail"] )
2023-05-07 01:15:06 +03:00
try:
await inter.response.send_message(embed=embed)
except:
await inter.channel.send(embed=embed)
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
async def end_of_query_(self, inter):
await inter.response.send_message("В очереди больше не осталось песен")
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
@app_commands.command(description="Plays music from popular platforms")
2023-05-07 01:15:06 +03:00
@app_commands.describe(url="URL from Youtube/RuTube and other platforms")
async def play(self, inter, url: str):
logger.debug(asyncio.get_running_loop())
2023-05-06 23:53:55 +03:00
channel = inter.user.voice.channel
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
if inter.user.voice is None:
await inter.response.send_message("Ты не в ГК")
2023-05-03 19:53:01 +03:00
return
2023-05-06 23:53:55 +03:00
if inter.guild.voice_client is None:
2023-05-03 19:53:01 +03:00
await channel.connect()
2023-05-06 23:53:55 +03:00
elif inter.user.voice.channel != inter.guild.voice_client.channel:
await inter.response.send_message(f"Занято каналом {inter.guild.voice_client.channel.mention}")
2023-05-03 19:53:01 +03:00
return
2023-05-06 23:53:55 +03:00
client = inter.guild.voice_client
2023-05-03 19:53:01 +03:00
if url=="":
url = self.query[str(channel.id)][0]
del self.query[str(channel.id)][0]
2023-05-06 23:53:55 +03:00
if str(channel.id) not in self.query.keys():
self.query[str(channel.id)] = {
"requester_id": inter.user.id,
2023-05-07 01:15:06 +03:00
"music_pos": 0,
2023-05-06 23:53:55 +03:00
"query": [],
"context": inter
}
2023-05-07 01:15:06 +03:00
self.query[str(channel.id)]["query"].append(url)
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
if client.is_playing() or client.is_paused():
2023-05-07 01:15:06 +03:00
logger.debug("\n".join(self.query[str(channel.id)]['query']))
await inter.response.send_message("Добавлена новая песня в очередь")
return
else:
inter.guild.voice_client.stop()
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
self.play_(inter, url)
2023-05-03 19:53:01 +03:00
2023-05-06 23:53:55 +03:00
@app_commands.command()
async def stop(self, inter):
inter.guild.voice_client.stop()
await inter.response.send_message("Остановлено")
@app_commands.command()
async def pause(self, inter):
inter.guild.voice_client.pause()
await inter.response.send_message("Поставлено на паузу")
@app_commands.command()
async def resume(self, inter):
inter.guild.voice_client.resume()
await inter.response.send_message("Снято с паузы")
@app_commands.command()
async def disconnect(self, inter):
await inter.guild.voice_client.disconnect()
await inter.response.send_message("Отключено")
@app_commands.command()
async def next(self, inter):
self.next_(inter)
def next_(self, inter, error=None):
2023-05-07 01:15:06 +03:00
logger.debug("\n....".join(["Query:"]+self.query[str(inter.user.voice.channel.id)]['query']))
2023-05-06 23:53:55 +03:00
inter.guild.voice_client.stop()
query = self.query[str(inter.user.voice.channel.id)]
2023-05-03 19:53:01 +03:00
query["music_pos"] = query["music_pos"] + 1
2023-05-06 23:53:55 +03:00
logger.debug((len(query["query"]), query["music_pos"]))
2023-05-07 01:15:06 +03:00
if len(query["query"]) == query["music_pos"]:
asyncio.run_coroutine_threadsafe(self.end_of_query_(inter), self.bot.loop)
2023-05-03 19:53:01 +03:00
2023-05-07 01:15:06 +03:00
logger.debug([query["music_pos"]])
2023-05-03 19:53:01 +03:00
url = query["query"][query["music_pos"]]
2023-05-06 23:53:55 +03:00
self.play_(inter, url)
2023-05-03 19:53:01 +03:00
async def setup(bot):
await bot.add_cog(Music(bot))