Example #1
0
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)
Example #2
0
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)
Example #3
0
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
Example #4
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
 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
Example #9
0
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
Example #10
0
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
Example #11
0
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
Example #12
0
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
Example #14
0
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}
Example #15
0
File: test.py Project: lhl/songclub
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}
Example #17
0
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
Example #18
0
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()
Example #19
0
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)
Example #20
0
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)
Example #21
0
 def _query_echonest(self, fingerprint):
     result = song.identify(code=fingerprint)
     
     return result
Example #22
0
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)
Example #23
0
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)
Example #24
0
def lookupEcho(code):
    track = song.identify(query_obj=code)
    return track