コード例 #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_tracks(track):
        try:
            song = from_spotify_url(
                "https://open.spotify.com/track/" + track["id"],
                output_format,
                use_youtube,
                lyrics_provider,
                None,
            )

            if generate_m3u:
                if path_template:
                    file_path = _parse_path_template(path_template, song, output_format)
                else:
                    file_path = _get_converted_file_path(song, output_format)

                return song, f"{file_path}\n"

            return song, None
        except (LookupError, ValueError):
            return None, None
        except OSError:
            if generate_m3u:
                song_obj = SongObject(track, album_response, {}, None, "", None)
                if path_template:
                    file_path = _parse_path_template(
                        path_template, song_obj, output_format
                    )
                else:
                    file_path = _get_converted_file_path(song_obj, output_format)

                return None, f"{file_path}\n"

            return None, None
コード例 #3
0
    def get_song(track):
        try:
            song = from_spotify_url(
                "https://open.spotify.com/track/" + track["track"]["id"],
                output_format,
                use_youtube,
                lyrics_provider,
                playlist,
            )

            if generate_m3u:
                file_path = _parse_path_template(path_template, song, output_format)

                return song, f"{file_path}\n"

            return song, None
        except (LookupError, ValueError):
            return None, None
        except OSError:
            if generate_m3u:
                song_obj = SongObject(
                    {*track["track"]}, {}, {}, None, "", playlist_response
                )
                file_path = _parse_path_template(path_template, song_obj, output_format)

                return None, f"{file_path}\n"

            return None, None
コード例 #4
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)
コード例 #5
0
def from_dump(data_dump: dict) -> SongObject:
    """
    Creates song object from data dump

    `dict` `data_dump` : data dump used to create song object

    returns `SongObject`
    """

    raw_track_meta = data_dump["raw_track_meta"]
    raw_album_meta = data_dump["raw_album_meta"]
    raw_artist_meta = data_dump["raw_artist_meta"]
    youtube_link = data_dump["youtube_link"]
    lyrics = data_dump["lyrics"]

    return SongObject(raw_track_meta, raw_album_meta, raw_artist_meta,
                      youtube_link, lyrics, None)
コード例 #6
0
def create_song_obj(name: str = None,
                    artists_input: list = None) -> SongObject:
    if name == None:
        song_name = "test song"
    else:
        song_name = name

    if artists_input == None:
        artist_objs = list(map(lambda x: {"name": x}, ["test artist"]))
    else:
        artist_objs = list(map(lambda x: {"name": x}, artists_input))

    raw_track_meta = {
        "name": song_name,
        "album": {
            "name":
            "test album",
            "artists":
            artist_objs,
            "release_date":
            "2021",
            "images": [{
                "url":
                "https://i.ytimg.com/vi_webp/iqKdEhx-dD4/hqdefault.webp"
            }],
        },
        "artists": artist_objs,
        "track_number": "1",
        "genres": ["test genre"],
    }

    raw_album_meta = {"genres": ["test genre"]}
    raw_artist_meta = {"genres": ["test artist genre"]}

    return SongObject(
        raw_track_meta,
        raw_album_meta,
        raw_artist_meta,
        "https://www.youtube.com/watch?v=Th_C95UMegc",
        "test lyrics",
        None,
    )
コード例 #7
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
    )