def echoprint_lookup(file): # Note that song.identify reads just the first 30 seconds of the file fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=fp, version="4.11") pprint.pprint(result)
def main(folder): if folder.endswith('.mp3'): files = [folder] else: # iterate over all .mp3 files in this directory, and identify them. files = [fullpath(folder, f) for f in os.listdir(folder) if f.endswith('.mp3')] updated = 0 for path in files: print os.path.basename(path) songs = None try: songs = song.identify(path, buckets=['audio_summary']) except EchoNestAPIError, e: print "API Error: %s" % e continue s = songs and songs.pop() if not s: print "Couldn't resolve %s" % path continue m = Metadata(s) m.write_id3(path, create_only=False, replace=False) updated += 1
def id_song(filename): metadata = {} config.ECHO_NEST_API_KEY = API_KEY song_info = song.identify(filename) metadata["title"]= song_info[0].title metadata["artist"] = song_info[0].artist_name #results = song.search(metadata["title"], metadata["artist"], #buckets=["tracks", "id:7digital-US"])[0] return metadata
def fetch_data(filepaths, result=None, overwrite=False, checkpoint_file=''): """ Parameters ---------- filepaths : list Collection of audio files on disk to query against the EchoNest API. result : dict, or None Dictionary to add info; will create if None. overwrite : bool, default=False If False, will skip any keys contained in `result`. checkpoint_file : str, or None Path to write results as they are accumulated; ignored if empty. Returns ------- result : dict Map of filebases to metadata. """ throttle = Throttle() throttle.touch() if result is None: result = dict() filepaths = set(filepaths) while filepaths: fpath = filepaths.pop() key = futil.filebase(fpath) # If we've already got data and we're not overwriting, move on. if key in result and not overwrite: print "[%s] %4d: '%s'" % (time.asctime(), len(filepaths), key) continue try: # Otherwise, let's make some requests. print "[%s] %4d: '%s'" % (time.asctime(), len(filepaths), key) song = S.identify(filename=fpath, codegen_start=0, codegen_duration=60) if song: result[key] = extract_info(song[0]) if checkpoint_file: with open(checkpoint_file, 'w') as fp: json.dump(result, fp, indent=2) throttle.wait() except S.util.EchoNestAPIError as err: if err.http_status == 429: print "You got rate limited braah ... hang on." throttle.wait(10) filepaths.add(fpath) elif err.http_status >= 500: print "Server error; moving on, dropping key: %s" % key except socket.error as err: print "Socket Error %s" % err filepaths.add(fpath) throttle.wait(10) return result
def lookup(file): # Note that song.identify reads just the first 30 seconds of the file fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=fp, version="4.11") print "Got result:", result print "Artist: %s (%s)" % (result[0].artist_name, result[0].artist_id) print "Song: %s (%s)" % (result[0].title, result[0].id) else: print "Couldn't decode", file
def fetch_data(filepaths, result=None, overwrite=False, checkpoint_file=''): """ Parameters ---------- filepaths : list Collection of audio files on disk to query against the EchoNest API. result : dict, or None Dictionary to add info; will create if None. overwrite : bool, default=False If False, will skip any keys contained in `result`. checkpoint_file : str, or None Path to write results as they are accumulated; ignored if empty. Returns ------- result : dict Map of filebases to metadata. """ throttle = Throttle() throttle.touch() if result is None: result = dict() filepaths = set(filepaths) while filepaths: fpath = filepaths.pop() key = futil.filebase(fpath) # If we've already got data and we're not overwriting, move on. if key in result and not overwrite: print "[%s] %4d: '%s'" % (time.asctime(), len(filepaths), key) continue try: # Otherwise, let's make some requests. print "[%s] %4d: '%s'" % (time.asctime(), len(filepaths), key) song = S.identify( filename=fpath, codegen_start=0, codegen_duration=60) if song: result[key] = extract_info(song[0]) if checkpoint_file: with open(checkpoint_file, 'w') as fp: json.dump(result, fp, indent=2) throttle.wait() except S.util.EchoNestAPIError as err: if err.http_status == 429: print "You got rate limited braah ... hang on." throttle.wait(10) filepaths.add(fpath) elif err.http_status >= 500: print "Server error; moving on, dropping key: %s" % key except socket.error as err: print "Socket Error %s" % err filepaths.add(fpath) throttle.wait(10) return result
def update_echonest_tags(self): """Obtain echoprint tags (if exist) for sourcefile. Generate echoprint code if required""" # Fragments taken from echonest's echonest-codegen lookup.py script if not self.echoprint_code: self.echoprint_codegen() # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=self.echoprint_code, version="4.11") if len(result): self.echoprint_tags = result
def scanFolder(folder): if isinstance(folder, list): files = folder elif os.path.isdir(folder): files = getNamesAndGenreFromFolder(folder) else: return -1 notAtEcho=[] notScanned=[] foundTracks = [] retry=[] i=0 if not os.path.isdir('echoNestResults'): os.mkdir('echoNestResults') for f in files: time = t.localtime() time = str(time.tm_hour) +'_' + str(time.tm_min) + '_' + str(time.tm_sec) try: print 'decodeing' print f code = getENMFPcode(f) try: print 'looking up on echonest' track = song.identify(query_obj=code) except: print "couldn't connect to server" retry.append(f) if not track: print 'song not at echonest' notAtEcho.append(f) continue print 'track:',track track=track[0] trackInfo = [f, track.audio_summary['tempo'], track.audio_summary['time_signature'], track.id] foundTracks.append(trackInfo) pickle.dump(foundTracks, open('echoNestResults/'+str(i)+'-'+time+'.pkl', 'w')) try: tag = d3.load(f).tag tag.copyright_url = 'echo' tag.bpm = track.audio_summary['tempo'] tag.save() except: print 'id3 fail' except : print "couldn't scan", sys.exc_info()[0] notScanned.append(f) i+=1 return foundTracks, notAtEcho, notScanned, retry
def lookup(file): # Note that song.identify reads just the first 30 seconds of the file # Also you'll need the codegen binary fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: result = song.identify(query_obj=fp, version="4.12") if len(result): artist = result[0].artist_name title = result[0].title return (title, artist) else: return None else: print "Error: Couldn't decode", file
def lookup(file): # song.identify reads the first 30 seconds of the file fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=fp, version="4.11") print "Got result:", result if len(result): print "Artist: %s (%s)" % (result[0].artist_name, result[0].artist_id) print "Song: %s (%s)" % (result[0].title, result[0].id) else: print "No match. This track may not be in the database yet." else: print "Couldn't decode", file
def lookup(file): # Note that song.identify reads just the first 30 seconds of the file fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=fp, version="4.12") print "Got result:", result if len(result): print "Artist: %s (%s)" % (result[0].artist_name, result[0].artist_id) print "Song: %s (%s)" % (result[0].title, result[0].id) else: print "No match. This track may not be in the database yet." else: print "Couldn't decode", file
def identify_song(tag): """ Uses the Echonest API to try identifying a song Returns: None if no results were found from any hosts Returns a list of artist + title names if successful """ result = song.identify(query_obj=tag) if result: return [{ 'artist': r.artist_name, 'title': r.title } for r in result] else: return None
def store_en_info(enmfp, url): u = urlparse(url) s = song.identify(code=enmfp)[0] #TODO deal with more than one match a = artist.Artist(id=s.artist_id) #TODO find out if we can get release info too redis_client.set('en_songs:%s' % s.id, json.dumps(s.__dict__)) redis_client.set('en_artists:%s' % a.id, json.dumps(a.__dict__)) redis_client.set('en_enmfp_by_path:%s' % u.path, enmfp) redis_client.set('en_song_ids_by_enmfp:%s' % enmfp, s.id) # Only lookup/store artist terms if we dont have yet key = 'en_artist_terms:%s' % a.id if not redis_client.get(key): redis_client.set(key, json.dumps(a.terms)) return {'song': s, 'artist': a}
def store_en_info(url): u = urlparse(url) # Calc or fetch enmfp from cache sha = sha256_for_file(u.path) key = 'en_enmfp_by_sha:%s' % sha enmfp = redis_client.get(key) if not enmfp: enmfp = get_enmfp_json_from_mp3(url) enmfp = redis_client.set(key, enmfp) # Do we have this song result in redis? en_song_id = redis_client.get('en_song_ids_by_enmfp:%s' % enmfp) if en_song_id: return {'result': 'exists'} # we've already handled this song, so dont do anyhting for it # Still here? Go to EN API for the song and artist info and store it s_results = song.identify(code=enmfp) if len(s_results) == 0: error = "*** ID FAIL %s with code %s" % (url, enmfp) print error return { 'result': 'error', 'error': error} else: s = s_results[0] print "ID %s" % (url) a = artist.Artist(id=s.artist_id) #TODO get release info somehow (via en track query then rosetta lookup?) # Add artist terms to artist obj for json dump ao = a.__dict__ ao['terms'] = a.terms redis_client.set('en_songs:%s' % s.id, json.dumps(s.__dict__)) redis_client.set('en_artists:%s' % a.id, json.dumps(ao)) redis_client.set('en_enmfp_by_path:%s' % u.path, enmfp) redis_client.set('en_song_ids_by_enmfp:%s' % enmfp, s.id) # Only lookup/store artist terms if we dont have yet key = 'en_artist_terms:%s' % a.id if not redis_client.get(key): redis_client.set(key, json.dumps(a.terms)) return {'result': 'ok', 'song': s, 'artist': a, 'enmfp': enmfp}
def lookup(file): # Note that song.identify reads just the first 30 seconds of the file fp = song.util.codegen(file) if len(fp) and "code" in fp[0]: # The version parameter to song/identify indicates the use of echoprint result = song.identify(query_obj=fp, version="4.11") # print "Got result:", result if len(result): print '{' print ' "artist": { "name": "%s", "id": "%s" },' % ( result[0].artist_name.encode('utf-8'), result[0].artist_id) print ' "song": { "title": "%s", "id": "%s" }' % ( result[0].title.encode('utf-8'), result[0].id) print '}' else: print '{ "error": "No match. This track may not be in the database yet" }' else: print '{ "error": "Couldn\'t decode %s" }' % file
def extract_using_echonest(file_): # Get length try: madf = mad.MadFile(file_) length = madf.total_time() // 1000 except: length = None # Identify via Echo Nest config.ECHO_NEST_API_KEY = 'UR4VKX7JXDXAULIWB' config.CODEGEN_BINARY_OVERRIDE = '/usr/bin/echoprint-codegen' try: possible_songs = identify(filename=file_) if possible_songs: song = possible_songs[0] return SongInfo(song.title, song.artist_name, '', length, None, None, None) else: return empty_song_info() except: return empty_song_info()
def match_song(duration, filename): """return artist and title of song in filename""" if FP_SERVICE == "acoustid": try: results = acoustid.match(ACOUSTID_API_KEY, filename) except: return (None, None) try: score, recording_id, title, artist = results.next() return Song(artist=artist, title=title) except: return (None, None) elif FP_SERVICE == "echonest": try: results = ensong.identify(filename, codegen_duration=duration, codegen_start=0) song = results[0] return Song(artist=song.artist_name, title=song.title) except: return (None, None) return (None, None)
def _query_echonest(self, fingerprint): result = song.identify(code=fingerprint) return result
def tagSong(filename): # Get status info statusfile = os.path.expanduser("~/.scrobbyl") lines = [] if os.path.exists(statusfile): fp = open(statusfile, "r") lines = fp.readlines() fp.close() lasttime = 0 lastartist = "" lasttrack = "" lastscrobble = 0 if len(lines) == 4: lasttime = int(lines[0]) lastartist = lines[1].strip() lasttrack = lines[2].strip() lastscrobble = int(lines[3]) fp = song.util.codegen(filename) pprint.pprint(fp) # Make sure we have a valid fp if fp == None or len(fp) == 0 or "code" not in fp[0]: raise Exception("Could not calculate fingerprint!") result = song.identify(query_obj=fp, version="4.11", buckets="audio_summary") pprint.pprint(result) if len(result) == 0: raise Exception("Song not found in database.") track = result[0].title artist = result[0].artist_name songlength = result[0].audio_summary.duration # Check to make sure it's not a duplicate now = time.time() doscrobble = True if lasttime: if (now - lasttime) < 100: # Check for duplicate song if lasttrack == track and lastartist == artist: # if config.getboolean('scrobble_rules','allow_repeat') and prevlength < (now - config.get('runtime_info','last_scrobble')): if False: print "Same song, but looks like it repeated..." else: print "Same song as last time, skipping..." doscrobble = False else: print "New song!" else: print "It's been longer than the songlength since we last checked." else: lasttrack = lastartist = "none" print "No previous song found." if doscrobble: print "Last track was %s by %s, now %s by %s. Scrobbling..." % (lasttrack, lastartist, track, artist) # lastfm.scrobble(artist, track) lastscrobble = now fp = open(statusfile, "w") fp.write("%d\n%s\n%s\n%d" % (now, artist, track, lastscrobble)) fp.close() return (track, artist, doscrobble)
def tagSong(filename): #Get status info statusfile = os.path.expanduser("~/.scrobbyl") lines = [] if os.path.exists(statusfile): fp = open(statusfile, "r") lines = fp.readlines() fp.close() lasttime = 0 lastartist = "" lasttrack = "" lastscrobble = 0 if len(lines) == 4: lasttime = int(lines[0]) lastartist = lines[1].strip() lasttrack = lines[2].strip() lastscrobble = int(lines[3]) fp = song.util.codegen(filename) pprint.pprint(fp) #Make sure we have a valid fp if fp == None or len(fp) == 0 or "code" not in fp[0]: raise Exception("Could not calculate fingerprint!") result = song.identify(query_obj=fp, version="4.11", buckets="audio_summary") pprint.pprint(result) if len(result) == 0: raise Exception("Song not found in database.") track = result[0].title artist = result[0].artist_name songlength = result[0].audio_summary.duration #Check to make sure it's not a duplicate now = time.time() doscrobble = True if lasttime: if (now - lasttime) < 100: #Check for duplicate song if lasttrack == track and lastartist == artist: #if config.getboolean('scrobble_rules','allow_repeat') and prevlength < (now - config.get('runtime_info','last_scrobble')): if False: print "Same song, but looks like it repeated..." else: print "Same song as last time, skipping..." doscrobble = False else: print "New song!" else: print "It's been longer than the songlength since we last checked." else: lasttrack = lastartist = "none" print "No previous song found." if (doscrobble): print "Last track was %s by %s, now %s by %s. Scrobbling..." % ( lasttrack, lastartist, track, artist) #lastfm.scrobble(artist, track) lastscrobble = now fp = open(statusfile, "w") fp.write("%d\n%s\n%s\n%d" % (now, artist, track, lastscrobble)) fp.close() return (track, artist, doscrobble)
def lookupEcho(code): track = song.identify(query_obj=code) return track