def write_basic_tags(self, modify_tags, set_artist_to_album, set_version): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if modify_tags: if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if set_artist_to_album: audio.tags['artist'] = self.album if type(audio) is EasyMP3: audio.save(v2_version=set_version) else: # Not actually audio audio.save()
def generate_music(self): if 'audio' in self.attachments_types: log.info('[AP] Извлечение аудио...') user_id = self.api_vk.users.get()[0]['id'] response = self.audio_session._vk.http.get(self.post_url) tracks = scrap_data(response.text, user_id, filter_root_el={'class': 'audios_list'}) for track in tracks: name = sub(r"[^a-zA-Z '#0-9.а-яА-Я()-]", '', track['artist'] + ' - ' + track['title'] + '.mp3') try: file = download(track['url'], out=name) except (urllib.error.URLError, IndexError): log.exception( '[AP] Не удалось скачать аудиозапись. Пропускаем ее...' ) continue if getsize(file) > 52428800: log.warning( '[AP] Файл весит более 50 МиБ. Пропускаем его...') continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = track['title'] music['artist'] = track['artist'] music.save() del music self.tracks.append((name, track['duration']))
def generate_music(self): if 'attachments' in self.post: log.info('[AP] Извлечение аудио...') log.info('[AP] Данная функция находится в стадии тестирования.') n = 0 session.http.cookies.update(dict(remixmdevice=self.remixmdevice)) user_id = api_vk.users.get()[0]['id'] for attachment in self.post['attachments']: if attachment['type'] == 'audio': post_url = 'https://m.vk.com/wall%(owner_id)s_%(id)s' % self.post soup = BeautifulSoup(session.http.get(post_url).text, 'html.parser') track_list = [decode_audio_url(track.get('value'), user_id) for track in soup.find_all(type='hidden') if 'mp3' in track.get('value')] dur_list = [dur.get('data-dur') for dur in soup.find_all('div') if dur.get('data-dur')] name = sub(r"[/\"?:|<>*]", '', attachment['audio']['artist'] + ' - ' + attachment['audio']['title'] + '.mp3') try: file = download(track_list[n], out=name) except urllib.error.URLError: continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = attachment['audio']['title'] music['artist'] = attachment['audio']['artist'] music.save() del music self.tracks.append((name, dur_list[n])) n += 1
def generate_music(self): if 'audio' in self.attachments_types: log.info('[AP] Извлечение аудио...') n = 0 self.session.http.cookies.update(dict(remixmdevice=self.remixmdevice)) user_id = self.api_vk.users.get()[0]['id'] for attachment in self.post['attachments']: if attachment['type'] == 'audio': post_url = 'https://m.vk.com/wall%(owner_id)s_%(id)s' % self.post soup = BeautifulSoup(self.session.http.get(post_url).text, 'html.parser') track_list = [decode_audio_url(track.get('value'), user_id) for track in soup.find_all(type='hidden') if 'mp3' in track.get('value')] dur_list = [dur.get('data-dur') for dur in soup.find_all('div') if dur.get('data-dur')] name = sub(r"[/\"?:|<>*]", '', attachment['audio']['artist'] + ' - ' + attachment['audio']['title'] + '.mp3') try: file = download(track_list[n], out=name) except (urllib.error.URLError, IndexError): log.exception('[AP] Не удалось скачать аудиозапись. Пропускаем ее...') continue if getsize(file) > 52428800: log.warning('[AP] Файл весит более 50 МиБ. Пропускаем его...') continue try: music = EasyID3(file) except id3.ID3NoHeaderError: music = File(file, easy=True) music.add_tags() music['title'] = attachment['audio']['title'] music['artist'] = attachment['audio']['artist'] music.save() del music self.tracks.append((name, dur_list[n])) n += 1
def add_metadata(filename: str, args): """Add metadata to an existing file.""" f = File(filename) f.add_tags() for title, tag in METADATA_FIELDS.items(): f.tags.add(tag(encoding=Encoding.UTF8, text=[getattr(args, title)])) f.save()
def ensure_id3_tag_present(filepath): try: meta = EasyID3(filepath) except ID3NoHeaderError: meta = File(filepath, easy=True) meta.add_tags() meta.save()
def write_info2file(self, info): # open file with mutagen audio = File(info['filename'], easy=True) if audio is None: return # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if info['album'] is not None: audio.tags['album'] = info['album'] if info['title'] is not None: audio.tags['title'] = info['title'] # write genre tag if self.container.config.genre_tag is not None: audio.tags['genre'] = self.container.config.genre_tag else: audio.tags['genre'] = '' # write pubDate if info['pubDate'] is not None: audio.tags['date'] = info['pubDate'] audio.save()
def write_basic_tags(self, modify_tags, set_artist_to_album, set_version): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if modify_tags: if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.subtitle is not None: audio.tags['subtitle'] = self.subtitle if self.subtitle is not None: audio.tags['comments'] = self.subtitle if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if set_artist_to_album: audio.tags['artist'] = self.album if type(audio) is EasyMP3: audio.save(v2_version=set_version) else: # Not actually audio audio.save()
def postProcessSong(self, song): if self.shouldGenerateTags: try: name = self.getSongPath(song) localList = song.name.split("- ") #The song should be split as "artist - title". If not, it won't be recognized artist = localList[0] if len(localList) > 1 else self.defaultArtist #The artist is usually first if its there. Otherwise no artist if self.allSongsDefaultArtist: artist = self.defaultArtist title = localList[1] if len(localList) > 1 else localList[0] #If there is no artist, the whole name is the title artist = artist.lstrip().rstrip() title = title.lstrip().rstrip() #Appreciate this. It took upwards of 5 hours to get the damn software to do this. try: songID = EasyID3(name) except ID3NoHeaderError: songID = MutagenFile(name, easy = True) songID.add_tags() songID['artist'] = artist songID['title'] = title songID.save() songID = ID3(name, v2_version=3) #EasyID3 doesn't support saving as 2.3 to get Windows to recognize it songID.update_to_v23() songID.save(v2_version=3) except FileNotFoundError: debug("File not found for: ", name)
def set_OPUS_data(song, song_path): """ Set the data into an OPUS container according to the passed data. """ COVER_ADDED = False try: SONG_PATH = os.path.join(defaults.DEFAULT.SONG_TEMP_DIR, song_path) mutagen_file = File(SONG_PATH) # Try adding the tags container try: mutagen_file.add_tags() except Exception: # If exception is thrown, the tags already exist pass # Clear out the tags from the file mutagen_file.clear() # Try adding the cover if dwCover(song): imagedata = open(defaults.DEFAULT.COVER_IMG, 'rb').read() picture = Picture() picture.data = imagedata picture.type = PictureType.COVER_FRONT picture.mime = "image/jpeg" encoded_data = b64encode(picture.write()) mutagen_file["metadata_block_picture"] = encoded_data.decode( "ascii") # Remove the image os.remove(defaults.DEFAULT.COVER_IMG) COVER_ADDED = True # Add the tags now # Refer to https://www.programcreek.com/python/example/63675/mutagen.File # for more information on it mutagen_file["Title"] = song.track_name mutagen_file["Album"] = song.collection_name mutagen_file["Artist"] = song.artist_name mutagen_file["Date"] = song.release_date mutagen_file["Genre"] = song.primary_genre_name mutagen_file.save() defaults.DEFAULT.SONG_NAME_TO_SAVE = song.track_name + '.opus' # Rename the downloaded file os.rename(SONG_PATH, os.path.join( defaults.DEFAULT.SONG_TEMP_DIR, defaults.DEFAULT.SONG_NAME_TO_SAVE )) return COVER_ADDED except Exception as e: return e
def set_track_metadata(self, track = None, filename = None, url = None): """Find and set all metadata for a track""" if url == None or track == None: return None if filename == None: filename = get_track_filename(url) # id3 is only for mp3 if not filename.endswith(".mp3"): if filename.endswith(".wav"): filename = self.convert_wav_to_mp3(filename) else: return None # Set title try: meta = ID3(filename) except ID3NoHeaderError: try: meta = File(filename, easy=True) meta.add_tags() meta.save() meta = ID3(filename) except: return except IOError: return try: meta.add(TIT2(encoding=3, text=track.title)) meta.add(TCON(encoding=3, text=track.genre)) meta.add(TCOM(encoding=3, text=track.user["username"])) meta.save() artwork_filename = wget.download(track.artwork_url) audio = MP3(filename, ID3=ID3) # add ID3 tag if it doesn't exist try: audio.add_tags() except error: pass audio.tags.add( APIC( encoding=3, # 3 is for utf-8 mime='image/jpeg', # image/jpeg or image/png type=3, # 3 is for the cover image desc=u'Cover', data=open(artwork_filename).read() ) ) audio.save() except: return
def add_tags(self): self.logger.debug("Started adding tags to YouTube tracks") tag_count = 0 downloaded_track: DownloadedTrack for downloaded_track in self.all_tracks_to_download: if "name" in downloaded_track.youtube_tags: file_path = Path(downloaded_track.youtube_tags["filepath"]) try: tagged_file = ID3() except mutagen.id3.ID3NoHeaderError: tagged_file = File() tagged_file.add_tags() tagged_file.save() tagged_file = ID3() if downloaded_track.youtube_tags["name"]: tagged_file["TIT2"] = TIT2( encoding=3, text=downloaded_track.youtube_tags["name"]) if downloaded_track.youtube_tags["track_number"]: try: tagged_file["TRCK"] = TRCK( encoding=3, text=str( downloaded_track.youtube_tags["track_number"])) except: tagged_file["TRCK"] = TRCK(encoding=3, text=u"1") if downloaded_track.youtube_tags["album"]: tagged_file["TALB"] = TALB( encoding=3, text=downloaded_track.youtube_tags["album"]) if downloaded_track.youtube_tags["artist"]: tagged_file["TPE1"] = TPE1( encoding=3, text=downloaded_track.youtube_tags["artist"]) tagged_file.save(file_path) while True: try: file_path.rename(file_path) except: continue break new_path = Path(file_path.parent / Path( util.clean_path_child( f"{downloaded_track.youtube_tags['artist']} - {downloaded_track.youtube_tags['name']}.mp3" ))) os.rename(file_path, new_path) downloaded_track.download_location = new_path downloaded_track.store_to_master_file() tag_count += 1 self.logger.debug( f"Finished adding tags to {tag_count} YouTube tracks")
def tag_file(filename, **kwargs): """Use mutagen to tag MP3 files.""" try: tag = EasyID3(filename) except ID3NoHeaderError: tag = File(filename, easy=True) tag.add_tags() for arg, value in kwargs.items(): tag[arg] = value tag.save(filename)
def get_tag(args): abs_path = os.path.abspath(args.path) try: id3_tag = easyid3.EasyID3(abs_path) except id3.ID3NoHeaderError: id3_tag = File(abs_path, easy=True) id3_tag.add_tags() id3_tag.save() return id3_tag
def get_id3_tags(self, file_name): try: self.audio_id3 = ID3(self.search_dir + "/" + file_name, v2_version=3) except _util.ID3NoHeaderError: file = File(self.search_dir + "/" + file_name) file.add_tags() file.save() self.audio_id3 = ID3(self.search_dir + "/" + file_name, v2_version=3) for tag in self.audio_id3: if tag.startswith("APIC") and (PictureType.COVER_FRONT == 3): image = QImage() image.loadFromData(self.audio_id3[tag].data) self.artwork_id3_label.setPixmap( QPixmap(image).scaled(150, 150)) break else: #TODO: default image should be stored as raw data self.artwork_id3_label.setPixmap(QPixmap("default.jpg")) if "TPE1" in self.audio_id3: self.artist_id3_edit.setText(str(self.audio_id3["TPE1"])) else: self.artist_id3_edit.clear() if "TIT2" in self.audio_id3: self.title_id3_edit.setText(str(self.audio_id3["TIT2"])) else: self.title_id3_edit.clear() if "TCON" in self.audio_id3: self.genre_id3_edit.setText(str(self.audio_id3["TCON"])) else: self.genre_id3_edit.clear() if "TALB" in self.audio_id3: self.album_id3_edit.setText(str(self.audio_id3["TALB"])) else: self.album_id3_edit.clear() if "TYER" in self.audio_id3: self.release_year_id3_edit.setText(str(self.audio_id3["TYER"])) else: self.release_year_id3_edit.clear() if "TRCK" in self.audio_id3: self.track_no_id3_edit.setText(str(self.audio_id3["TRCK"])) else: self.track_no_id3_edit.clear()
def on_episode_downloaded(self, episode): # exit if mutagen is not installed if not mutagen_installed: return # read filename (incl. file path) from gPodder database filename = episode.local_filename(create=False, check_only=True) if filename is None: return # open file with mutagen audio = File(filename, easy=True) if audio is None: return # read title+album from gPodder database album = episode.channel.title title = episode.title if (strip_album_from_title and title and album and title.startswith(album)): title = title[len(album):].lstrip() # convert pubDate to string try: pubDate = datetime.datetime.fromtimestamp( episode.pubDate).strftime('%Y-%m-%d %H:%M') except: pubDate = None # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if album is not None: audio.tags['album'] = album if title is not None: audio.tags['title'] = title # write genre tag if genre_tag is not None: audio.tags['genre'] = genre_tag else: audio.tags['genre'] = '' # write pubDate if pubDate is not None: audio.tags['date'] = pubDate audio.save() log(u'tagging.on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title))
class Tagging: def __init__(self, io): """ """ try: self.fileObj = io if self.fileObj.url.rsplit('.')[-1] != 'mp3': raise ExtensionException('Not Expecting file extension') self.audio = EasyID3(self.fileObj.path) except mutagen.id3.ID3NoHeaderError as err: self.audio = File(self.fileObj.path, easy=True) self.audio.add_tags() self.audio.save(self.fileObj.path, v1=2) except (mutagen.MutagenError, ExtensionException) as err: self.audio = None def add_tag(self, tags, image): if tags is not None: for key, value in tags.items(): if value is not None or value != '': if key != 'cover': self.audio[u'{}'.format(key)] = value self.audio.save(self.fileObj.path, v1=2) if image is not None: img = image.path fileObj = open(img.path, 'rb').read() img_ext = img.name.rsplit('.')[-1] multipart = [('jpg', 'image/jpeg'), ('png', 'image/png'), ('jpeg', 'image/jpeg')] img_typ = '' for typ in multipart: if img_ext in typ: img_typ = typ[1] break id3 = ID3(self.fileObj.path) id3.add(APIC(3, img_typ, 3, 'Front Cover', fileObj)) id3.save(v2_version=3) def tags(self): tags = {} if self.audio is not None: for key, value in self.audio.items(): tags[key] = value[0] return tags
def tag(input_file, metadata): try: audio = EasyID3(input_file) except ID3NoHeaderError: # If file does not currently have an id3 header # then create one. audio = File(input_file, easy=True) audio.add_tags() audio['title'] = metadata['title'] audio['artist'] = metadata['artist'] audio['album'] = metadata['album'] audio.save()
def update_id3_tags(self): """ Update ID3 tags of downloaded song """ # Must init ID3 tags for appropriate header settings audio = File(self.tags._title+'.mp3', easy=True) audio.add_tags() # Save new tags audio['title'] = self.tags._title audio['artist'] = self.tags._artist audio['album'] = self.tags._album audio.save(self.tags._title+'.mp3')
def on_episode_downloaded(self, episode): # exit if mutagen is not installed if not mutagen_installed: return # read filename (incl. file path) from gPodder database filename = episode.local_filename(create=False, check_only=True) if filename is None: return # open file with mutagen audio = File(filename, easy=True) if audio is None: return # read title+album from gPodder database album = episode.channel.title title = episode.title if (strip_album_from_title and title and album and title.startswith(album)): title = title[len(album):].lstrip() # convert pubDate to string try: pubDate = datetime.datetime.fromtimestamp(episode.pubDate).strftime('%Y-%m-%d %H:%M') except: pubDate = None # write title+album information into audio files if audio.tags is None: audio.add_tags() # write album+title if album is not None: audio.tags['album'] = album if title is not None: audio.tags['title'] = title # write genre tag if genre_tag is not None: audio.tags['genre'] = genre_tag else: audio.tags['genre'] = '' # write pubDate if pubDate is not None: audio.tags['date'] = pubDate audio.save() log(u'tagging.on_episode_downloaded(%s/%s)' % (episode.channel.title, episode.title))
def download(self, path: str, web_driver: WebDriver = None, service_url: str = '', lyrics='', website='', comment=''): file_path = super().download(path) try: meta = id3.ID3(file_path) except id3.ID3NoHeaderError: meta = File(file_path) meta.add_tags() if web_driver: lyrics = self.load_lyrics(web_driver) meta['TPE1'] = id3._frames.TPE1(text=[self.artist]) meta['TIT2'] = id3._frames.TIT2(text=[self.title]) meta['USLT'] = id3._frames.USLT(text=lyrics) meta['WORS'] = id3._frames.WORS(text=[website]) meta['COMM'] = id3._frames.COMM(text=[comment]) meta.save() return file_path
def UpdateDetails(audio, details): """ Update the metadata of the files. """ keys = details.keys() print("Updating metadata for " + audio) if 'album_art' in keys: img = requests.get(details['album_art'], stream=True) img = img.raw file = File(audio) try: file.add_tags() except _util.error: pass file.tags.add( APIC( encoding=3, # UTF-8 mime='image/png', type=3, # 3 is for album art desc='covr', data=img.read() # Reads and adds album art )) file.save() file = EasyMP3(audio) if 'artist' in keys: file["artist"] = (details['artist']) file["albumartist"] = details['artist'] if 'title' in keys: file["title"] = details['title'] if 'album' in keys: file["album"] = details['album'] file.save() print("Current tags:", file.tags) file = ID3(audio) if 'lyrics' in keys: file[u"USLT::'en'"] = (USLT(encoding=3, lang=u'eng', desc=u'desc', text=details['lyrics'])) file.save() print("Done!")
def write_basic_tags(self): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate audio.save()
def write_basic_tags(self): audio = File(self.filename, easy=True) if audio.tags is None: audio.add_tags() if self.album is not None: audio.tags['album'] = self.album if self.title is not None: audio.tags['title'] = self.title if self.genre is not None: audio.tags['genre'] = self.genre if self.pubDate is not None: audio.tags['date'] = self.pubDate if self.container.config.set_artist_to_album: audio.tags['artist'] = self.album audio.save()
def main(): parser = argparse.ArgumentParser( 'Change or manipulate the ID3 tags of the audio files') parser.add_argument('--track', '-n', type=int, default=None, help='set the track number') parser.add_argument('--track-total', '-N', type=int, default=None, help='set total number of tracks') parser.add_argument('--artist', '-a', default=None, help='set the artist name') parser.add_argument('--album', '-A', default=None, help='set the album name') parser.add_argument('--title', '-t', default=None, help='set the title name') parser.add_argument('--wors', '-r', default=None, help='set the internet radio url') parser.add_argument('--year', '-Y', default=None, help='set the release year') parser.add_argument('--cover', '-c', default=None, help='set the cover image') parser.add_argument('--format', '-f', default=None, help='return the ID3 information as a formatted' '''string; the format string should containing one or more''' ''' of the following specifiers: , {track} , {artist} , {title} , {album} , {year} , {kbps} , {wors} , {len} (the length of the audio file, in seconds) , {path} (the absolute path of the file)''') parser.add_argument('--separator', '-s', default='\n', help='define the separator used to append at the end' ' of the output for each file (excluding the last' ' file)') parser.add_argument('--escape', '-e', default='', help='define the characters that should be escaped in' ' all the outputed fields') parser.add_argument('audiofile', nargs='+', help='an audio file containing the ID3 tags') args = parser.parse_args() # input section to_track = args.track to_track_total = args.track_total to_artist = args.artist to_album = args.album to_title = args.title to_wors = args.wors to_year = args.year to_cover = args.cover if to_cover is not None: cover_ext = os.path.splitext(to_cover)[1] # print("Cover path is "+to_cover) import mimetypes mimetypes.init() to_cover_mime = mimetypes.types_map[cover_ext] # print("Mime type is "+to_cover_mime) # output section outputs = [] formatstr = args.format escapepat = "" delimiter = '' for c in args.escape: esc = '' if c in r'()[]\^$.|?*+{}': esc = '\\' escapepat = escapepat + delimiter + esc + c delimiter = '|' to_escape = False if escapepat != '': to_escape = True escapepat = '(%s)' % escapepat separator = args.separator def getinfo(file_): try: return (file_.info.bitrate / 1000, int(round(file_.info.length))) except: return (0, 0) for f in args.audiofile: path = os.path.realpath(f) artist = title = album = year = wors = "" file_ = File(f) kbps, len_ = getinfo(file_) try: if (type(file_) == MP3): # add ID3 tag if it doesn't exist try: file_.add_tags() except: pass # should we set the tag in anyway? if to_track is not None or to_track_total is not None: old = (0, 0) if 'TRCK' in file_: try: old = tuple( map(int, file_['TRCK'].text[0].split('/'))) old = (old + (0, 0))[:2] except: pass if to_track is None: to_track = old[0] if to_track_total is None: to_track_total = old[1] file_['TRCK'] = TRCK( encoding=3, text='%02d' % to_track + ' / %02d' % to_track_total if to_track_total else '') if to_track == 0 and to_track_total == 0: del file_['TRCK'] if to_artist is not None: file_['TPE1'] = TPE1(encoding=3, text=to_artist) if to_album is not None: file_['TALB'] = TALB(encoding=3, text=to_album) if to_title is not None: file_['TIT2'] = TIT2(encoding=3, text=to_title) if to_wors is not None: file_['WORS'] = WORS(url=to_wors) if to_year is not None: file_['TDRL'] = TDRL(encoding=3, text=to_year) if to_cover is not None: # print('The image data is '+open(to_cover).read()) file_['APIC:'] = APIC(encoding=3, mime=to_cover_mime, type=3, data=open(to_cover).read()) file_.save() # process mp3 specific tag information track = file_['TRCK'].text[0] if 'TRCK' in file_ \ else '' artist = file_['TPE1'].text[0] if 'TPE1' in file_ \ else '' album = file_['TALB'].text[0] if 'TALB' in file_ \ else '' title = file_['TIT2'].text[0] if 'TIT2' in file_ \ else '' wors = file_['WORS'].url if 'WORS' in file_ else '' year = file_['TDRL'].text[0] if 'TDRL' in file_ else '' elif (type(file_) == MP4): # should we set the tag in anyway? if to_track is not None or to_track_total is not None: old = (0, 0) if 'trkn' in file_: try: old = tuple(map(int, file_['trkn'][0])) old = (old + (0, 0))[:2] except: pass if to_track is None: to_track = old[0] if to_track_total is None: to_track_total = old[1] file_['trkn'] = [(to_track, to_track_total)] if to_track == 0 and to_track_total == 0: del file_['trkn'] if to_artist is not None: file_['\xa9ART'] = [to_artist] if to_album is not None: file_['\xa9alb'] = [to_album] if to_title is not None: file_['\xa9nam'] = [to_title] if to_year is not None: file_['\xa9day'] = [to_year] if to_cover is not None: file_['covr'] = [open(to_cover).read()] file_.save() track = '%02d / %02d' % file_['trkn'][0] if 'trkn' in file_ \ else '' artist = file_['\xa9ART'][0] if '\xa9ART' in file_ \ else '' album = file_['\xa9alb'][0] if '\xa9alb' in file_ \ else '' title = file_['\xa9nam'][0] if '\xa9nam' in file_ \ else '' year = file_['\xa9day'][0] if '\xa9day' in file_ \ else '' except: pass reps = { 'track': track, 'artist': artist, 'title': title, 'album': album, 'year': year, "kbps": kbps, 'wors': wors, 'len': len_, 'path': path } if to_escape: for k in reps: reps[k] = re.sub(escapepat, r'\\\1', u"%s" % reps[k]) if formatstr is not None: outputs.append(formatstr.format(**reps)) output = separator.join(outputs) print(output, end='')
class TagTool(object): def __init__(self, filePath): if os.path.isfile(filePath) is False: return self._filepath = filePath self._ext = __extension__(filePath) self._handle = File(filePath) self.title = '' self.album = '' self.albumartist = '' self.artist = '' self.copyright = '' self.tracknumber = '' self.totaltrack = '' self.discnumber = '' self.totaldisc = '' self.genre = '' self.date = '' self.composer = '' self.isrc = '' self.lyrics = '' self.__load__() def save(self, coverPath: str = None): try: if 'mp3' in self._ext: return self.__saveMp3__(coverPath) if 'flac' in self._ext: return self.__saveFlac__(coverPath) if 'mp4' in self._ext or 'm4a' in self._ext: return self.__saveMp4__(coverPath) return False except Exception as e: return False, str(e) def addPic(self, converPath: str = None): try: self.__savePic__(converPath) self._handle.save() return True except Exception as e: return False, str(e) def addLyrics(self, lyrics: str = None): try: if 'mp3' in self._ext: self._handle.tags.add( USLT(encoding=3, lang=u'eng', desc=u'desc', text=__tryStr__(self.lyrics))) if 'flac' in self._ext: self._handle.tags['lyrics'] = __tryStr__(self.lyrics) if 'mp4' in self._ext or 'm4a' in self._ext: self._handle.tags['\xa9lyr'] = __tryStr__(self.lyrics) self._handle.save() return True except Exception as e: return False, str(e) def __load__(self): try: if 'mp3' in self._ext: return self.__getMp3__() if 'flac' in self._ext: return self.__getFlac__() if 'mp4' in self._ext or 'm4a' in self._ext: return self.__getMp4__() except: return def __saveMp3__(self, coverPath): if self._handle.tags is None: self._handle.add_tags() self._handle.tags.add(TIT2(encoding=3, text=self.title)) self._handle.tags.add(TALB(encoding=3, text=self.album)) # self._handle.tags.add(TOPE(encoding=3, text=self.albumartist)) self._handle.tags.add(TPE1(encoding=3, text=self.artist)) self._handle.tags.add(TCOP(encoding=3, text=self.copyright)) self._handle.tags.add(TRCK(encoding=3, text=str(self.tracknumber))) # self._handle.tags.add(TRCK(encoding=3, text=self.discnum)) self._handle.tags.add(TCON(encoding=3, text=self.genre)) self._handle.tags.add(TDRC(encoding=3, text=self.date)) self._handle.tags.add(TCOM(encoding=3, text=self.composer)) self._handle.tags.add(TSRC(encoding=3, text=self.isrc)) self._handle.tags.add( USLT(encoding=3, lang=u'eng', desc=u'desc', text=self.lyrics)) self.__savePic__(coverPath) self._handle.save() return True def __getMp3__(self): if self._handle.tags is None: self._handle.add_tags() def __saveFlac__(self, coverPath): if self._handle.tags is None: self._handle.add_tags() self._handle.tags['title'] = self.title self._handle.tags['album'] = self.album self._handle.tags['albumartist'] = __tryList__(self.albumartist) self._handle.tags['artist'] = __tryList__(self.artist) self._handle.tags['copyright'] = __tryStr__(self.copyright) self._handle.tags['tracknumber'] = str(self.tracknumber) self._handle.tags['tracktotal'] = str(self.totaltrack) self._handle.tags['discnumber'] = str(self.discnumber) self._handle.tags['disctotal'] = str(self.totaldisc) self._handle.tags['genre'] = __tryStr__(self.genre) self._handle.tags['date'] = __tryStr__(self.date) self._handle.tags['composer'] = __tryStr__(self.composer) self._handle.tags['isrc'] = __tryStr__(self.isrc) self._handle.tags['lyrics'] = __tryStr__(self.lyrics) self.__savePic__(coverPath) self._handle.save() return True def __getFlac__(self): if self._handle.tags is None: return self.title = self.__getTagItem__('title') self.album = self.__getTagItem__('album') self.albumartist = self.__getTagItem__('albumartist') self.artist = self.__getTagItem__('artist') self.copyright = self.__getTagItem__('copyright') self.tracknumber = self.__getTagItem__('tracknumber') self.totaltrack = self.__getTagItem__('tracktotal') self.discnumber = self.__getTagItem__('discnumber') self.totaldisc = self.__getTagItem__('disctotal') self.genre = self.__getTagItem__('genre') self.date = self.__getTagItem__('date') self.composer = self.__getTagItem__('composer') self.isrc = self.__getTagItem__('isrc') self.lyrics = self.__getTagItem__('lyrics') def __saveMp4__(self, coverPath): self._handle.tags['\xa9nam'] = self.title self._handle.tags['\xa9alb'] = self.album self._handle.tags['aART'] = __tryList__(self.albumartist) self._handle.tags['\xa9ART'] = __tryList__(self.artist) self._handle.tags['cprt'] = __tryStr__(self.copyright) self._handle.tags['trkn'] = [[ __tryInt__(self.tracknumber), __tryInt__(self.totaltrack) ]] self._handle.tags['disk'] = [[ __tryInt__(self.discnumber), __tryInt__(self.totaldisc) ]] self._handle.tags['\xa9gen'] = __tryStr__(self.genre) self._handle.tags['\xa9day'] = __tryStr__(self.date) self._handle.tags['\xa9wrt'] = __tryList__(self.composer) self._handle.tags['\xa9lyr'] = __tryStr__(self.lyrics) self.__savePic__(coverPath) self._handle.save() return True def __getMp4__(self): self.title = self.__getTagItem__('\xa9nam') self.album = self.__getTagItem__('\xa9alb') self.albumartist = self.__getTagItem__('aART') self.artist = self.__getTagItem__('\xa9ART') self.copyright = self.__getTagItem__('\cprt') self.tracknumber = self.__getTagItem__('trkn') self.totaltrack = self.__getTagItem__('trkn') self.discnumber = self.__getTagItem__('disk') self.totaldisc = self.__getTagItem__('disk') self.genre = self.__getTagItem__('\xa9gen') self.date = self.__getTagItem__('\xa9day') self.composer = self.__getTagItem__('\xa9wrt') self.lyrics = self.__getTagItem__('\xa9lyr') def __getTagItem__(self, name): if name in self._handle.tags: return self._handle.tags[name] return '' def __savePic__(self, coverPath): data = __content__(coverPath) if data is None: return if 'flac' in self._ext: pic = flac.Picture() pic.data = data if '.jpg' in coverPath: pic.mime = u"image/jpeg" self._handle.clear_pictures() self._handle.add_picture(pic) if 'mp3' in self._ext: self._handle.tags.add(APIC(encoding=3, data=data)) if 'mp4' in self._ext or 'm4a' in self._ext: pic = mp4.MP4Cover(data) self._handle.tags['covr'] = [pic]
def create_mp3_meta(mp3_path): meta = File(mp3_path, easy=True) meta.add_tags() meta.save(mp3_path)
def add_simple_metadata(file_path, artist='', title='', album='', albumartist='', override=False): """ Automatically sets the metadata for a music file :param file_path: the path to the music file :param artist: given artist name :param title: given title name :param album: given album name :param albumartist: given album coverist :param override: if True, all of the metadata is overridden :return: True or False depending on whether audio file was changed or not """ try: audio = EasyID3(file_path) except mutagen.id3.ID3NoHeaderError: audio = File(file_path) audio.add_tags() audio.save() audio = EasyID3(file_path) filename = pathlib.Path(file_path).name advanced_audio = File(file_path) try: if (not override and audio.get('title', '') and audio.get('artist', '') and audio.get('albumartist', '') and has_album_cover(file_path)) and 'TDRC' in advanced_audio: return False if not artist: artist = get_artist(filename) else: if artist.count(' , '): artist.split(' , ') elif artist.count(' ,'): artist = artist.split(' ,') elif artist.count(', '): artist = artist.split(', ') elif artist.count(','): artist = artist.split(',') if not title: title = filename.split(' - ')[-1][:-4] if override: audio['title'] = title audio['artist'] = artist if album: audio['album'] = album if albumartist: audio['albumartist'] = albumartist else: if 'album' not in audio: if album == '': audio['album'] = title else: audio['album'] = album if 'title' not in audio: audio['title'] = title if 'artist' not in audio: audio['artist'] = artist if 'albumartist' not in audio: if albumartist: audio['albumartist'] = albumartist else: audio['albumartist'] = artist audio.save() audio = MP3(file_path) # if artist and title and override or audio.get('TDRC', False): # auto_set_year(audio, artist, title) if not has_album_cover(file_path): if not set_album_cover(file_path): print(f'Album art not found for {file_path}') except MutagenError: print(f'{filename} in use') return False except ValueError: print('Error adding metadata to', filename) return False return True
class TagTool(object): def __init__(self, filePath): if os.path.isfile(filePath) is False: return self._filepath = filePath self._ext = _getExtension(filePath) self._handle = File(filePath) self.title = '' self.album = '' self.albumartist = '' self.artist = '' self.copyright = '' self.tracknumber = '' self.totaltrack = '' self.discnumber = '' self.totaldisc = '' self.genre = '' self.date = '' self.composer = '' self.isrc = '' def save(self, coverPath=None): try: if 'mp3' in self._ext: return self._saveMp3(coverPath) if 'flac' in self._ext: return self._saveFlac(coverPath) if 'mp4' in self._ext or 'm4a' in self._ext: return self._saveMp4(coverPath) return False except: return False def _saveMp3(self, coverPath): self._handle.tags.add(TIT2(encoding=3, text=self.title)) self._handle.tags.add(TALB(encoding=3, text=self.album)) # self._handle.tags.add(TOPE(encoding=3, text=self.albumartist)) self._handle.tags.add(TPE1(encoding=3, text=self.artist)) self._handle.tags.add(TCOP(encoding=3, text=self.copyright)) self._handle.tags.add(TRCK(encoding=3, text=str(self.tracknumber))) # self._handle.tags.add(TRCK(encoding=3, text=self.discnum)) self._handle.tags.add(TCON(encoding=3, text=self.genre)) self._handle.tags.add(TDRC(encoding=3, text=self.date)) self._handle.tags.add(TCOM(encoding=3, text=self.composer)) self._handle.tags.add(TSRC(encoding=3, text=self.isrc)) self._savePic(coverPath) self._handle.save() return True def _saveFlac(self, coverPath): if self._handle.tags is None: self._handle.add_tags() self._handle.tags['title'] = self.title self._handle.tags['album'] = self.album self._handle.tags['albumartist'] = self.albumartist self._handle.tags['artist'] = self.artist self._handle.tags['copyright'] = _noneToEmptyString(self.copyright) self._handle.tags['tracknumber'] = str(self.tracknumber) self._handle.tags['tracktotal'] = str(self.totaltrack) self._handle.tags['discnumber'] = str(self.discnumber) self._handle.tags['disctotal'] = str(self.totaldisc) self._handle.tags['genre'] = _noneToEmptyString(self.genre) self._handle.tags['date'] = _noneToEmptyString(self.date) self._handle.tags['composer'] = _noneToEmptyString(self.composer) self._handle.tags['isrc'] = str(self.isrc) self._savePic(coverPath) self._handle.save() return True def _saveMp4(self, coverPath): self._handle.tags['\xa9nam'] = self.title self._handle.tags['\xa9alb'] = self.album self._handle.tags['aART'] = _getArrayStr(self.albumartist) self._handle.tags['\xa9ART'] = _getArrayStr(self.artist) self._handle.tags['cprt'] = _noneToEmptyString(self.copyright) self._handle.tags['trkn'] = [[_tryInt(self.tracknumber), _tryInt(self.totaltrack)]] self._handle.tags['disk'] = [[_tryInt(self.discnumber), _tryInt(self.totaldisc)]] self._handle.tags['\xa9gen'] = _noneToEmptyString(self.genre) self._handle.tags['\xa9day'] = _noneToEmptyString(self.date) self._handle.tags['\xa9wrt'] = _getArrayStr(self.composer) self._savePic(coverPath) self._handle.save() return True def _savePic(self, coverPath): data = _getFileData(coverPath) if data is None: return if 'flac' in self._ext: pic = flac.Picture() pic.data = data if pathHelper.getFileExtension(coverPath) == '.jpg': pic.mime = u"image/jpeg" self._handle.clear_pictures() self._handle.add_picture(pic) if 'mp3' in self._ext: self._handle.tags.add(APIC(encoding=3, data=data)) if 'mp4' in self._ext or 'm4a' in self._ext: pic = mp4.MP4Cover(data) self._handle.tags['covr'] = [pic]
print("Song already exists! Skipping...") del trackIDs[0] continue print("Downloading song " + str(i + 1) + " of " + str(totalTracks) + ": " + id3Title + " by " + id3Artist) try: url = api.get_stream_url(trackIDs[0]) urlretrieve(url, filePath) except: print("Error occurred downloading trackID " + trackIDs[0] + ". Skipping...") del trackIDs[0] continue errorTrack = 0 mp3File = File(filePath) mp3File.add_tags() mp3File.tags.add(id3.TIT2(encoding=3, text=id3Title)) mp3File.tags.add(id3.TALB(encoding=3, text=id3Album)) mp3File.tags.add(id3.TPE1(encoding=3, text=id3Artist)) mp3File.tags.add(id3.TPE2(encoding=3, text=id3AlbumArtist)) mp3File.tags.add(id3.TCOM(encoding=3, text=id3Composer)) if id3Genre: mp3File.tags.add(id3.TCON(encoding=3, text=id3Genre)) if id3Year: mp3File.tags.add(id3.TYER(encoding=3, text=id3Year)) mp3File.tags.add(id3.TRCK(encoding=3, text=id3TrackNumber)) mp3File.tags.add(id3.TPOS(encoding=3, text=id3DiscNumber)) if id3AlbumCover: mp3File.tags.add( id3.APIC(mime='image/jpeg', type=3,
def main(): parser = argparse.ArgumentParser( 'Change or manipulate the ID3 tags of the audio files') parser.add_argument('--artist', '-a', default='', help='set the artist name') parser.add_argument('--album', '-A', default='', help='set the album name') parser.add_argument('--title', '-t', default='', help='set the title name') parser.add_argument('--wors', '-r', default='', help='set the internet radio url') parser.add_argument('--year', '-Y', default='', help='set the release year') parser.add_argument('--cover', '-c', default='', help='set the cover image') parser.add_argument( '--format', '-f', default='', help='''return the ID3 information as a formatted string; the format string should containing one or more of the following specifiers: , {artist} , {title} , {album} , {year} , {kbps} , {wors} , {len} (the length of the audio file, in seconds) , {path} (the absolute path of the file)''' ) parser.add_argument( '--separator', '-s', default='\n', help= 'define the separator used to append at the end of the output for each file (excluding the last file)' ) parser.add_argument( '--escape', '-e', default='', help= 'define the characters that should be escaped in all the outputed fields' ) parser.add_argument('audiofile', nargs='+', help='an audio file containing the ID3 tags') args = parser.parse_args() # input section to_artist = unicode(args.artist.decode('utf-8')) to_album = unicode(args.album.decode('utf-8')) to_title = unicode(args.title.decode('utf-8')) to_wors = unicode(args.wors.decode('utf-8')) to_year = unicode(args.year.decode('utf-8')) to_cover = unicode(args.cover.decode('utf-8')) if to_cover != '': cover_ext = os.path.splitext(to_cover)[1] #print("Cover path is "+to_cover) import mimetypes mimetypes.init() to_cover_mime = mimetypes.types_map[cover_ext] #print("Mime type is "+to_cover_mime) # output section outputs = [] formatstr = unicode(args.format) escapepat = "" delimiter = '' for c in unicode(args.escape): esc = '' if c in r'()[]\^$.|?*+{}': esc = '\\' escapepat = escapepat + delimiter + esc + c delimiter = '|' to_escape = False if escapepat != '': to_escape = True escapepat = '(%s)' % escapepat separator = unicode(args.separator) def getinfo(file): try: return (file.info.bitrate / 1000, int(round(file.info.length))) except: return (0, 0) for f in args.audiofile: path = unicode(os.path.realpath(f.decode('utf-8'))) artist = title = album = year = wors = "" file = File(f) kbps, len = getinfo(file) try: if (type(file) == MP3): # add ID3 tag if it doesn't exist try: file.add_tags() except: pass # should we set the tag in anyway? if to_artist != '': file.tags['TPE1'] = TPE1(encoding=3, text=to_artist) if to_album != '': file.tags['TALB'] = TALB(encoding=3, text=to_album) if to_title != '': file.tags['TIT2'] = TIT2(encoding=3, text=to_title) if to_wors != '': file.tags['WORS'] = WORS(url=to_wors) if to_year != '': file.tags['TDRL'] = TDRL(encoding=3, text=to_year) if to_cover != '': #print('The image data is '+open(to_cover).read()) file.tags['APIC:'] = APIC(encoding=3, mime=to_cover_mime, type=3, data=open(to_cover).read()) file.save() # process mp3 specific tag information artist = file.tags['TPE1'].text[ 0] if 'TPE1' in file.tags else '' album = file.tags['TALB'].text[0] if 'TALB' in file.tags else '' title = file.tags['TIT2'].text[0] if 'TIT2' in file.tags else '' wors = file.tags['WORS'].url if 'WORS' in file.tags else '' year = file.tags['TDRL'].text[0] if 'TDRL' in file.tags else '' elif (type(file) == MP4): # should we set the tag in anyway? if to_artist != '': file.tags['\xa9ART'] = [to_artist] if to_album != '': file.tags['\xa9alb'] = [to_album] if to_title != '': file.tags['\xa9nam'] = [to_title] if to_year != '': file.tags['\xa9day'] = [to_year] if to_cover != '': file.tags['covr'] = [open(to_cover).read()] file.save() artist = file.tags['\xa9ART'][ 0] if '\xa9ART' in file.tags else '' album = file.tags['\xa9alb'][ 0] if '\xa9alb' in file.tags else '' title = file.tags['\xa9nam'][ 0] if '\xa9nam' in file.tags else '' year = file.tags['\xa9day'][0] if '\xa9day' in file.tags else '' except: pass reps = { u'artist': artist, u'title': title, u'album': album, u'year': year, u"kbps": kbps, u'wors': wors, u'len': len, u'path': path } if to_escape: for k in reps: reps[k] = re.sub(escapepat, r'\\\1', u"%s" % reps[k]) if formatstr != '': outputs.append(formatstr.format(**reps)) output = separator.join(outputs).encode('utf-8') print(output, end=u'')
def main(): parser = argparse.ArgumentParser('Change or manipulate the ID3 tags of the audio files') parser.add_argument('--artist','-a', default='', help='set the artist name') parser.add_argument('--album','-A', default='', help='set the album name') parser.add_argument('--title','-t', default='', help='set the title name') parser.add_argument('--wors','-r', default='', help='set the internet radio url') parser.add_argument('--year','-Y', default='', help='set the release year') parser.add_argument('--cover','-c', default='', help='set the cover image') parser.add_argument('--format', '-f', default='', help='''return the ID3 information as a formatted string; the format string should containing one or more of the following specifiers: , {artist} , {title} , {album} , {year} , {kbps} , {wors} , {len} (the length of the audio file, in seconds) , {path} (the absolute path of the file)''') parser.add_argument('--separator','-s', default='\n', help='define the separator used to append at the end of the output for each file (excluding the last file)') parser.add_argument('--escape','-e', default='', help='define the characters that should be escaped in all the outputed fields') parser.add_argument('audiofile', nargs='+', help='an audio file containing the ID3 tags') args = parser.parse_args() # input section to_artist = unicode(args.artist.decode('utf-8')) to_album = unicode(args.album.decode('utf-8')) to_title = unicode(args.title.decode('utf-8')) to_wors = unicode(args.wors.decode('utf-8')) to_year = unicode(args.year.decode('utf-8')) to_cover = unicode(args.cover.decode('utf-8')) if to_cover != '': cover_ext = os.path.splitext(to_cover)[1] #print("Cover path is "+to_cover) import mimetypes mimetypes.init() to_cover_mime = mimetypes.types_map[cover_ext] #print("Mime type is "+to_cover_mime) # output section outputs = [] formatstr = unicode(args.format) escapepat = "" delimiter = '' for c in unicode(args.escape): esc = '' if c in r'()[]\^$.|?*+{}': esc = '\\' escapepat = escapepat + delimiter + esc + c delimiter = '|' to_escape = False if escapepat != '': to_escape = True escapepat = '(%s)' % escapepat separator = unicode(args.separator) def getinfo(file): try: return (file.info.bitrate / 1000, int(round(file.info.length))) except: return (0,0) for f in args.audiofile: path = unicode(os.path.realpath(f.decode('utf-8'))) artist = title = album = year = wors = "" file = File(f) kbps, len = getinfo(file) try: if (type(file) == MP3): # add ID3 tag if it doesn't exist try: file.add_tags() except: pass # should we set the tag in anyway? if to_artist != '': file.tags['TPE1'] = TPE1(encoding=3, text=to_artist) if to_album != '': file.tags['TALB'] = TALB(encoding=3, text=to_album) if to_title != '': file.tags['TIT2'] = TIT2(encoding=3, text=to_title) if to_wors != '': file.tags['WORS'] = WORS(url=to_wors) if to_year != '': file.tags['TDRL'] = TDRL(encoding=3, text=to_year) if to_cover != '': #print('The image data is '+open(to_cover).read()) file.tags['APIC:'] = APIC( encoding=3, mime=to_cover_mime, type=3, data=open(to_cover).read() ) file.save() # process mp3 specific tag information artist = file.tags['TPE1'].text[0] if 'TPE1' in file.tags else '' album = file.tags['TALB'].text[0] if 'TALB' in file.tags else '' title = file.tags['TIT2'].text[0] if 'TIT2' in file.tags else '' wors = file.tags['WORS'].url if 'WORS' in file.tags else '' year = file.tags['TDRL'].text[0] if 'TDRL' in file.tags else '' elif (type(file) == MP4): # should we set the tag in anyway? if to_artist != '': file.tags['\xa9ART'] = [to_artist] if to_album != '': file.tags['\xa9alb'] = [to_album] if to_title != '': file.tags['\xa9nam'] = [to_title] if to_year != '': file.tags['\xa9day'] = [to_year] if to_cover != '': file.tags['covr'] = [open(to_cover).read()] file.save() artist = file.tags['\xa9ART'][0] if '\xa9ART' in file.tags else '' album = file.tags['\xa9alb'][0] if '\xa9alb' in file.tags else '' title = file.tags['\xa9nam'][0] if '\xa9nam' in file.tags else '' year = file.tags['\xa9day'][0] if '\xa9day' in file.tags else '' except: pass reps = {u'artist':artist, u'title':title, u'album':album, u'year':year, u"kbps":kbps, u'wors':wors, u'len':len, u'path':path} if to_escape: for k in reps: reps[k] = re.sub(escapepat, r'\\\1', u"%s" % reps[k]) if formatstr != '': outputs.append(formatstr.format(**reps)) output = separator.join(outputs).encode('utf-8') print(output, end=u'')