from yt_dlp import YoutubeDL from yt_dlp.postprocessor import FFmpegExtractAudioPP import id3pp class _CreateYDL: @staticmethod def youtube() -> YoutubeDL: ydl = YoutubeDL({'format': 'ba'}) ydl.add_post_processor(id3pp.InfoYouTubePP(), when='before_dl') ydl.add_post_processor(FFmpegExtractAudioPP(preferredcodec='mp3'), when='post_process') return ydl @staticmethod def yt_proxied() -> YoutubeDL: ydl = _CreateYDL.youtube() ydl.params['proxy'] = 'http://127.0.0.1:1080' # TODO return ydl @staticmethod def yandex() -> YoutubeDL: return YoutubeDL() # TODO: cookies create_ydl_fn = { 'youtube': _CreateYDL.youtube, 'yt_proxied': _CreateYDL.yt_proxied, 'yandex': _CreateYDL.yandex, } ydl_fn_keys = create_ydl_fn.keys() class Downloaders: def __init__(self) -> None: self.ydls: dict[str, YoutubeDL | None] = { 'youtube': None, 'yt_proxied': None, 'yandex': None, } def get_ydl(self, site: str) -> YoutubeDL: ydl = self.ydls[site] if ydl is None: ydl = create_ydl_fn[site]() ydl.params['trim_file_name'] = 255 # TODO: config # NOTE: includes path, not only filename # artists.0 instead of artist, because it can contain "feat. ..." ydl.params['outtmpl']['default'] = 'music/%(artists.0)s/%(album)s/%(track)s.%(ext)s' ydl.add_post_processor(id3pp.ID3TagsPP(), when='post_process') return ydl def cleanup(self) -> None: for ydl in self.ydls.values(): if ydl is not None: ydl.close()