Created
January 23, 2024 06:21
-
-
Save nielsrolf/2b412ca6c3b21e86458fb466c5c89df1 to your computer and use it in GitHub Desktop.
Music metadata extractor for yt-dlp and offline music apps
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
import os | |
import shutil | |
from mutagen.mp3 import MP3 | |
from mutagen.id3 import ID3, TIT2, TPE1, TALB | |
import click | |
def update(file, directory, target_directory): | |
if file.endswith('.mp3'): # Check if the file is an MP3 | |
path = os.path.join(directory, file) | |
audio = MP3(path, ID3=ID3) | |
# Ensure that ID3 tag exists | |
try: | |
audio.add_tags() | |
except: | |
pass | |
name = file.split(" [")[0] | |
artists = [] | |
album = "" | |
if " - " in name: | |
artists, name = name.split(" - ", maxsplit=1) | |
artists = artists.split("&") | |
if "(" in name: | |
_, edited_by = name.split("(") | |
edited_by = edited_by.split(")")[0].replace('Edit', '').replace('Remix', '').split("&") | |
artists += edited_by | |
for i, artist in enumerate(artists): | |
if " @ " in artist: | |
artists[i], album = artist.split(" @ ") | |
artists = [i.strip() for i in artists] | |
name = name.strip() | |
album = album.strip() | |
# Set the tags | |
audio['TIT2'] = TIT2(encoding=3, text=name) | |
audio['TPE1'] = TPE1(encoding=3, text=artists) | |
if album: | |
audio['TALB'] = TALB(encoding=3, text=album) | |
# Save the changes | |
new_file_path = os.path.join(target_directory, f"{name}.mp3") | |
if os.path.exists(new_file_path): | |
return | |
shutil.copy(path, new_file_path) | |
audio.save(new_file_path) | |
print(f"Updated tags for {file}") | |
@click.command() | |
@click.argument("src", type=str) | |
@click.argument("output", type=str) | |
def main(src, output): | |
os.makedirs(output, exist_ok=True) | |
files = os.listdir(src) | |
sorted_files = sorted(files, key=lambda x: os.path.getctime(os.path.join(src, x))) | |
for file in sorted_files: | |
print(file) | |
try: | |
update(file, src, output) | |
except Exception as e: | |
print(e) | |
shutil.copy(os.path.join(src, file), os.path.join(output, file)) | |
pass | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment