diff --git a/beetsplug/echonest_tempo.py b/beetsplug/echonest_tempo.py index b2178485c..2810b30ba 100644 --- a/beetsplug/echonest_tempo.py +++ b/beetsplug/echonest_tempo.py @@ -45,7 +45,7 @@ def fetch_item_tempo(lib, loglevel, item, write): return # Fetch tempo. - tempo = get_tempo(item.artist, item.title) + tempo = get_tempo(item.artist, item.title, item.length) if not tempo: log.log(loglevel, u'tempo not found: %s - %s' % (item.artist, item.title)) @@ -59,12 +59,12 @@ def fetch_item_tempo(lib, loglevel, item, write): item.store() -def get_tempo(artist, title): +def get_tempo(artist, title, duration): """Get the tempo for a song.""" # We must have sufficient metadata for the lookup. Otherwise the API # will just complain. - artist = artist.replace(u'\n', u' ').strip() - title = title.replace(u'\n', u' ').strip() + artist = artist.replace(u'\n', u' ').strip().lower() + title = title.replace(u'\n', u' ').strip().lower() if not artist or not title: return None @@ -74,7 +74,7 @@ def get_tempo(artist, title): # EchoNest supports foreign ids from MusicBrainz, but currently # only for artists, not individual tracks/recordings. results = pyechonest.song.search( - artist=artist, title=title, results=1, + artist=artist, title=title, results=100, buckets=['audio_summary'] ) except pyechonest.util.EchoNestAPIError as e: @@ -99,9 +99,19 @@ def get_tempo(artist, title): # So we look through the results for songs that have the right # artist and title. The API also doesn't have MusicBrainz track IDs; # otherwise we could use those for a more robust match. + min_distance = duration + pick = None for result in results: - if result.artist_name == artist and result.title == title: - return results[0].audio_summary['tempo'] + if result.artist_name.lower() == artist and result.title.lower() == title: + distance = abs(duration - result.audio_summary['duration']) + log.debug(u'echonest_tempo: candidate {} - {} [abs({:2.2f}-{:2.2f})={:2.2f}] = {}'.format( + result.artist_name, result.title, + result.audio_summary['duration'], duration, distance, + result.audio_summary['tempo'])) + if distance < min_distance: + min_distance = distance + pick = result.audio_summary['tempo'] + return pick class EchoNestTempoPlugin(BeetsPlugin):