import mutagen from mutagen import flac, id3, mp4 from mutagen.id3 import APIC, TALB, TCOM, TCOP, TDRC, TIT2, TOPE, TPE1, TRCK, TSRC, TXXX, USLT class Metadata: path_file: str title: str album: str albumartist: str artists: [str] copy_right: str tracknumber: int discnumber: int totaldisc: int totaltrack: int date: str composer: [str] isrc: str lyrics: str path_cover: str cover_data: bytes album_replay_gain: float album_peak_amplitude: float track_replay_gain: float track_peak_amplitude: float m: mutagen.mp4.MP4 | mutagen.mp4.MP4 | mutagen.flac.FLAC def __init__( self, path_file: str, album: str = "", title: str = "", artists: str = "", copy_right: str = "", tracknumber: int = 0, discnumber: int = 0, totaltrack: int = 0, totaldisc: int = 0, composer: list[str] | None = None, isrc: str = "", albumartist: str = "", date: str = "", lyrics: str = "", cover_data: bytes = None, album_replay_gain: float = 1.0, album_peak_amplitude: float = 1.0, track_replay_gain: float = 1.0, track_peak_amplitude: float = 1.0, ): self.path_file = path_file self.title = title self.album = album self.albumartist = albumartist self.artists = artists self.copy_right = copy_right self.tracknumber = tracknumber self.discnumber = discnumber self.totaldisc = totaldisc self.totaltrack = totaltrack self.date = date self.composer = composer self.isrc = isrc self.lyrics = lyrics self.cover_data = cover_data self.album_replay_gain = album_replay_gain self.album_peak_amplitude = album_peak_amplitude self.track_replay_gain = track_replay_gain self.track_peak_amplitude = track_peak_amplitude self.m: mutagen.mp4.MP4 | mutagen.flac.FLAC | mutagen.mp3.MP3 = mutagen.File(self.path_file) def _cover(self) -> bool: result: bool = False if self.cover_data: if isinstance(self.m, mutagen.flac.FLAC): flac_cover = flac.Picture() flac_cover.type = id3.PictureType.COVER_FRONT flac_cover.data = self.cover_data flac_cover.mime = "image/jpeg" self.m.clear_pictures() self.m.add_picture(flac_cover) elif isinstance(self.m, mutagen.mp3.MP3): self.m.tags.add(APIC(encoding=3, data=self.cover_data)) elif isinstance(self.m, mutagen.mp4.MP4): cover_mp4 = mp4.MP4Cover(self.cover_data) self.m.tags["covr"] = [cover_mp4] result = True return result def save(self): if not self.m.tags: self.m.add_tags() if isinstance(self.m, mutagen.flac.FLAC): self.set_flac() elif isinstance(self.m, mutagen.mp3.MP3): self.set_mp3() elif isinstance(self.m, mutagen.mp4.MP4): self.set_mp4() self._cover() self.m.save() return True def set_flac(self): self.m.tags["TITLE"] = self.title self.m.tags["ALBUM"] = self.album self.m.tags["ALBUMARTIST"] = self.albumartist self.m.tags["ARTIST"] = self.artists self.m.tags["COPYRIGHT"] = self.copy_right self.m.tags["TRACKNUMBER"] = str(self.tracknumber) self.m.tags["TRACKTOTAL"] = str(self.totaltrack) self.m.tags["DISCNUMBER"] = str(self.discnumber) self.m.tags["DISCTOTAL"] = str(self.totaldisc) self.m.tags["DATE"] = self.date self.m.tags["COMPOSER"] = ", ".join(self.composer) if self.composer else "" self.m.tags["ISRC"] = self.isrc self.m.tags["LYRICS"] = self.lyrics self.m.tags["REPLAYGAIN_ALBUM_GAIN"] = str(self.album_replay_gain) self.m.tags["REPLAYGAIN_ALBUM_PEAK"] = str(self.album_peak_amplitude) self.m.tags["REPLAYGAIN_TRACK_GAIN"] = str(self.track_replay_gain) self.m.tags["REPLAYGAIN_TRACK_PEAK"] = str(self.track_peak_amplitude) def set_mp3(self): # ID3 Frame (tags) overview: https://exiftool.org/TagNames/ID3.html / https://id3.org/id3v2.3.0 # Mapping overview: https://docs.mp3tag.de/mapping/ self.m.tags.add(TIT2(encoding=3, text=self.title)) self.m.tags.add(TALB(encoding=3, text=self.album)) self.m.tags.add(TOPE(encoding=3, text=self.albumartist)) self.m.tags.add(TPE1(encoding=3, text=self.artists)) self.m.tags.add(TCOP(encoding=3, text=self.copy_right)) self.m.tags.add(TRCK(encoding=3, text=str(self.tracknumber))) self.m.tags.add(TRCK(encoding=3, text=self.discnumber)) self.m.tags.add(TDRC(encoding=3, text=self.date)) self.m.tags.add(TCOM(encoding=3, text=", ".join(self.composer) if self.composer else "")) self.m.tags.add(TSRC(encoding=3, text=self.isrc)) self.m.tags.add(USLT(encoding=3, lang="eng", desc="desc", text=self.lyrics)) self.m.tags.add(TXXX(encoding=3, desc="REPLAYGAIN_ALBUM_GAIN", text=str(self.album_replay_gain))) self.m.tags.add(TXXX(encoding=3, desc="REPLAYGAIN_ALBUM_PEAK", text=str(self.album_peak_amplitude))) self.m.tags.add(TXXX(encoding=3, desc="REPLAYGAIN_TRACK_GAIN", text=str(self.track_replay_gain))) self.m.tags.add(TXXX(encoding=3, desc="REPLAYGAIN_TRACK_PEAK", text=str(self.track_peak_amplitude))) def set_mp4(self): self.m.tags["\xa9nam"] = self.title self.m.tags["\xa9alb"] = self.album self.m.tags["aART"] = self.albumartist self.m.tags["\xa9ART"] = self.artists self.m.tags["cprt"] = self.copy_right self.m.tags["trkn"] = [[self.tracknumber, self.totaltrack]] self.m.tags["disk"] = [[self.discnumber, self.totaldisc]] # self.m.tags['\xa9gen'] = self.genre self.m.tags["\xa9day"] = self.date self.m.tags["\xa9wrt"] = ", ".join(self.composer) if self.composer else "" self.m.tags["\xa9lyr"] = self.lyrics self.m.tags["isrc"] = self.isrc self.m.tags["----:com.apple.iTunes:REPLAYGAIN_ALBUM_GAIN"] = str(self.album_replay_gain).encode("utf-8") self.m.tags["----:com.apple.iTunes:REPLAYGAIN_ALBUM_PEAK"] = str(self.album_peak_amplitude).encode("utf-8") self.m.tags["----:com.apple.iTunes:REPLAYGAIN_TRACK_GAIN"] = str(self.track_replay_gain).encode("utf-8") self.m.tags["----:com.apple.iTunes:REPLAYGAIN_TRACK_PEAK"] = str(self.track_peak_amplitude).encode("utf-8")