A suite of standalone Python scripts that tag .ogg music libraries with rich metadata — Spotify info, lyrics, genre, and BPM/mood — written straight into the file's Vorbis comment tags. Each script is its own mini-tool with its own conda environment, so you only set up (and run) the ones you actually need.
- This is best used with Spytify with
.wavdownload and then converting that to.oggformat for the best Spotify quality feel.- This is the Manual Edition — each tagger is run by hand, one at a time. An automated/pipeline version that chains all of them together is in here.
- 🟢 Spotify Tagger — Looks up each track on Spotify and writes title, artist, album, release year, and embedded album art (640×640 JPEG). Tracks Spotify's ~700 requests/day soft limit in a local JSON file and warns (but doesn't stop) if you go over.
- 🌐📝 Lyrics Tagger (Online) — Pulls plain lyrics from LRCLib, NetEase, and Musixmatch (in that order) and writes them to the
LYRICStag, stripped of timestamps and metadata lines. 🅾️ 📝 Lyrics Tagger (Offline) — Transcribes lyrics straight from the audio using a local pipeline (Demucs vocal separation → DeepFilterNet3 denoising → Faster-Whisper large-v3). No internet needed, but it does need a decent Nvidia GPU.- 🌐♪ Genre Tagger (Online) — Queries Last.fm, iTunes, and MusicBrainz, merges and scores their tags, and writes up to 3 genres per track. Caches artist-level lookups so repeat artists don't cost extra API calls.
🅾️ ♪ Genre Tagger (Offline) — Uses MusicNN (TensorFlow) to sniff out up to 3 genres per track without any internet connection.- 🎧 BPM + Mood Tagger — Cross-validates BPM using both aubio and librosa, then assigns one of 23 mood prototypes based on tempo, loudness, and spectral features normalized against your whole library.
- Python 3.10 or 3.11 (a separate version is used per module — see below)
- Miniconda or Anaconda — every module runs in its own isolated conda environment -> ensure "Add Anaconda to my PATH environment variable" is checked ✓
- System-wide ffmpeg on PATH (required by the offline Lyrics and Genre taggers) -> click here to know how to do that
- An NVIDIA GPU + driver (optional, but strongly recommended for the offline Lyrics and Genre taggers — both fall back to CPU automatically if no GPU is found)
- A free Spotify Developer client ID/secret (for the Spotify Tagger only)
- A free last.fm api key (for the Online Genre Tagger only)
No dependencies need to be installed by hand — setup_venvs.bat handles all of that per module.
Double-click setup_venvs.bat. It checks for conda, ffmpeg, and a GPU, then builds one conda environment per module inside venvs/ (skipping any module whose script isn't present in scripts/, and skipping environments that are already set up). This step can take a while — the offline modules pull in TensorFlow or PyTorch with CUDA support.
Each module is launched from its own environment:
conda run -p "venvs\spotify_tagger" python "scripts\spotify_tagger.py"
or activate the environment first:
conda activate "venvs\spotify_tagger"
python "scripts\spotify_tagger.py"
On first run, each script asks for:
- An input folder of
.oggfiles (read-only — your originals are never touched) - An output folder for the finished, tagged copies (defaults to
outputs/) - Spotify credentials, if running the Spotify Tagger
- last.fm credentials, if running the Online Genre Tagger
These choices are remembered in configs/ for next time — just press Enter to reuse them.
Every file is copied to temp/, tagged there, then moved to outputs/. Progress is saved after every single file to a checkpoint JSON in logs/, so you can safely stop and resume — already-tagged files are always skipped on the next run.
Each script has a small CONFIG block near the top for tweaking behavior, for example:
# online_genre_tagger.py / local_genre_tagger.py
TOP_N_GENRES = 3 # max genre tags written per track# spotify_tagger.py
DAILY_CALL_LIMIT = 700 # soft warning limit, not a hard stopInput/output folders and credentials are set interactively on first run and saved to configs/<script_name>.json — delete that file to be prompted again.
| Issue | Solution |
|---|---|
setup_venvs.bat says conda not found |
Install Miniconda, then open a new terminal so PATH refreshes |
| Offline Lyrics/Genre tagger fails at runtime | Make sure system-wide ffmpeg is on PATH — these two modules use the system copy, not a conda-installed one |
| No GPU detected | The offline modules still work on CPU, just slower — check your NVIDIA driver is current if you expected GPU support |
| Spotify Tagger shows a rate-limit warning | You've passed the ~700 calls/day soft budget — it's safe to keep going, but you may start seeing 429 errors; re-running later in the day resumes from your checkpoint |
| A file keeps showing up as "missed" | It has no match on the given source (Spotify/lyrics/genre) — it's still copied to outputs/, just without that tag |
| Want to re-tag everything from scratch | Delete the relevant checkpoint JSON in logs/ |
- Every module treats your input folder as read-only — files are copied to
temp/before anything is written, and only the finished copy lands inoutputs/. - Filenames for the Spotify Tagger must follow
Artist - Title.ogg; anything without a" - "separator is logged and skipped. - All modules log everything (DEBUG level) to their own file under
logs/, even when the console only shows a summary. - For further technical info click here
Spotify's catalog isn't stable — labels pull tracks, artists get delisted, whole albums vanish from your library overnight with zero warning. Songs I loved for years have quietly disappeared more than once. So I record what I care about with Spytify — but a .wav or .mp3 straight off that pipeline is basically a blank slate: no lyrics, no genre, often no cover art, just a filename. That's a visual downgrade and hurts the point of preserving something if what you're left with is worse than the first experience.
Tagify is the other half of that: it takes those bare files and builds back — and in places exceeds — what Spotify's own app displays. Full album art, accurate metadata, multilingual lyrics, genre tags pulled from multiple sources and cross-checked, even BPM and mood data Spotify never exposed to begin with. The result is a library that's not just "saved," but archived properly — metadata-rich, searchable, and playable in any player, forever, regardless of what Spotify does next.
Made with ♥ by Rane Kun