def analyze(self): with open(self.moodpath, "rb") as inputFile: cpt = 0 #read mood file while True: byte = inputFile.read(3) if len(byte) == 3: #calculate histogram self._countsR[int(ord(byte[0]) / 23)] += 1 self._countsG[int(ord(byte[1]) / 23)] += 1 self._countsB[int(ord(byte[2]) / 23)] += 1 #calculate enery self.energy_1 += pow(ord(byte[0]), 2) self.energy_2 += pow(ord(byte[1]), 2) self.energy_3 += pow(ord(byte[2]), 2) cpt += 1 else: break if cpt != 0: #end of enery calculation self.energy_1 /= cpt self.energy_2 /= cpt self.energy_3 /= cpt try: #fetch bitrate tag = TinyTag.get(self.filepath) if tag.bitrate < 512: br = int(round(tag.bitrate)) else: br = int(round(tag.bitrate/1000)) self.kbps = br except OSError as ose: print("Error: " + str(ose)) return (1) #get peak histogram self.peak_hist_1 = self.getCountsMax(self._countsR); self.peak_hist_2 = self.getCountsMax(self._countsG); self.peak_hist_3 = self.getCountsMax(self._countsB); return (0)
def getSongInfo(filepath): tag = TinyTag.get(filepath) # make sure everthing returned (except length) is a string for attribute in ['artist','album','title','track']: if getattr(tag, attribute) is None: setattr(tag, attribute, '') return Metainfo(tag.artist, tag.album, tag.title, str(tag.track), tag.length)
def db_check(): mp3s = get_mp3_list() for d, mp3 in mp3s: fullpath = os.path.join(d,mp3) data = db_get(fullpath, 'fullpath') if not data: print 'adding: ', fullpath data = { 'fullpath': fullpath, 'title': mp3, 'description': '', } try: date_part = mp3.split('.')[0] date_obj = datetime.strptime(date_part, '%Y-%m-%d_%H-%M-%S') #data['date'] = datetime.strftime(date_obj, '%a %b %d, %Y at %I:%M %p') data['date'] = date_obj except: date_obj = datetime.fromtimestamp(os.path.getctime(fullpath)) #data['date'] = datetime.strftime(date_obj, '%a %b %d, %Y at %I:%M %p') data['date'] = date_obj tag = TinyTag.get(fullpath) m, s = divmod(tag.duration, 60) h, m = divmod(m, 60) data['duration'] = "%d:%02d:%02d" % (h, m, s) db_insert(data) delete = [] for mp3 in db_get_all(): if not os.path.exists(mp3['fullpath']): delete.append(mp3['fullpath']) for d in delete: print 'removing: ', d db_remove(d)
def getMetaData(fullname, playlists): log.info('accessing metadata...') index = 0 tagInfo = [] for track in playlists: name= playlists[track] if os.path.isfile(name): try: filename = os.path.basename(name) log.success('-------------------------') tag = TinyTag.get(name) if tag.title != '' or tag.artist != '': song = str(tag.title+':'+tag.artist) tagInfo.append(song) log.warn('tag info:', filename.encode("ascii", "ignore")) log.info('Artist:', tag.artist) log.info('Album:', tag.album) log.info('Title:', tag.title.encode("ascii", "ignore")) log.info('Track number:', tag.track) index += 1 else: log.warn('WARN: no id3 info provide') except Exception as e: log.err("An error occurred while getting metadata of the file:", name) log.err("Error:", e) else: log.err("The file: %s does not exist, check the path or filename" % (name)) print log.err('track processing:', str(index)) saveMetaData(fullname, tagInfo, index) return tagInfo
def test_duration_with_vlc(self): import vlc v = vlc.Instance() mp = MusicPlayer(self.config) albums = mp.get_albums_and_songs() # VLC Start start_time = time.time() for album in albums: print(colorstring("Album: " + album.title, Colors.GREEN)) for song in album.getsonglist(): print(colorstring("\t" + str(song.title), Colors.BLUE)) media = v.media_new(song.filepath) media.parse() print("\tsong duration: " + str(media.get_duration())) print(colorstring("--- VLC took %s seconds ---" % round((time.time() - start_time), 5), Colors.RED)) # VLC End # TinyTag Start start_time = time.time() for album in albums: print(colorstring("Album: " + album.title, Colors.GREEN)) for song in album.getsonglist(): print(colorstring("\t" + str(song.title), Colors.BLUE)) tinytag = TinyTag.get(song.filepath, False, True) print("\tsong duration: " + str(round(tinytag.duration * 1000))) print(colorstring("--- TinyTag took %s seconds ---" % round((time.time() - start_time), 5), Colors.RED))
def folderTraversal(self, folderPath): for root, subdir, files in os.walk(folderPath): hasMusic = False albumName = "" for f in files: fullPath = os.path.join(root, f) try: metadata = TinyTag.get(fullPath) except LookupError: # File is not a valid audio file, skip continue metadata.album = str(metadata.album) self.trackIDList.add(utils.genID(metadata)) if self.config.filter.check(metadata) and not (metadata in self.record): albumName = metadata.album if albumName not in self.albums: self.albums[albumName] = objects.Album(albumName) newTrack = objects.Track(metadata, fullPath) self.albums[albumName].add(newTrack) hasMusic = True self.progress.incTotal() if hasMusic: # Handle cover image self.albums[albumName].coverFile = self.__detectCoverFile(root) logging.info("Album: %s with %d song(s)" % (albumName, len(self.albums[albumName].tracks)))
def main(): args = parser.parse_args() args.foldername = os.path.expanduser(args.foldername) new_foldername = args.foldername # keep a list of all cues and flacs file_lists = get_music(new_foldername=new_foldername) music_filenames = file_lists['mp3'] # now, for each file, get the mp3 tags and get the date created music_dataframe = [] for music_file in music_filenames: try: tag = TinyTag.get(music_file) except Exception as e: print e next if tag.artist is not None: artist = tag.artist.encode('ascii', 'ignore') if tag.album is not None: album = tag.album.encode('ascii', 'ignore') if tag.title is not None: title = tag.title.encode('ascii', 'ignore') date_changed = os.path.getmtime(music_file) music_dataframe.append({'artist':artist,'album':album,'title':title,'date':date_changed}) music_dataframe = DataFrame(music_dataframe) music_dataframe.to_csv("mp3_tags.csv")
def _fetch_embedded_image(self, path): filetypes = ('.mp3',) max_tries = 3 header, data, resized = None, '', False try: files = os.listdir(path) files = (f for f in files if f.lower().endswith(filetypes)) for count, file_in_dir in enumerate(files, start=1): if count > max_tries: break filepath = os.path.join(path, file_in_dir) try: tag = TinyTag.get(filepath, image=True) image_data = tag.get_image() except IOError: continue if not image_data: continue _header, _data = self.resize_image_data( image_data, (self.IMAGE_SIZE, self.IMAGE_SIZE)) if _data: header, data, resized = _header, _data, True break except OSError: pass return header, data, resized
def api_fetchalbumart(self, directory): _save_and_release_session() default_folder_image = "../res/img/folder.png" log.i('Fetching album art for: %s' % directory) filepath = os.path.join(cherry.config['media.basedir'], directory) if os.path.isfile(filepath): # if the given path is a file, try to get the image from ID3 tag = TinyTag.get(filepath, image=True) image_data = tag.get_image() if image_data: log.d('Image found in tag.') header = {'Content-Type': 'image/jpg', 'Content-Length': len(image_data)} cherrypy.response.headers.update(header) return image_data else: # if the file does not contain an image, display the image of the # parent directory directory = os.path.dirname(directory) #try getting a cached album art image b64imgpath = albumArtFilePath(directory) img_data = self.albumartcache_load(b64imgpath) if img_data: cherrypy.response.headers["Content-Length"] = len(img_data) return img_data #try getting album art inside local folder fetcher = albumartfetcher.AlbumArtFetcher() localpath = os.path.join(cherry.config['media.basedir'], directory) header, data, resized = fetcher.fetchLocal(localpath) if header: if resized: #cache resized image for next time self.albumartcache_save(b64imgpath, data) cherrypy.response.headers.update(header) return data elif cherry.config['media.fetch_album_art']: #fetch album art from online source try: foldername = os.path.basename(directory) keywords = foldername log.i(_("Fetching album art for keywords {keywords!r}").format(keywords=keywords)) header, data = fetcher.fetch(keywords) if header: cherrypy.response.headers.update(header) self.albumartcache_save(b64imgpath, data) return data else: # albumart fetcher failed, so we serve a standard image raise cherrypy.HTTPRedirect(default_folder_image, 302) except: # albumart fetcher threw exception, so we serve a standard image raise cherrypy.HTTPRedirect(default_folder_image, 302) else: # no local album art found, online fetching deactivated, show default raise cherrypy.HTTPRedirect(default_folder_image, 302)
def test_pathlib_compatibility(): try: import pathlib except ImportError: return testfile = next(iter(testfiles.keys())) filename = pathlib.Path(testfolder) / testfile tag = TinyTag.get(filename)
def __init__(self, ruta, titulo = "Cancion desconocida", artista = "Autor desconocido"): self.ruta = ruta datos = TinyTag.get(ruta) self.artista = artista self.titulo = titulo if datos.title: self.titulo = datos.title if datos.artist: self.artista = datos.artist
def get_node(filename): from tinytag import TinyTag logger.debug(filename) try: tag = TinyTag.get(filename) logger.info(tag.title) except LookupError as err: logger.error("File `{0}` processing error: {1}".format(filename, err))
def genMoodHist(fileName, inputFile, outputFile, localOutput): countsR = initCounts() countsG = initCounts() countsB = initCounts() while True: byte = inputFile.read(3) if len(byte) == 3: countsR[int(ord(byte[0]) / 23)] += 1 countsG[int(ord(byte[1]) / 23)] += 1 countsB[int(ord(byte[2]) / 23)] += 1 else: break for binIdx in range(12): xMin = binIdx * 23 xMax = xMin + 22 localOutput.write(str(xMin) + "-" + str(xMax) + ";") localOutput.write("\n") writeHist(countsR, localOutput) writeHist(countsG, localOutput) writeHist(countsB, localOutput) try: tag = TinyTag.get(fileName[:-5] + ".mp3") if tag.bitrate < 512: br = int(round(tag.bitrate)) else: br = int(round(tag.bitrate/1000)) outputFile.write(fileName + ";" + str(br) + ";") table = [] ct = 0; with open(fileName[:-5] + ".csv", 'r') as fd: for line in fd: table.append(line.strip().split(";")) ct += 1; for i in range(0,3): subtotal = float(0) for rgb in table: subtotal += pow(int(rgb[i]), 2) subtotal /= ct outputFile.write(str(subtotal) + ";") outputFile.write(str(getCountsMax(countsR)) + ";" + str(getCountsMax(countsG)) + ";" + str(getCountsMax(countsB)) + "\n") except OSError as ose: print("Error: " + str(ose)) return (1) return (0)
def tags_wav(name, infer=True): try: tags = TinyTag.get(name) except struct.error: if infer: uprint('WARN: Corrupted or mistagged, inferring artist and album: %s ...' % name, end=' ') return infer_album_artist(name) return None if not tags: return None, None return tags.artist, tags.album
def get_info(testfile, expected): filename = os.path.join(samplefolder, testfile) print(filename) tag = TinyTag.get(filename) for key, value in expected.items(): result = getattr(tag, key) fmt_string = 'field "%s": got %s (%s) expected %s (%s)!' fmt_values = (key, repr(result), type(result), repr(value), type(value)) assert result == value, fmt_string % fmt_values print(tag) print(tag.__repr__())
def get_artist(path): musicMeta = TinyTag.get(path) artist = musicMeta.artist if artist is not None: artist = ''.join(i for i in artist if i not in string.punctuation).replace(" ", "") if artist is None or not artist or artist.isspace(): return "Unknown" else: return artist
def getTag(song_path): #returns all matching fields tag = TinyTag.get(song_path) tag_fields = tag.__dict__ details = {} for item in tag_fields: if item in fields and tag_fields[item] != None: details[item] = tag_fields[item] details['duration'] = "{:.2f}".format(details.get('duration')) if details.get('bitrate') > 5000: details.pop('bitrate') return details
def __init__(self, title: str, filepath: str): super(SongModel, self).__init__() self.id = id(self) self.title = title self.filepath = filepath # This operation can go wrong when another program is using the filepath try: self._tags = TinyTag.get(self.filepath, False, True) self.duration = round(self._tags.duration) except PermissionError as e: self.duration = None print(e)
def moves_record(): """-""" input_file = "../audio/show1/01_m.mp3" tag = TinyTag.get(input_file) track_length = tag.duration if os.path.exists(input_file + ".moves"): os.remove(input_file + ".moves") output_file = open(input_file + ".moves", "w") pygame.init() pygame.mixer.init() pygame.mixer.music.load(input_file) print "Playing " + input_file print "3... " time.sleep(1) print "2... " time.sleep(1) print "1... " time.sleep(1) pygame.mixer.music.play() start_time = time.time() last_time = 0 is_done = False do_extra_close = False create_output(output_file, '{ "moveitem": [') while (is_done != True) and ((time.time() - start_time) < track_length): command = "" next_char = getch() current_time = time.time() - start_time if do_extra_close: create_output( output_file, str(' { "time":%.2f, "command":"%s" },' % ((current_time + last_time) / 2, "CLOSE")) ) do_extra_close = False if next_char == "q": is_done = True else: if next_char == "i": # This means OPEN_THEN_CLOSE command = "OPEN" do_extra_close = True if next_char == "o": command = "OPEN" if next_char == "p": command = "CLOSE" if command != "": create_output(output_file, str(' { "time":%.2f, "command":"%s" },' % (current_time, command))) last_time = current_time create_output(output_file, str(' { "time":%.2f, "command":"CLOSE" }\n] }' % track_length)) output_file.close()
def copland_scrape(): event_list = Event.objects.filter(start_date__gt=date(2013, 11, 22)).order_by('start_date') event_list = event_list.reverse() text_file = open("copland.txt", "w") fstring = "" for e in event_list: print(e.name) fstring += e.start_date.strftime("%m.%d.%y") + ": " + e.name program = Program.objects.select_related().filter(event = e).order_by('position') performers = Performer.objects.select_related().filter(event = e).order_by('position') recs = EventAudioRecording.objects.select_related().filter(event = e).order_by('position') dur = "" for i in range(len(program)): work = program[i].works.all()[0] if len(recs) > 0 and os.path.isfile(recs[i].compressed_master_recording.path): #mf = mad.MadFile(recs[i].compressed_master_recording.path) #dur = int(mf.total_time() / 1000) #dur = str(timedelta(seconds=dur)) #fname = recs[i].uncompressed_master_recording.path #print(fname) #with contextlib.closing(wave.open(fname,'r')) as f: # frames = f.getnframes() # rate = f.getframerate() # duration = math.floor(frames / float(rate)) # minutes, seconds = divmod(duration, 60) # hours, minutes = divmod(minutes, 60) # dur = str(hours) + ":" + str(minutes) + ":" + str(seconds) tag = TinyTag.get(recs[i].compressed_master_recording.path) duration = tag.duration print(duration) minutes, seconds = divmod(duration, 60) hours, minutes = divmod(minutes, 60) dur = str(int(hours)) + ":" + str(int(minutes)) + ":" + str(int(seconds)) else: dur = "????" fstring += "\n"+work.name + " by " + work.authors.all()[0].name + "* - " + dur if len(performers) > 0: fstring += "\nperformers: " for p in performers: fstring += p.performer.name + " - " for i in p.instruments.all(): fstring += i.name + ", " fstring = fstring[:-2] fstring += "; " fstring = fstring[:-2] fstring += "\n\n" text_file.write(fstring.encode('utf-8')) text_file.close()
def get_encode_task(source_file, destination, bitrate): tags = TinyTag.get(source_file) track_relative_path = get_track_relative_path(tags) if track_relative_path: track_absolute_path = os.path.join(destination, track_relative_path) if not os.path.exists(track_absolute_path): return { 'source': source_file, 'destination': track_absolute_path, 'destination_rel': track_relative_path, 'bitrate': bitrate } else: print('Ignoring ' + source_file)
def __init__(self, ruta, titulo='Cancion desconocida', artista='Autor desconocido'): # Usar TinyTag para obtener la informacion de la cancion, sobreescribir con lo pasado por # parametro solo si la informacion no se encuentra disponible self.ruta = ruta tag = TinyTag.get(ruta) get_titulo = tag.title get_artista = tag.artist if get_titulo: self.titulo = tag.title else: self.titulo = titulo if get_artista: self.artista = tag.artist else: self.artista = artista
def _get_duration_of(filename): """Return the duration of the media file located at ``filename``. Use :meth:`.Media.populate_duration_from` if you want to populate the duration property of a Media instance using a local file. :param filename: Path to the media file which shall be used to determine this media's duration. The file extension must match its file type, since it is used to determine what type of media file it is. For a list of supported formats, see https://pypi.python.org/pypi/tinytag/ :type filename: str :returns: datetime.timedelta """ return datetime.timedelta(seconds=TinyTag.get(filename).duration)
def parse_metadata(self): # Errors with some mp3 files try: tag = TinyTag.get(str(self.absolute_path())) self.meta_track = tag.track.zfill(2) if tag.track else None self.meta_track_total = tag.track_total self.meta_title = tag.title self.meta_artist = tag.artist self.meta_album = tag.album self.meta_year = tag.year self.meta_genre = tag.genre self.meta_duration = tag.duration except: logger.info('Fail to get meta data from %s', str(self.absolute_path()))
def get_info(testfile, expected): filename = os.path.join(testfolder, testfile) print(filename) tag = TinyTag.get(filename) for key, expected_val in expected.items(): result = getattr(tag, key) if key == 'duration': # allow duration to be off by 100 ms and a maximum of 1% if abs(result - expected_val) < 0.100: if expected_val and min(result, expected_val) / max(result, expected_val) > 0.99: continue fmt_string = 'field "%s": got %s (%s) expected %s (%s)!' fmt_values = (key, repr(result), type(result), repr(expected_val), type(expected_val)) assert result == expected_val, fmt_string % fmt_values
def cover_art_get(self, dest_file_name="covert_art.jpg"): if self.playing_type == 'radio': return COVER_ART_RADIO if self.filepath == "": return DEFAULT_COVER try: tag = TinyTag.get(os.path.join(self.music_directory, self.file), image=True) cover_art = tag.get_image() except: return DEFAULT_COVER if cover_art is None: return DEFAULT_COVER with open(dest_file_name, 'wb') as img: img.write(cover_art) # write artwork to new image return dest_file_name
def cover_art_get(self): if self.playing_type == 'radio': return self._get_cover_from_zip(COVER_ART_RADIO) if self.file == "" : return self._get_cover_from_zip(DEFAULT_COVER) try: tag = TinyTag.get(os.path.join(self.music_directory, self.file), image=True) cover_art = tag.get_image() except: return self._get_cover_from_zip(DEFAULT_COVER) if cover_art is None: return self._get_cover_from_zip(DEFAULT_COVER) bytes_io = io.BytesIO(cover_art) return pygame.image.load(bytes_io)
def add(self, path): try: tag = TinyTag.get(path) except: artiste = 'Pas' album = 'de' title = 'chocolat' duration = '!' else: artist = tag.artist album = tag.album title = tag.title duration = int(tag.duration) duration = '{:02}:{:02}'.format(duration / 60, duration % 60) entry = Entry(path, artist, album, title, duration) self.playlist.append(entry)
def test_get_length(self): taginfo = TinyTag.get(self.samplefiles[0], False, True) print("artist " + str(taginfo.artist)) # artist name as string print("album " + str(taginfo.album)) # album as string print("albumartist " + str(taginfo.albumartist)) # album artist as string print("audio_offset " + str(taginfo.audio_offset)) # number of bytes before audio data begins print("bitrate " + str(taginfo.bitrate)) # bitrate in kBits/s print("disc " + str(taginfo.disc)) # disc number print("disc_total " + str(taginfo.disc_total)) # the total number of discs print("duration (sec) " + str(taginfo.duration)) # duration of the song in seconds print("filesize " + str(taginfo.filesize)) # file size in bytes print("genre " + str(taginfo.genre)) # genre as string print("samplerate " + str(taginfo.samplerate)) # samples per second print("title " + str(taginfo.title)) # title of the song print("track " + str(taginfo.track)) # track number as string print("track_total " + str(taginfo.track_total)) # total number of tracks as string print("year " + str(taginfo.year)) # year or data as string
def get(self, request, path): file_path = Directory.get_basedir().absolute_path() / path if not file_path.exists(): raise NotFound() # try fetching from the audio file if file_path.is_file(): tag = TinyTag.get(str(file_path), image=True) image_data = tag.get_image() if image_data: return ImageResponse(image_data=image_data) # try the parent directory of the file file_path = os.path.dirname(str(file_path)) file_cache_path = pathprovider.album_art_file_path(str(file_path)) if os.path.exists(file_cache_path): logger.debug('Getting cached thumbnail: %s' % file_cache_path) with open(file_cache_path, 'rb') as fh: return ImageResponse(image_data=fh.read()) fetcher = AlbumArtFetcher() header, data, resized = fetcher.fetch_local(str(file_path)) if header: logger.debug('Getting album art from local: %s' % file_path) if resized: with open(file_cache_path, 'wb') as fh: fh.write(data) return ImageResponse(image_data=data) # else: # logger.debug('Getting album art from online source.') # try: # foldername = os.path.basename(file_path) # keywords = foldername # logger.info("Fetching album art for keywords: %s" % keywords) # header, data = fetcher.fetch(keywords) # if header: # with open(file_cache_path, 'wb') as fh: # fh.write(data) # return ImageResponse(image_data=data) # except: # logger.error('Unable to get album art from online source.') raise Http404()
def _get_size(self, file): tag = TinyTag.get(file) return tag.filesize
from tinytag import TinyTag # Pass the filename into the # Tinytag.get() method and store # the result in audio variable video = TinyTag.get("RGB mp4.mp4") # Use the attributes # and display print("Title:" + str(video.dimensions)) print("Artist: " + str(video.artist)) print("Genre:" + str(video.genre)) print("Year Released: " + str(video.year)) print("Bitrate:" + str(video.bitrate) + " kBits/s") print("Composer: " + str(video.composer)) print("Filesize: " + str(video.filesize) + " bytes") print("AlbumArtist: " + str(video.albumartist)) print("Duration: " + str(video.duration) + " seconds") print("TrackTotal: " + str(video.track_total))
def get_song_filename(filename, db_directory, format='wav'): """Creates a filepath to a song based on the mp3 metadata.""" tag = TinyTag.get(filename) title = tag.title.replace('/', '').replace(' ', ' ') return '{}/{}/{}/{}.{}'.format(db_directory, tag.artist, tag.album, title, format)
def conventer_durability(self): tag = TinyTag.get(self.port2) self.fin_time = tag.duration self.fin_time = int(self.fin_time) minutes = self.fin_time / 60 sec = self.fin_time % 60
mp3s = [] songs = [] songs_ok = [] m4as = [] for root, dirs, files in os.walk(args.cwd): for filename in files: if os.path.splitext(filename)[1] == ".mp3": songs.append(os.path.join(root, filename)) elif os.path.splitext(filename)[1] == ".m4a": songs.append(os.path.join(root, filename)) with progressbar.ProgressBar(max_value=len(songs)) as bar: for i, song in enumerate(songs): audiofile = TinyTag.get(song) # audiofile = eyed3.load(song) # if hasattr(audiofile, 'tag'): # if hasattr(audiofile.tag, 'genre'): # songs_ok.append(song) # else: # log_bad_song(song) # else: # log_bad_song(song) log_bad_song(audiofile.genre) if hasattr(audiofile, 'genre'): if audiofile.genre == 'None' or audiofile.genre == None or audiofile.genre == '': no_info_doc += log_bad_song(song) else: songs_ok.append(song) else:
print('If path is network location please use UNC path \\\servername\\\path') path = input("Enter Location of Album: ") directories = [] tracknames = [] trackpositions = [] trackdurations = [] filetypes = ('.mp3', '.m4a', '.flac', '.ogg', '.m4b') template = 'album.nfo' type = 'album' compilation = 'false' for name in os.listdir(path): if name.endswith(filetypes): filename = os.path.join(path, name) tag = TinyTag.get(filename) title = tag.title track = tag.track duration = tag.duration tracknames.append(title) trackpositions.append(track) duration = math.ceil(duration) duration = str(datetime.timedelta(seconds=duration)) trackdurations.append(duration) album = tag.album artist = tag.artist genre = tag.genre year = tag.year createfile = os.path.join(path, 'album.nfo')
title = song['title'] album = song['album']['name'] id = song['entityId'] if album not in yt_albums.keys(): yt_albums[album] = [] yt_albums[album].append((title, id)) local_album = {} eyed3.log.setLevel("ERROR") for dirpath, dirnames, filenames in os.walk(r"E:\Music"): for filename in filenames: if '.mp3' in filename[-4:]: audiofile = eyed3.load(dirpath + os.sep + filename) title = audiofile.tag.title album = audiofile.tag.album if album not in local_album.keys(): local_album[album] = [] local_album[album].append((title, dirpath + os.sep + filename)) if '.flac' in filename[-5:]: audiofile = TinyTag.get(dirpath + os.sep + filename) title = audiofile.title album = audiofile.album if album not in local_album.keys(): local_album[album] = [] local_album[album].append((title, dirpath + os.sep + filename)) for item in yt_albums.keys(): if len(yt_albums[item]) != len(local_album[item]): print('youtube\t', item, len(yt_albums[item])) print('local\t', item, len(local_album[item])) print('\nyoutube\t', len(yt_albums)) print('local\t', len(local_album), '\n')
def test_mp3_length_estimation(): ID3.set_estimation_precision(0.7) tag = TinyTag.get(os.path.join(testfolder, 'samples/silence-44-s-v1.mp3')) assert 3.5 < tag.duration < 4.0
def test_unsupported_extension(): bogus_file = os.path.join(testfolder, 'samples/there_is_no_such_ext.bogus') TinyTag.get(bogus_file)
import os from tinytag import TinyTag, TinyTagException tracks = [] for root, dirs, files, in os.walk( "/home/lowkey/Documents/Programs/Python/Project Medusa/Music"): for name in files: if name.endswith((".mp3", ".m4a", ".flac", ".alac")): tracks.append(name) try: temp_track = TinyTag.get(root + "/" + name) #change to \ for windows print(temp_track.title, "-", temp_track.artist) except TinyTagException: print("Error")
def load_meta(self): if tag_importer.is_supported(self.song_path): song_tag = tag_importer.get(self.song_path, image=True) return song_tag, song_tag.get_image() else: print('Error: file format not supported')
def message(text): fileName = "message.ogg" call_polly(text, fileName) track = TinyTag.get(fileName) moveMouth.moveMouth(track.duration) playsound(fileName) # play sound
description=f"{description}. " f"Check out my GitHub" f" page: " f"https://github.com" f"/agb2k") path, dirs, files = next(os.walk(path_input)) num_files = len(files) # Loop through files print("Please wait till program is complete:") for x in fileList: count += 1 total_count += 1 file = str(x) tag = TinyTag.get(file) # Account for songs/albums with brackets in their title modified_title = re.sub(r"\([^()]*\)", "", f"{tag.title}") modified_album = re.sub(r"\([^()]*\)", "", f"{tag.album}") song = f"{modified_title} {tag.artist} {modified_album}" result = spotify_object.search(q=song) try: song_list.append(result['tracks']['items'][0]['uri']) except: try: file_details = os.path.basename(x).split(' - ') song_new = f"{modified_title} {file_details[0]}" result_new = spotify_object.search(q=song_new)
def get_song_metadata(self, filename): return TinyTag.get(filename)
def moveFiles(rootDir): """Look through files and directories and move them to specified locations """ homedir = os.environ['HOME'] albumDirec = 'AlbumCoverImages' #Check if a directory exists if not os.path.isdir(os.path.join(homedir, 'Pictures', albumDirec)): print('AlbumCoverImages not found, trying to make...') os.makedirs(os.path.join(homedir, 'Pictures', albumDirec)) for root, dirs, files in os.walk(rootDir, topdown=False): #print('testtest') for name in files: #Find image files, and move them to albumCoverImages #For some bullshit reason or statments won't work here, have to # parse this out to elif statements, ughhhh... if '.jpg' in name: os.rename(os.path.join(root, name), os.path.join(homedir, 'Pictures', albumDirec, name)) print('{0} moved to {1}!'.format(name, os.path.join(homedir, 'Pictures', albumDirec))) elif '.png' in name: os.rename(os.path.join(root, name), os.path.join(homedir, 'Pictures', albumDirec, name)) print('{0} moved to {1}!'.format(name, os.path.join(homedir, 'Pictures', albumDirec, name))) elif '.gif' in name: os.rename(os.path.join(root, name), os.path.join(homedir, 'Pictures', albumDirec, name)) print('{0} moved to {1}!'.format(name, os.path.join(homedir, 'Pictures', albumDirec, name))) elif '.pdf' in name: os.rename(os.path.join(root, name), os.path.join(homedir, 'Pictures', albumDirec, name)) print('{0} moved to {1}!'.format(name, os.path.join(homedir, 'Pictures', albumDirec, name))) else: try: #Use tinytag to get file metadata tag = TinyTag.get(os.path.join(root, name)) artistName = tag.artist albumName = tag.album #TODO: Need to add more conditions if isinstance(artistName, str): artistName = artistName.replace('/', '_') elif isinstance(albumName, str): albumName.replace('/', '_') #Check if the artists directory exists, if not make it try: if not os.path.isdir(os.path.join(rootDir, artistName)): os.makedirs(os.path.join(rootDir, artistName)) print('{0} directory made!'.format(artistName)) except ValueError: print('ValueError with {0}'.format(root+'/'+name)) continue except TypeError: print('TypeError with {0}'.format(root+'/'+name)) continue #Check if the songs album exists, if not make it try: if not os.path.isdir(os.path.join(rootDir, artistName, albumName)): os.makedirs(os.path.join(rootDir, artistName, albumName)) print('{0} directory made!'.format(albumName)) except TypeError: print('TypeError with {0}! Look at album directory making.'.format(root+'/'+name)) continue #TODO: Check if album is in artist direc, if not, move it #Check if song is in album, if not move it try: if os.path.isfile(os.path.join(rootDir, artistName, albumName, name)) == False: os.rename(os.path.join(root, name), os.path.join(rootDir, artistName, albumName, name)) print('{0} moved to {1}!'.format(name, albumName)) except TypeError: print('TypeError with file {0}! Look at line song moving'.format(root+'/'+name)) continue #TODO: Check if this part works except LookupError: if (".jpg") or (".png") or (".7z") or ("README") or (".zip") in name: continue else: print('No reader support for {0}'.format(name)) continue
if (len(sys.argv) > 1): files = sys.argv[1:len(sys.argv)] else: files = os.listdir() files = list(filter(only_video_audio_files, files)) cwd = os.getcwd().split("\\")[-1] print("\n" + cwd.title(), ":", sep="") # print(style.BRIGHT + fg.CYAN + cwd.title() + ":" + fg.RESET + style.RESET_ALL, sep="") individual_file_duration = {} total_duration_in_secs = 0 if (len(files) > 0): for file in files: metadata = TinyTag.get(file) individual_file_duration[file] = print_duration( math.floor(metadata.duration)) total_duration_in_secs += metadata.duration total_duration_in_secs_str = print_duration(total_duration_in_secs) print("Total Duration:", total_duration_in_secs_str) print("No of files:", len(files)) print("Average length of File:", print_duration(total_duration_in_secs / len(files))) print("Total Duration (1.25x):", divide(total_duration_in_secs, 1.25)) print("Total Duration (1.5x):", divide(total_duration_in_secs, 1.5)) print("Total Duration (1.75x):", divide(total_duration_in_secs, 1.75)) print("Total Duration (2x):", divide(total_duration_in_secs, 2)) print("Total Duration (2.5x):", divide(total_duration_in_secs, 2.5)) print("")
def getInfo(path): mp3 = TinyTag.get(path) toReturn = [] toReturn.append(mp3.artist) toReturn.append(mp3.title) return toReturn
def open_(): try: global w, img, rp global r global k global ll, pp w = filedialog.askopenfilename(initialdir='', title="Choose A Song", filetypes=(("Music Files", "*.mp3 *.wav " "*.ogg *.mx " "*.mod"), )) # ll = os.listdir(w) if w != "": list1.insert(END, w) if str(w).endswith('.mp3'): pygame.mixer.init() list1.selection_set(END) tag = TinyTag.get(w) Label(win, text=tag.title + " \t \t \t \t \t \t \t \t \t \t \t \t", bd=1, relief=SUNKEN, anchor=W).place(x=0, y=280) except FileNotFoundError or NameError or OSError: Label( win, text="You didn't choose a file \t \t \t \t \t \t \t \t \t \t \t \t", bd=1, relief=SUNKEN, anchor=W).place(x=0, y=280) try: img = Image.open(w.strip(os.path.basename(w)) + "cover.jpg") # resize the image and apply a high-quality down sampling filter img = img.resize((110, 110), Image.ANTIALIAS) # PhotoImage class is used to add image to widgets, icons etc img = ImageTk.PhotoImage(img) # create a label panel = Label(win, image=img) # set the image as img panel.image = img panel.place(x=35, y=160) except FileNotFoundError or NameError or OSError: ko = Image.open("Vinyl Music Player icon.png") # resize the image and apply a high-quality down sampling filter ko = ko.resize((110, 110), Image.ANTIALIAS) # PhotoImage class is used to add image to widgets, icons etc ko = ImageTk.PhotoImage(ko) # create a label kok = Label(win, image=ko) # set the image as img kok.image = ko kok.place(x=35, y=160)
# Playing around with TinyTag from tinytag import TinyTag mp3_file_name = "/Users/mgermaine93/Desktop/Test-Music/03 Dylan Thomas.mp3" m4a_file_name = "/Users/mgermaine93/Desktop/Test-Music/03 Dylan Thomas.m4a" album_art = "/Users/mgermaine93/Desktop/better oblivion community center.jpg" tag = TinyTag.get(mp3_file_name, image=True) image_data = tag.get_image() print(image_data) # This prints "None" tag2 = TinyTag.get(m4a_file_name, image=True) image_data_2 = tag.get_image() print(image_data_2) # This also prints "None"
files = [f for f in listdir(folder) if isfile(join(folder, f))] # Usually music folders have one .nfo file for file in reversed(files): if file.endswith(".nfo"): os.remove(os.path.join(folder, file)) break # Remove artist name from the filename # This is only for CD album folders, not for folders with mixed artists temp = None replace_with = "" for file in files: if file.endswith((".mp3", ".flac", ".wav", ".ogg", ".mp4", ".m4a", ".wma", ".wave", ".opus")): tag = TinyTag.get(os.path.join(folder, file)) artist = tag.artist if temp == None: if artist not in file: break if artist + " - " in file: temp = artist + " - " elif "-" + artist + "-": temp = "-" + artist + "-" replace_with = " - " os.rename(os.path.join(folder, file), os.path.join(folder, file.replace(temp, replace_with)))
import random import time from tinytag import TinyTag as tg dirpath = os.path.abspath("----your songs dir path----") #songs dir songs=[] for i in os.listdir(dirpath): songs.append("----your songs dir path----"+i) l=len(songs) st=set() while True: initsize=len(st) fl=random.choice(songs) st.add(fl) aftersize=len(st) if initsize!=aftersize: os.startfile(fl) msg = fl.split('\\') print("Playing ",msg[5]) #msg[---vary acc to path args---] if aftersize==l: break else: tag = tg.get(fl) time.sleep(tag.duration) #get info about file using tinytag lib continue
def getInfo(self, targetFolderPath_list: list): """ 从指定的目录读取符合匹配规则的歌曲的标签卡信息 """ filePath_list = [] self.targetFolderPath_list = targetFolderPath_list for target_path in self.targetFolderPath_list: absPath_list = [ os.path.join(target_path, filename) for filename in os.listdir(target_path) ] # 更新文件路径列表 filePath_list += [ filePath for filePath in absPath_list if os.path.isfile(filePath) ] # 获取符合匹配音频文件名和路径列表 self.__splitSonglist(filePath_list) # 如果数据文件夹不存在就创建一个 if not os.path.exists('Data'): os.mkdir('Data') # 从json文件读取旧信息 try: with open('Data\\songInfo.json', 'r', encoding='utf-8') as f: oldData = json.load(f) except: oldData = [{}] oldSongPath_list = [ oldFileInfo.get('songPath') for oldFileInfo in oldData ] # 判断旧文件路径列表是否与新文件名列表相等 if set(self.songPath_list) == set(oldSongPath_list) and len( oldSongPath_list) == len(self.songPath_list): # 如果文件路径完全相等就直接获取以前的文件信息并返回 self.songInfo_list = oldData.copy() return newSongPath_set = set(self.songPath_list) oldSongPath_set = set(oldSongPath_list) # 计算文件路径差集 diffSongPath_list = list(newSongPath_set - oldSongPath_set) # 计算文件路径的并集 commonSongPath_set = newSongPath_set & oldSongPath_set # 根据文件路径并集获取部分文件信息字典 if commonSongPath_set: self.songInfo_list = [ oldSongInfo_dict for oldSongInfo_dict in oldData if oldSongInfo_dict['songPath'] in commonSongPath_set ] # 如果有差集的存在就需要更新json文件 if not (newSongPath_set < oldSongPath_set and commonSongPath_set): # 获取后缀名,歌名,歌手名列表 self.__splitSonglist(diffSongPath_list, flag=1) argZip = zip(self.song_list, self.songPath_list, self.songname_list, self.songer_list, self.suffix_list) for index, (song, songPath, songname, songer, suffix) in enumerate(argZip): id_card = TinyTag.get(songPath) # 获取时间戳 createTime = QFileInfo(songPath).birthTime().toString( Qt.ISODate) album_list, tcon, year, duration, tracknumber = self.__getAlbumTconYear( suffix, id_card, songPath) # 将歌曲信息字典插入列表 self.songInfo_list.append({ 'song': song, 'songPath': songPath, 'songer': songer, 'songName': songname, 'album': album_list[0], # album为原专辑名 'modifiedAlbum': album_list[-1], # modifiedAlbum为修改后的专辑名 'tcon': tcon, 'year': year, 'tracknumber': tracknumber, 'duration': duration, 'suffix': suffix, 'createTime': createTime }) self.sortByCreateTime() # 更新json文件 with open('Data\\songInfo.json', 'w', encoding='utf-8') as f: json.dump(self.songInfo_list, f)
def getCoverImg(self, f): self.__tag = TinyTag.get(f, image=True) self.__img_data = self.__tag.get_image()
def getTags(song): tag = TinyTag.get(song) return (tag)
def test_mp4_image_loading(): tag = TinyTag.get(os.path.join(testfolder, 'samples/iso8859_with_image.m4a'), image=True) image_data = tag.get_image() assert image_data is not None assert 20000 < len(image_data) < 25000, 'Image is %d bytes but should be around 22kb' % len(image_data)
def test_to_str(): tag = TinyTag.get(os.path.join(testfolder, 'samples/empty.ogg')) assert str(tag) # since the dict is not ordered we cannot == 'somestring' assert repr(tag) # since the dict is not ordered we cannot == 'somestring'
def test_mp3_image_loading_without_description(): tag = TinyTag.get(os.path.join(testfolder, 'samples/id3image_without_description.mp3'), image=True) image_data = tag.get_image() assert image_data is not None assert 28600 < len(image_data) < 28700, 'Image is %d bytes but should be around 28.6kb' % len(image_data) assert image_data.startswith(b'\xff\xd8\xff\xe0'), 'The image data must start with a jpeg header'
def test_mp3_id3v22_image_loading(): tag = TinyTag.get(os.path.join(testfolder, 'samples/id3v22_image.mp3'), image=True) image_data = tag.get_image() assert image_data is not None assert 18000 < len(image_data) < 19000, 'Image is %d bytes but should be around 18.1kb' % len(image_data) assert image_data.startswith(b'\xff\xd8\xff\xe0'), 'The image data must start with a jpeg header'
filenames = sys.argv[1:] except Exception as exc: print(exc) usage() header_printed = False for i, filename in enumerate(filenames): try: if skip_unsupported: if os.path.isdir(filename): continue if not TinyTag.is_supported(filename): # sys.stderr.write('%s: skipping unsupported file\n' % filename) continue tag = TinyTag.get(filename, image=save_image_path is not None) if save_image_path: # allow for saving the image of multiple files actual_save_image_path = save_image_path if len(filenames) > 1: actual_save_image_path, ext = splitext(actual_save_image_path) actual_save_image_path += '%05d' % i + ext image = tag.get_image() if image: with open(actual_save_image_path, 'wb') as fh: fh.write(image) data = {'filename': filename} data.update(tag.as_dict()) if formatting == 'json': print(json.dumps(data)) elif formatting == 'csv':
def get_chapter_number(file): file_info = TinyTag.get(file.name) return str(int(json.loads(file_info.artist)['chapter']))