예제 #1
0
def get_youtube_meta_track(youtube_url: str,
                           spotify_url: str,
                           output_format: str = None):
    # check if URL is a playlist, user, artist or album, if yes raise an Exception,
    # else procede

    # Get the Song Metadata
    print(f"Gathering Spotify Metadata for: {spotify_url}")
    raw_track_meta, raw_artist_meta, raw_album_meta = metadata_provider.from_url(
        spotify_url)

    song_name = raw_track_meta["name"]
    contributing_artist = []
    for artist in raw_track_meta["artists"]:
        contributing_artist.append(artist["name"])

    converted_file_name = SongObject.create_file_name(
        song_name, [artist["name"] for artist in raw_track_meta["artists"]])

    if output_format is None:
        output_format = "mp3"

    converted_file_path = Path(".", f"{converted_file_name}.{output_format}")

    # if a song is already downloaded skip it
    if converted_file_path.is_file():
        print(f'Skipping "{converted_file_name}" as it\'s already downloaded')
        return None

    # (try to) Get lyrics from Genius
    lyrics = provider_utils._get_song_lyrics(song_name, contributing_artist)

    return SongObject(raw_track_meta, raw_album_meta, raw_artist_meta,
                      youtube_url, lyrics)
예제 #2
0
def get_youtube_meta_track(
    youtube_url: str,
    spotify_url: str,
    output_format: str = None,
    lyrics_provider: str = None,
):
    # check if URL is a playlist, user, artist or album, if yes raise an Exception,
    # else procede

    # Get the Song Metadata
    raw_track_meta, raw_artist_meta, raw_album_meta = metadata_provider.from_url(
        spotify_url)

    song_name = raw_track_meta["name"]
    contributing_artist = [
        artist["name"] for artist in raw_track_meta["artists"]
    ]
    converted_file_name = SongObject.create_file_name(
        song_name, [artist["name"] for artist in raw_track_meta["artists"]])

    if output_format is None:
        output_format = "mp3"

    converted_file_path = Path(".", f"{converted_file_name}.{output_format}")

    # if a song is already downloaded skip it
    if converted_file_path.is_file():
        print(f'Skipping "{converted_file_name}" as it\'s already downloaded')
        return None

    # (try to) Get lyrics from musixmatch/genius
    # use musixmatch as the default provider
    if lyrics_provider == "genius":
        lyrics = lyrics_providers.get_lyrics_genius(song_name,
                                                    contributing_artist)
    else:
        lyrics = lyrics_providers.get_lyrics_musixmatch(
            song_name, contributing_artist)

    return SongObject(raw_track_meta, raw_album_meta, raw_artist_meta,
                      youtube_url, lyrics, None)
예제 #3
0
def from_spotify_url(
    spotify_url: str,
    output_format: str = None,
    use_youtube: bool = False,
    lyrics_provider: str = None,
    playlist: dict = None,
) -> SongObject:
    """
    Creates song object using spotfy url

    `str` `spotify_url` : spotify url used to create song object
    `str` `output_format` : output format of the song

    returns a `SongObject`
    """

    # Set default ouput format to mp3
    if output_format is None:
        output_format = "mp3"

    # Get the Song Metadata
    raw_track_meta, raw_artist_meta, raw_album_meta = metadata_provider.from_url(
        spotify_url
    )

    if raw_track_meta is None:
        raise ValueError("Couldn't get metadata from url")

    song_name = raw_track_meta["name"]
    album_name = raw_track_meta["album"]["name"]
    isrc = raw_track_meta.get("external_ids", {}).get("isrc")
    duration = round(raw_track_meta["duration_ms"] / 1000, ndigits=3)
    contributing_artists = [artist["name"] for artist in raw_track_meta["artists"]]
    display_name = ", ".join(contributing_artists) + " - " + song_name

    # Create file name
    converted_file_name = SongObject.create_file_name(
        song_name, [artist["name"] for artist in raw_track_meta["artists"]]
    )

    # If song name is too long use only first artist
    if len(converted_file_name) > 250:
        converted_file_name = SongObject.create_file_name(
            song_name, [raw_track_meta["artists"][0]["name"]]
        )

    converted_file_path = Path(".", f"{converted_file_name}.{output_format}")

    # Alternate file path.
    alternate_file_path = Path(".", f"{display_name}.{output_format}")

    # if a song is already downloaded skip it
    if converted_file_path.is_file() or alternate_file_path.is_file():
        print(f'Skipping "{converted_file_name}" as it\'s already downloaded')
        raise OSError(f"{converted_file_name} already downloaded")

    # Get the song's downloadable audio link
    if use_youtube:
        print(f'Searching YouTube for "{display_name}"', end="\r")
        youtube_link = yt_provider.search_and_get_best_match(
            song_name, contributing_artists, duration, isrc
        )
    else:
        print(f'Searching YouTube Music for "{display_name}"', end="\r")
        youtube_link = ytm_provider.search_and_get_best_match(
            song_name, contributing_artists, album_name, duration, isrc
        )

    # Check if we found youtube url
    if youtube_link is None:
        print(
            f'Could not match any of the results on YouTube for "{display_name}". Skipping'
        )
        raise LookupError("Could not match any of the results on YouTube for")
    else:
        print(" " * (len(display_name) + 25), end="\r")
        print(f'Found YouTube URL for "{display_name}" : {youtube_link}')

    # (try to) Get lyrics from musixmatch/genius
    # use musixmatch as the default provider
    if lyrics_provider == "genius":
        lyrics = lyrics_providers.get_lyrics_genius(song_name, contributing_artists)
    else:
        lyrics = lyrics_providers.get_lyrics_musixmatch(song_name, contributing_artists)

    return SongObject(
        raw_track_meta, raw_album_meta, raw_artist_meta, youtube_link, lyrics, playlist
    )