diff --git a/Constants.py b/Constants.py index bff68b4..1006293 100644 --- a/Constants.py +++ b/Constants.py @@ -21,3 +21,4 @@ FUNNY_COLOR = 696969 RESPONSES_FILE = "responses.json" +MAX_VIDEO_DOWNLOAD_SIZE: int = 80 # in MB, do not use anything other than an integer diff --git a/src/Youtube.py b/src/Youtube.py index 681e66e..aacde4d 100644 --- a/src/Youtube.py +++ b/src/Youtube.py @@ -1,9 +1,13 @@ import functools import logging +import os from queue import LifoQueue import yt_dlp +from Constants import MAX_VIDEO_DOWNLOAD_SIZE +from src.downloader import VideoDownloader, VideoFile + ydl_opts = { 'format': 'bestaudio', 'noplaylist': True, @@ -75,11 +79,11 @@ def yt_dlp_hook(progress_queue: LifoQueue, download): def youtube_download(video_url, progress_queue: LifoQueue, file_path_with_name): logging.debug(f"Downloading {video_url} to {file_path_with_name}") yt_dlp_hook_partial = functools.partial(yt_dlp_hook, progress_queue) + ydl_opts_new = ydl_opts.copy() + ydl_opts_new["outtmpl"] = file_path_with_name + ydl_opts_new["progress_hooks"] = [yt_dlp_hook_partial] - ydl_opts["outtmpl"] = file_path_with_name - ydl_opts["progress_hooks"] = [yt_dlp_hook_partial] - - with yt_dlp.YoutubeDL(ydl_opts) as ydl: + with yt_dlp.YoutubeDL(ydl_opts_new) as ydl: return ydl.download(url_list=[video_url]) @@ -88,3 +92,36 @@ def youtube_download(video_url, progress_queue: LifoQueue, file_path_with_name): def get_last_played_guilded() -> video_data_guild: return last_played + +class YoutubeDownloader(VideoDownloader): + @staticmethod + def download_video_from_link(url: str, path: str | None = None) -> list[VideoFile]: + if path is None: + path = os.path.join("downloads", "youtube") + + os.makedirs(path, exist_ok=True) + + costum_options = { + 'format': f'bestvideo[filesize<{MAX_VIDEO_DOWNLOAD_SIZE}M]+bestaudio', + "outtmpl": os.path.join(path, "%(id)s.mp4"), + 'noplaylist': True, + 'default_search': 'auto', + 'keepvideo': False, + 'nooverwrites': True, + 'quiet': True, + } + + with yt_dlp.YoutubeDL(costum_options) as ydl: + ydt = ydl.extract_info(url, download=True) + + if ydt is None: + return [] + + info = ydt.get("entries", [None])[0] or ydt + video_id = info["id"] + if video_id is None: + return [] + + file_path = os.path.join(path, f"{video_id}.mp4") + + return [VideoFile(file_path, info.get("title", None))] diff --git a/src/downloading_system.py b/src/downloading_system.py index 5272e0e..91f7360 100644 --- a/src/downloading_system.py +++ b/src/downloading_system.py @@ -1,6 +1,7 @@ import re from typing import Type +from src.Youtube import YoutubeDownloader from src.downloader import VideoDownloader from src.twitter import TwitterDownloader @@ -15,4 +16,6 @@ def get_downloader(url: str) -> Type[VideoDownloader] | None: """ if re.match(_TWITTER_REGEX, url): return TwitterDownloader + if re.match(_YOUTUBE_REGEX, url): + return YoutubeDownloader return None