Skip to content

Tidal._search_track() could be improved #2

Description

@stephanlensky

Hey there--came across this project while writing something very similar myself. For my own purposes, I wanted something that could convert playlists more accurately (attempting to preserve albums, etc.) than any of the existing conversion services or scripts.

Just thought you might be interested in the solution I came up with, feel free to take or adapt it to your own code. If not, feel free to ignore and close this!

It's a little rough around the edges, I was just trying to get something down that worked.

def sanitize_name(name):
    # tidal songs don't always contain "(feat. whoever)" at the end of titles
    # best to strip it from the search
    regex = r' \((feat|ft)\.? .+?\)'
    name = re.sub(regex, '', name)
    
    # tidal titles don't always use parens or hyphens in the same way that spotify titles do
    # strip those as well
    return name.replace('(', '').replace(')', '').replace(' - ', ' ')

# artists and album_artists are string arrays of artist names provided from spotipy
def find_tidal_track(tidal, title, artists, album, album_artists):
    title = sanitize_name(title)

    # initial filter by title and album artist match
    query = '{} {}'.format(title, artists[0])
    track_results = tidal.search('track', query).tracks
    results = []
    for r in track_results:
        name = sanitize_name(r.name)
        if name == title and r.album.artist.name == album_artists[0]:
            results.append(r)

    # if there are no results with the initial filter, the song can't be found
    if not len(results):
        return None

    # if we can find an exact album match, prefer that
    for r in results:
        if sanitize_name(r.album.name) == sanitize_name(album):
            return r

    # otherwise, try to match an album published by the original artist
    artist_albums = tidal.get_artist_albums(results[0].album.artist.id)
    for a in artist_albums:
        for r in results:
            if r.album.name == a.name:
                return r

    return None

Doing it like this almost perfectly guarantees no false positives, and correctly filters out compilation albums.

It will occasionally fail to match songs that are actually on Tidal, but I wasn't sure how to avoid this. For example, the track by Bernhoft named In Tangerine - Bonus Track is just named In Tangerine on Tidal. As a result, searching for the string "In Tangerine Bonus Track" on Tidal yields no results.

Mostly though it works pretty well!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions