Created
March 21, 2022 03:51
-
-
Save succinct/2d7157f4eb7ed7333166a80213171581 to your computer and use it in GitHub Desktop.
Retrieve cover art from Spotify API by searching for artist and track title
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Spotipy: https://spotipy.readthedocs.io/ | |
import argparse, os, re, requests, shutil, spotipy, sys | |
from spotipy.oauth2 import SpotifyClientCredentials | |
def main(): | |
parser=argparse.ArgumentParser() | |
parser.add_argument('--id', help='[REQUIRED] Your Spotify API app client ID (see https://developer.spotify.com/dashboard)') | |
parser.add_argument('--secret', help='[REQUIRED] Your Spotify API app client secret') | |
parser.add_argument('--track', help='The full label for the track, in the format "<artist> - <title>"') | |
parser.add_argument('--artist', help='The track artist (overrides the --track argument)') | |
parser.add_argument('--title', help='The title of the track (overrides the --track argument)') | |
parser.add_argument('--output', help='The path in which to output the cover image (defaults to the working directory, image name "cover.png")') | |
parser.add_argument('--size', help='The size of the cover art to retrieve: large|medium|small (default: "large")') | |
args=parser.parse_args() | |
client_id = args.id | |
client_secret = args.secret | |
artist = args.artist or False | |
title = args.title or False | |
output = args.output or os.path.dirname(os.path.realpath(sys.argv[0])) + '\\cover.png' | |
size = args.size or 'large' | |
if not client_id or not client_secret: | |
print("You must specify your Spotify API client ID with --id and your client secret with --secret (see https://developer.spotify.com/dashboard)") | |
sys.exit() | |
# Get artist/title from track info, or explicitly | |
if not artist and not title: | |
trackinfo = args.track or False | |
if trackinfo: | |
# do things | |
[artist, title] = trackinfo.split(" - ", 1) | |
else: | |
print("You must specify either --track, or --artist & --title") | |
sys.exit() | |
try: | |
auth_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret) | |
spotify = spotipy.Spotify(auth_manager=auth_manager) | |
q = f"artist:{artist} track:{title}" | |
if not re.search('live', title, re.IGNORECASE): | |
q = f"{q} NOT live" # ignore live releases | |
print(f"[Spotify] Searching for '{q}'...") | |
results = spotify.search(q=q, limit=1, type='track') | |
cover_url = False | |
for i, track in enumerate(results['tracks']['items']): # There will be at most one result per the query options | |
contributing_artists = False | |
for i, contributing_artist in enumerate(track['artists']): | |
if contributing_artists: | |
contributing_artists = f"{contributing_artists}, {contributing_artist['name']}" | |
else: | |
contributing_artists = contributing_artist['name'] | |
print(f"[Spotify] Match found: {contributing_artists} {track['name']}") | |
image_sizes = track['album']['images'] | |
match size: | |
case 'large': | |
cover_image = image_sizes[0] | |
case 'medium': | |
cover_image = image_sizes[1] | |
case 'small': | |
cover_image = image_sizes[2] | |
cover_url = cover_image['url'] | |
if cover_url: | |
# Download image | |
req = requests.get(cover_url, stream = True) | |
if req.status_code == 200: | |
# Set decode_content value to True, otherwise the downloaded image file's size will be zero. | |
req.raw.decode_content = True | |
with open(output, 'wb') as file_output: | |
shutil.copyfileobj(req.raw, file_output) | |
print(f"Cover image saved to {output} ({size})") | |
else: | |
print('Image could not be retrieved!') | |
else: | |
print(f"Unable to find cover art for '{artist} - {title}'") | |
except: # catch *all* exceptions | |
e = sys.exc_info()[0] | |
print(f"Error: {e}") | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment