diff --git a/BrandrdXMusic/platforms/Youtube.py b/BrandrdXMusic/platforms/Youtube.py index 61126de8..36a44678 100644 --- a/BrandrdXMusic/platforms/Youtube.py +++ b/BrandrdXMusic/platforms/Youtube.py @@ -1,6 +1,8 @@ -import asyncio import os import re +import asyncio +import aiohttp +import requests from typing import Union import yt_dlp @@ -344,3 +346,137 @@ def song_audio_dl(): direct = True downloaded_file = await loop.run_in_executor(None, audio_dl) return downloaded_file, direct + + +class YTM: + def __init__(self): + self.base = "https://www.youtube.com/watch?v=" + self.regex = r"(?:youtube\.com|youtu\.be)" + self.status = "https://www.youtube.com/oembed?url=" + self.listbase = "https://youtube.com/playlist?list=" + self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + + async def download( + self, + link: str, + mystic, + video: Union[bool, str] = None, + videoid: Union[bool, str] = None, + songaudio: Union[bool, str] = None, + songvideo: Union[bool, str] = None, + format_id: Union[bool, str] = None, + title: Union[bool, str] = None, + ) -> str: + if videoid: + vidid = link + else: + pattern = r"(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/|v\/|live_stream\?stream_id=|(?:\/|\?|&)v=)?([^&\n]+)" + match = re.search(pattern, link) + vidid = match.group(1) + + async def audio_dl(url): + async with aiohttp.ClientSession() as session: + async with session.request( + method="GET", url=url, allow_redirects=True + ) as response: + file_path = os.path.join("downloads", f"{vidid}.webm") + with open(file_path, "wb") as file: + while True: + chunk = await response.content.read(1024 * 1024 * 100) + if not chunk: + break + file.write(chunk) + return file_path + + async def song_audio_dl(url): + async with aiohttp.ClientSession() as session: + async with session.request( + method="GET", url=url, allow_redirects=True + ) as response: + file_path = os.path.join("downloads", f"{vidid}.mp4") + with open(file_path, "wb") as file: + while True: + chunk = await response.content.read(1024 * 1024 * 1024) + if not chunk: + break + file.write(chunk) + + file_name, file_extension = os.path.splitext(file_path) + audio_file_path = os.path.join("downloads", f"{file_name}.mp3") + + cmd = f"ffmpeg -i {file_path} -b:a 192K {audio_file_path}" + process = await asyncio.create_subprocess_shell( + cmd, + shell=True, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await process.communicate() + if process.returncode != 0: + print(f"Error: {stderr.decode()}") + os.remove(file_path) + return audio_file_path + + file.write(chunk) + return file_path + + async def video_dl(url): + async with aiohttp.ClientSession() as session: + async with session.request( + method="GET", url=url, allow_redirects=True + ) as response: + file_path = os.path.join("downloads", f"{vidid}.mp4") + with open(file_path, "wb") as file: + while True: + chunk = await response.content.read(1024 * 1024 * 1024) + if not chunk: + break + file.write(chunk) + + return file_path + + async def song_video_dl(url): + async with aiohttp.ClientSession() as session: + async with session.request( + method="GET", url=url, allow_redirects=True + ) as response: + file_path = os.path.join("downloads", f"{vidid}.mp4") + with open(file_path, "wb") as file: + while True: + chunk = await response.content.read(1024 * 1024 * 1024) + if not chunk: + break + file.write(chunk) + + return file_path + + response = requests.get( + f"https://pipedapi-libre.kavin.rocks/streams/{vidid}" + ).json() + loop = asyncio.get_running_loop() + if songvideo: + url = response.get("videoStreams", [])[-1]["url"] + fpath = await loop.run_in_executor( + None, lambda: asyncio.run(song_video_dl(url)) + ) + return fpath + elif songaudio: + url = response.get("videoStreams", [])[-1]["url"] + fpath = await loop.run_in_executor( + None, lambda: asyncio.run(song_audio_dl(url)) + ) + return fpath + elif video: + url = response.get("videoStreams", [])[-1]["url"] + direct = True + downloaded_file = await loop.run_in_executor( + None, lambda: asyncio.run(video_dl(url)) + ) + else: + url = response.get("audioStreams", [])[4]["url"] + direct = True + downloaded_file = await loop.run_in_executor( + None, lambda: asyncio.run(audio_dl(url)) + ) + + return downloaded_file, direct \ No newline at end of file