from pathlib import Path from mutagen import mp3, id3 from yt_dlp.postprocessor import PostProcessor import config import cover import genius ENC_UTF8 = 3 class InfoYouTubePP(PostProcessor): '''Generates YT Music fields in info if necessary. Must be run before downloading and post-processing with FFmpegExtractAudioPP and ID3YouTubePP, so use only with when<="before_dl" ("pre_process" also suits, see yt_dlp.utils.POSTPROCESS_WHEN) for correct file path and ID3 tags''' def run(self, information): if not 'track' in information: information['track'] = information['title'] if not 'artist' in information: information['artist'] = information['uploader'].removesuffix(' - Topic') if not 'artists' in information: information['artists'] = [information['artist']] if not 'album' in information: try: information['album'] = information['playlist'].removeprefix('Album \u2013 ') except KeyError: pass if not 'track_number' in information: try: information['track_number'] = information['playlist_index'] except KeyError: pass # here was some code for disc_number, # but it is even not in mutagen ID3 fields list return [], information class ID3TagsPP(PostProcessor): '''Inserts ID3 tags after all PPs (for YT: InfoYouTubePP and FFmpegExtractAudioPP), triggers searching and parsing lyrics from Genius''' def __init__(self) -> None: self.cfg = config.get() super().__init__() def run(self, information): file = mp3.MP3(information['filepath']) title = information['track'] artists: list[str] = information['artists'] file['TIT2'] = id3.TIT2(encoding=ENC_UTF8, text=title) file['TPE1'] = id3.TPE1(encoding=ENC_UTF8, text=artists) # multiple values are null-separated if 'album' in information: file['TALB'] = id3.TALB(encoding=ENC_UTF8, text=information['album']) if 'release_year' in information: file['TDRC'] = id3.TDRC(encoding=ENC_UTF8, text=str(information['release_year'])) if 'track_number' in information: file['TRCK'] = id3.TRCK(encoding=ENC_UTF8, text=str(information['track_number'])) if 'genre' in information: file['TCON'] = id3.TCON(encoding=ENC_UTF8, text=information['genre']) if self.cfg.save_lyrics: try: lyr_title, lyr_url = genius.search(title, artists[0]) genius.raise_on_irrelevant_result(lyr_title, title, artists[0]) file['USLT'] = id3.USLT(encoding=ENC_UTF8, text=genius.parse(lyr_url)) except: pass file.save() if self.cfg.save_cover: try: album_path = Path(information['filepath']).parent if 'youtube' in information['extractor']: cover.download_from_yt(information['thumbnail'], album_path) else: cover.download(information['thumbnail'], album_path) except: pass return [], information