music play + now playing
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
from .discordPlayer import DiscordPlayer
|
||||
from .downloader import Downloader
|
||||
from .redis import Redis
|
||||
from .spotify import Spotify
|
||||
|
40
framework/discordPlayer.py
Normal file
40
framework/discordPlayer.py
Normal file
@ -0,0 +1,40 @@
|
||||
from discord import FFmpegOpusAudio, VoiceChannel, VoiceClient
|
||||
|
||||
from entity import File
|
||||
|
||||
|
||||
class DiscordPlayer:
|
||||
def __init__(self) -> None:
|
||||
self.clients: dict[int, VoiceClient] = {}
|
||||
self.timeout = 60
|
||||
|
||||
async def connect(self, guildId: int, voiceChannel: VoiceChannel) -> None:
|
||||
if (
|
||||
guildId not in self.clients
|
||||
or self.clients[guildId] is None
|
||||
or not self.clients[guildId].is_connected()
|
||||
):
|
||||
self.clients[guildId] = await voiceChannel.connect(timeout=self.timeout)
|
||||
print(f"connect to {voiceChannel.name}")
|
||||
|
||||
async def disconnect(self, guildId: int) -> None:
|
||||
if guildId in self.clients and self.clients[guildId].is_connected():
|
||||
await self.clients[guildId].disconnect()
|
||||
|
||||
def play(
|
||||
self, guildId: int, file: File | str, seekTime: int = 0, after=None
|
||||
) -> None:
|
||||
self.clients[guildId].play(
|
||||
FFmpegOpusAudio(
|
||||
file.name if isinstance(file, File) else file,
|
||||
bitrate=256,
|
||||
before_options="-ss %d" % seekTime,
|
||||
options="-vn",
|
||||
),
|
||||
after=lambda error: self.clients[guildId].loop.create_task(after(error))
|
||||
if after is not None
|
||||
else None,
|
||||
)
|
||||
|
||||
def stop(self, guildId) -> None:
|
||||
self.clients[guildId].stop()
|
@ -1,47 +1,34 @@
|
||||
import pickle
|
||||
from logging import Logger
|
||||
|
||||
import redis.asyncio as redis
|
||||
from redis.asyncio.lock import Lock
|
||||
from redis.asyncio import Redis as RedisClient
|
||||
|
||||
from config import RedisConfig
|
||||
|
||||
|
||||
class Redis:
|
||||
def __init__(self, logger: Logger, config: RedisConfig, rootKeyName: str) -> None:
|
||||
self._client = redis.Redis(
|
||||
self.client: RedisClient = RedisClient(
|
||||
host=config.host,
|
||||
port=config.port,
|
||||
password=config.password,
|
||||
auto_close_connection_pool=False,
|
||||
)
|
||||
self._locks: dict[str, Lock] = {}
|
||||
self.rootKeyName = rootKeyName
|
||||
self.logger = logger
|
||||
|
||||
async def _get_lock(self, key) -> Lock:
|
||||
if key not in self._locks:
|
||||
self._locks[key] = self._client.lock(key)
|
||||
return self._locks[key]
|
||||
|
||||
async def acquire(self, key: str) -> None:
|
||||
lock = await self._get_lock(f"{self.rootKeyName}:queue:{key}")
|
||||
await lock.acquire()
|
||||
|
||||
async def release(self, key: str) -> None:
|
||||
lock = await self._get_lock(f"{self.rootKeyName}:queue:{key}")
|
||||
await lock.release()
|
||||
|
||||
async def get(self, key: str):
|
||||
async def get(self, context: str, key: str):
|
||||
self.logger.info(f"get value {key} from redis")
|
||||
value = await self._client.get(f"{self.rootKeyName}:queue:{key}")
|
||||
value = await self.client.get(f"{self.rootKeyName}:{context}:{key}")
|
||||
if value:
|
||||
return pickle.loads(value)
|
||||
return None
|
||||
|
||||
async def set(self, key: str, value) -> None:
|
||||
async def set(self, context: str, key: str, value) -> None:
|
||||
self.logger.info(f"set value {key} to redis")
|
||||
await self._client.set(f"{self.rootKeyName}:queue:{key}", pickle.dumps(value))
|
||||
await self.client.set(
|
||||
f"{self.rootKeyName}:{context}:{key}", pickle.dumps(value)
|
||||
)
|
||||
|
||||
async def close(self) -> None:
|
||||
await self._client.close()
|
||||
await self.client.close()
|
||||
|
@ -21,5 +21,10 @@ class Spotify:
|
||||
|
||||
async def getTrack(self, url: str):
|
||||
return await self.loop.run_in_executor(
|
||||
None, lambda: self.client.track(url, self.region)
|
||||
None, lambda: self.client.track(url, market=self.region)
|
||||
)
|
||||
|
||||
async def getPlaylist(self, url: str):
|
||||
return await self.loop.run_in_executor(
|
||||
None, lambda: self.client.playlist(url, market=self.region)
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ class Youtube:
|
||||
self.params = {
|
||||
"format": "bestaudio/best",
|
||||
"outtmpl": path.join(downloadDirectory, "%(id)s"),
|
||||
"updatetime": False,
|
||||
"restrictfilenames": True,
|
||||
"noplaylist": True,
|
||||
"ignoreerrors": True,
|
||||
@ -37,7 +38,7 @@ class Youtube:
|
||||
videosSearch = VideosSearch(
|
||||
query, limit=1, language=self.language, region=self.region
|
||||
)
|
||||
return await videosSearch.next()
|
||||
return (await videosSearch.next())["result"]
|
||||
|
||||
async def fetchData(self, url: str):
|
||||
info = await self.loop.run_in_executor(
|
||||
@ -66,7 +67,7 @@ class Youtube:
|
||||
),
|
||||
)
|
||||
|
||||
async def download(self, url: str, fileName: str, progress=None) -> None:
|
||||
async def download(self, url: str, fileName: str, progress=None) -> File:
|
||||
if progress is not None:
|
||||
progress_hook = lambda status: self.downloadProgress(progress, status)
|
||||
self.client.add_progress_hook(progress_hook)
|
||||
|
Reference in New Issue
Block a user