diff --git a/Spotify_Music/platforms/Youtube.py b/Spotify_Music/platforms/Youtube.py index 11647b3..bee5cd8 100644 --- a/Spotify_Music/platforms/Youtube.py +++ b/Spotify_Music/platforms/Youtube.py @@ -1,3 +1,4 @@ + import asyncio import glob import os @@ -12,7 +13,7 @@ import config from Spotify_Music.utils.database import is_on_off -from Spotify_Music.utils.formatters import time_to_seconds +from Spotify_Music.utils.formatters import time_to_seconds, seconds_to_min def cookies(): @@ -24,39 +25,39 @@ def cookies(): return f"""cookies/{str(cookie_txt_file).split("/")[-1]}""" -def get_ytdl_options(ytdl_opts, commamdline=True) -> Union[str, dict, list]: - if commamdline: - if isinstance(ytdl_opts, list): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts += ["--username", "oauth2", "--password", "''"] - else: - ytdl_opts += ["--cookies", cookies()] - elif isinstance(ytdl_opts, str): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts += "--username oauth2 --password '' " - else: - ytdl_opts += f"--cookies {cookies()}" - elif isinstance(ytdl_opts, dict): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts.update({"username": "oauth2", "password": ""}) - else: - ytdl_opts["cookiefile"] = cookies() - else: - if isinstance(ytdl_opts, list): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts += ["username", "oauth2", "password", "''"] - else: - ytdl_opts += ["cookiefile", cookies()] - elif isinstance(ytdl_opts, str): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts += "username oauth2 password '' " - else: - ytdl_opts += f"cookiefile {cookies()}" - elif isinstance(ytdl_opts, dict): - if os.getenv("TOKEN_ALLOW") == True: - ytdl_opts.update({"username": "oauth2", "password": ""}) - else: - ytdl_opts["cookiefile"] = cookies() +def get_ytdl_options( + ytdl_opts: Union[str, dict, list], commandline: bool = True +) -> Union[str, dict, list]: + token_data = os.getenv("TOKEN_DATA") + + if isinstance(ytdl_opts, list): + if token_data: + ytdl_opts += [ + "--username" if commandline else "username", + "oauth2", + "--password" if commandline else "password", + "''", + ] + else: + ytdl_opts += ["--cookies" if commandline else "cookiefile", cookies()] + + elif isinstance(ytdl_opts, str): + if token_data: + ytdl_opts += ( + "--username oauth2 --password '' " + if commandline + else "username oauth2 password '' " + ) + else: + ytdl_opts += ( + f"--cookies {cookies()}" if commandline else f"cookiefile {cookies()}" + ) + + elif isinstance(ytdl_opts, dict): + if token_data: + ytdl_opts.update({"username": "oauth2", "password": ""}) + else: + ytdl_opts["cookiefile"] = cookies() return ytdl_opts @@ -76,7 +77,7 @@ async def shell_cmd(cmd): return out.decode("utf-8") -class YouTubeAPI: +class YouTube: def __init__(self): self.base = "https://www.youtube.com/watch?v=" self.regex = r"(?:youtube\.com|youtu\.be)" @@ -187,7 +188,7 @@ async def video(self, link: str, videoid: Union[bool, str] = None): else: return 0, stderr.decode() - async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None): + async def playlist(self, link, limit, videoid: Union[bool, str] = None): if videoid: link = self.listbase + link if "&" in link: @@ -212,21 +213,43 @@ async def track(self, link: str, videoid: Union[bool, str] = None): link = self.base + link if "&" in link: link = link.split("&")[0] - results = VideosSearch(link, limit=1) - for result in (await results.next())["result"]: - title = result["title"] - duration_min = result["duration"] - vidid = result["id"] - yturl = result["link"] - thumbnail = result["thumbnails"][0]["url"].split("?")[0] - track_details = { - "title": title, - "link": yturl, - "vidid": vidid, - "duration_min": duration_min, - "thumb": thumbnail, - } - return track_details, vidid + try: + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + duration_min = result["duration"] + vidid = result["id"] + yturl = result["link"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + track_details = { + "title": title, + "link": yturl, + "vidid": vidid, + "duration_min": duration_min, + "thumb": thumbnail, + } + return track_details, vidid + except Exception: + return await self._track(link) + + async def _track(self, q): + options = get_ytdl_options({ + 'format': 'best', + 'noplaylist': True, + 'quiet': True, + 'extract_flat': "in_playlist", + }) + with YoutubeDL(options) as ydl: + info_dict = ydl.extract_info(f"ytsearch: {q}", download=False) + details= info_dict.get("entries")[0] + info = { + "title": details["title"], + "link": details["url"], + "vidid": details["id"], + "duration_min": seconds_to_min(details["duration"]), + "thumb": details["thumbnails"][0]["url"], + } + return info, details["id"] async def formats(self, link: str, videoid: Union[bool, str] = None): if videoid: @@ -399,9 +422,9 @@ def song_audio_dl(): "-g", "-f", "best[height<=?720][width<=?1280]", + link, ] - command += get_ytdl_options([]) - command.append(link) + command = get_ytdl_options(command) proc = await asyncio.create_subprocess_exec( *command,