Skip to content

How to get high quality covers for all your music

Guillermo Loaysa edited this page Mar 16, 2024 · 1 revision

Copy this python script (download_covers.py).

Be sure to fill the path to MUSIC_FOLDER.

Do not trust me (or anything on the Internet) blindly. Make a test run first on a directory containing a couple of artists/albums (maybe copy/paste them from your music folder to any other place) and run the script on it first.

To avoid getting wrong album covers, the script will not download anything if the album name and artists don't match.

It will log to the console when it couldn't find a cover, so you are aware of it.

You will have to install request for it to work:

pip install requests

then you can run the script like this:

python download_covers.py.

"""
Get the artwork for the music in the music directory.
Add to MUSIC_FOLDER the path to the music folder.
By default, the script will download a .png file named cover.png and delete any .jpg/.jpeg files inside the album.
I strongly recommend making a first run commenting out the delete_jpg_files function inget_album_cover_and_delete_old_one
to make sure the script works as expected.
If you currently have png cover files, change the name of the file to cover_example.png or whatever in process_album function.
The script will also download the highest resolution image available.
"""

import os
import glob
from urllib.parse import quote_plus

import requests

MUSIC_FOLDER = "path/to/music/folder"


def delete_jpg_files(directory: str):
    """
    Deletes all .jpg and .jpeg files in the specified directory if a .png file is present.
    """
    try:
        # Check if there's a .png file in the directory
        if glob.glob(os.path.join(directory, '*.png')):
            for file in glob.glob(os.path.join(directory, '*')):
                if file.lower().endswith(('.jpg', '.jpeg')):
                    os.remove(file)
    except Exception as e:
        print("An error occurred while deleting .jpg and .jpeg files in the directory %s: %s", directory, e)


def download_image(url: str, path: str):
    """
    Downloads the image from the url and saves it in the path.
    """
    try:
        response = requests.get(url, stream=True, timeout=10)
        if response.status_code == 200:
            with open(path, 'wb') as file:
                for chunk in response.iter_content(1024):
                    file.write(chunk)
        else:
            print("Failed to download image. Server responded with status code %s.", response.status_code)
    except Exception as e:
        print("An error occurred while downloading the image from %s: %s", url, e)


def process_album(album_path: str, artist_name: str, album_name: str):
    """
    Retrieves the artwork for the album.
    """
    try:
        album_name_encoded = quote_plus(album_name)
        url = f"https://itunes.apple.com/search?term={album_name_encoded}&country=es&media=music&entity=album"
        response = requests.get(url, timeout=10)
        parsed_response = response.json()
        if not parsed_response["results"]:
            print("No album cover found for %s by %s", album_name, artist_name)
            return
        for result in parsed_response["results"]:
            if result["artistName"].lower() == artist_name.lower():
                artwork_url = result["artworkUrl100"]
                artwork_url = artwork_url.replace("100x100bb", "1500x1500-999")  # Download image at highest resolution
                download_image(artwork_url, os.path.join(album_path, 'cover.png'))
                return
    except Exception as e:
        print("An error occurred while retrieving the artwork for the album %s by %s: %s", album_name,
                      artist_name, e)


def get_album_cover_and_delete_old_one(album_dir: str, artist: str, album: str):
    """
    Deletes .jpg and .jpeg files inside the album directory if a .png file is present,
    and retrieves the artwork for the album.
    """
    try:
        print("Getting cover for: %s by %s in path %s", album, artist, album_dir)
        if os.path.isdir(album_dir):  # Check if it's a directory
            process_album(album_dir, artist, album)
            delete_jpg_files(album_dir)  # Delete any existing .jpg or .jpeg files
    except Exception as e:
        print("An error occurred while processing the album %s by %s: %s", album, artist, e)


if __name__ == "__main__":
    """
    Iterates over all the directories in the music folder and retrieves the artwork for the albums.
    Assumes the music folder is structured as follows:
    music_folder/artists/albums/songs
    """
    for artist in os.listdir(MUSIC_FOLDER):
        for album in os.listdir(os.path.join(MUSIC_FOLDER, artist)):
            get_album_cover_and_delete_old_one(os.path.join(MUSIC_FOLDER, artist, album), artist, album)
Clone this wiki locally