Skip to content

Instantly share code, notes, and snippets.

@klattimer
Created December 19, 2023 11:07
Show Gist options
  • Save klattimer/7b7a342639254f4781cee35f8cac22dd to your computer and use it in GitHub Desktop.
Save klattimer/7b7a342639254f4781cee35f8cac22dd to your computer and use it in GitHub Desktop.
Fix your MP3 id3 metadata using Shazam (songrec)
#!/usr/bin/env python3
#
# Script assumes you have songrec and id3tool installed.
#
# https://github.com/marin-m/SongRec
# https://github.com/zerodivide1/id3tool
#
# Once you've got those installed, just run it from the current path, installing to /usr/local/bin or whatever you like
# It'll find all mp3 files, use songrec to recognise them, and id3tool to fix the tags, optionally you may want to use
# id3ren to rename the files appropriately.
#
import os
import subprocess
import json
import glob
import sys
def execute_cmd(cmd):
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
try:
output = json.loads(result.stdout)
return output
except json.JSONDecodeError:
print("Error: Failed to parse output as JSON")
else:
print("Error: Command execution failed")
def retag(filename, title, album, artist, year, genre, tracknumber):
print("Retagging %s: %s - %s, %s" % (filename, artist, album, title))
cmd = "id3tool -t \"%s\" -a \"%s\" -r \"%s\" -y \"%s\" -g \"%s\" -n \"%s\" \"%s\"" % (title, album, artist, year, genre, tracknumber, filename)
os.system(cmd)
mp3_files = glob.iglob("**/*.[mM][pP]3", recursive=True)
for filename in mp3_files:
filename = os.path.abspath(filename)
if os.path.isdir(filename):
continue
cmd = ["/usr/bin/songrec", "audio-file-to-recognized-song", filename]
output = execute_cmd(cmd)
print("Retrieving data for file: %s" % filename)
if output is None:
print ("ERROR: No output for %s" % filename)
continue
track = output.get("track", {})
artists = track.get("artists", [])
if len(artists) == 0:
print ("Cannot find an artist")
print(track.get("artists"))
continue
try:
title = track["title"]
album = None
for item in track["sections"][0]["metadata"]:
if item["title"] == "Album":
album = item["text"]
break
try:
artist = artists[0]["name"]
except:
artist = track['subtitle']
year = None
for item in track["sections"][0]["metadata"]:
if item["title"] == "Released":
year = item["text"]
break
genre = track["genres"]["primary"]
tracknumber = track["key"]
except Exception as e:
print("Error: Failed to parse output")
print(str(e))
print()
print(json.dumps(output, indent=4, sort_keys=True))
continue
retag(filename,
title=title,
album=album,
artist=artist,
year=year,
genre=genre,
tracknumber=tracknumber)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment