A highly modular, professional-grade pipeline for archiving Spotify playlists with pristine audio quality, accurate metadata, and precise lyrics.
- Project Overview
- Core Features
- System Architecture & Project Structure
- Prerequisites
- Installation Guide
- Command Line Interface (CLI) Usage
- Configuration Reference
- Contribution Guidelines
- Disclaimer & License
The Spotify Downloader is a sophisticated, command-line driven application designed to flawlessly bridge the gap between streaming playlists and local music archiving. Unlike conventional tools that blindly scrape the web, this software implements a multi-stage pipeline: exact-match recording via system audio interfaces, parallelized high-fidelity downloading from YouTube, and meticulous metadata injection.
By integrating seamlessly with APIs like iTunes for track details and LRCLIB for synchronized lyrics, the output is not just a collection of audio files, but a fully structured, locally hosted music library that rivals streaming platforms in organization and metadata depth.
- Precision Spotify Recording (Linux & Windows): Captures exact track titles and artist names directly from the active local Spotify desktop client — no Spotify account or Web API required. On Linux it reads the MPRIS/D-Bus interface via
playerctl; on Windows it reads the system media session (GSMTC) via thewinrtbindings. Features automated loop detection to gracefully terminate the recording phase. - Parallelized Retrieval Engine: Utilizes Python's
concurrent.futuresto rapidly query YouTube and download audio streams. Automatically resolves rate-limiting and applies fallback mechanisms for maximum reliability. - Multi-Format Lossless & Lossy Extraction: Leverages
yt-dlpandFFmpegto extract audio directly into standard MP3, highly efficient M4A (AAC), or studio-quality FLAC containers. - Industry Standard Audio Normalization: Features optional integration with FFmpeg's
loudnormfilter to normalize audio output to -14 LUFS, precisely matching Spotify's standard volume levels across diverse tracks. - Comprehensive Metadata Injection: Dynamically fetches ID3/FLAC/MP4 tags from the iTunes API. Embeds high-resolution cover art (up to 600x600), album details, release dates, and track numbers directly into the audio containers using
mutagen. - Synchronized Lyrics Support: Interfaces with LRCLIB to retrieve both plain and time-synchronized lyrics, embedding plain lyrics into the audio file and saving synchronized
.lrcfiles side-by-side for compatible music players. - Intelligent Library Deduplication: Features a dedicated deduplication engine that parses existing directories, compares tracks based on cryptographic hashes, embedded metadata, and lyrics presence, systematically eliminating inferior duplicates.
- Rich Terminal User Interface (TUI): Built with
richandquestionaryfor an immersive terminal experience, featuring interactive menus, live progress bars with time estimations, and formatted summary tables.
The project strictly adheres to a modular architecture, ensuring separation of concerns and maintainability.
Spotify_Download/
├── main.py
├── recorder.py
├── youtube.py
├── metadata.py
├── utils.py
├── convert_to_opus.py
├── transliterate_lyrics.py
├── requirements.txt
├── requirements-optional.txt
├── run.bat # Windows double-click launcher
├── build_windows.ps1 # Windows .exe build (PyInstaller)
├── spotify_downloader.spec # PyInstaller spec
├── build_deb.sh # Linux .deb build
├── deb_resources/
│ ├── control
│ └── spotify-downloader.desktop
└── .gitignore
main.py- Purpose: The central orchestrator and primary Command Line Interface entry point.
- Functionality: Handles argument parsing using
argparse, deploys interactive format selection menus viaquestionary, and directs the sequential execution of the recording, searching, downloading, and tagging pipelines. Displays a comprehensive, color-coded summary table upon completion.
recorder.py- Purpose: The local Spotify-client interface module (cross-platform).
- Functionality: Captures the currently playing track + artist straight from the desktop Spotify app — no account or Web API. On Linux it runs
playerctlagainst the MPRIS/D-Bus interface; on Windows it queries the system media session (GSMTC) through thewinrtbindings. A shared, platform-agnostic loop with intelligent loop-detection autonomously stops when the playlist repeats.
youtube.py- Purpose: The search and high-speed retrieval engine.
- Functionality: Harnesses
yt-dlpto query YouTube for optimal official audio streams based on the recorded text files. ImplementsThreadPoolExecutorfor concurrent operations, significantly reducing total processing time. Handles stream extraction, format conversion via FFmpeg post-processing, and optional audio normalization parameters.
metadata.py- Purpose: The tag enrichment and file organization subsystem.
- Functionality: Interfaces with the iTunes Search API to resolve pristine track details and the LRCLIB API for localized lyrics. It utilizes the
mutagenlibrary to safely embed these complex data structures (including binary image data for cover art) directly into the file headers. Additionally, it processes filesystem operations to automatically organize outputs into artist-specific directories.
utils.py- Purpose: A centralized library of shared utility functions and system checks.
- Functionality: Manages the shared
rich.consoleenvironment (and forces UTF-8 output on Windows). Provides cross-platform dependency resolution (check_ffmpeg,get_ffmpeg/get_ffprobe,check_recorder_requirements). Contains the logic for sanitizing filesystem paths (incl. Windows reserved-name handling), generating.m3uplaylists that retain original playback order, and the metadata-aware deduplication function (remove_duplicates).
convert_to_opus.py- Purpose: Standalone / in-process batch Opus converter.
- Functionality: Recursively converts FLAC/MP3/M4A to space-efficient Opus VBR via FFmpeg, validates output with FFprobe, and prunes corrupt files. Runnable from the CLI or called in-process from the wizard.
transliterate_lyrics.py- Purpose: Hindi/Urdu → Hinglish transliteration.
- Functionality: Detects Devanagari / Arabic script and converts it to colloquial Roman "Hinglish", using
indic-transliterationwhen installed and falling back to a built-in character map otherwise.
requirements.txt- Purpose: Environment definition.
- Functionality: Locks down exact Python dependency versions required for stability (e.g.,
yt-dlp,mutagen,rich,questionary).
build_deb.sh&deb_resources/- Purpose: Linux deployment and distribution tooling.
- Functionality: A shell script configured to package the tool into a
.debinstaller for Debian/Ubuntu distributions, utilizing configuration files and standard.desktopentries located indeb_resourcesfor seamless desktop integration.
run.bat,build_windows.ps1&spotify_downloader.spec- Purpose: Windows launch & distribution tooling.
- Functionality:
run.batis a double-click launcher for source installs;build_windows.ps1+spotify_downloader.specbuild a self-contained one-folder.exevia PyInstaller, bundling FFmpeg/FFprobe and the WinRT bindings.
The application relies on external binaries for media processing and system interaction.
- Python 3.8+
- FFmpeg: Strictly required for audio extraction, format conversion, and LUFS normalization.
- Recorder backend (only needed for the
--recordfeature):- Linux:
playerctl - Windows: the
winrtpackages — installed automatically byrequirements.txt(no extra step)
- Linux:
Installation on Debian/Ubuntu:
sudo apt update
sudo apt install python3 python3-pip ffmpeg playerctlInstallation on Fedora/RHEL:
sudo dnf install python3 python3-pip ffmpeg playerctlInstallation on macOS (Homebrew):
brew install python ffmpegInstallation on Windows (winget / PowerShell):
winget install Python.Python.3.12 # if you don't already have Python
winget install Gyan.FFmpeg # puts ffmpeg + ffprobe on PATHNo
playerctlneeded on Windows — recording uses the built-in Windows media session (GSMTC) via thewinrtpackages fromrequirements.txt.
It is highly recommended to isolate the project environment.
pip install -r requirements.txt-
Clone the repository to your local machine:
git clone https://github.com/Waleed-Ahmad-dev/Spotify_Download.git cd Spotify_Download -
Create and activate a virtual environment:
python3 -m venv venv source venv/bin/activate # On Windows use: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
If you are using a Debian-based Linux distribution, you can build and install a .deb package for system-wide access.
-
Navigate to the repository root.
-
Execute the build script:
chmod +x build_deb.sh ./build_deb.sh
-
Install the generated package:
sudo dpkg -i build/spotify-downloader-gui_1.0_all.deb sudo apt-get install -f
Quick start (from source):
winget install Python.Python.3.12 # skip if you already have Python
winget install Gyan.FFmpeg # ffmpeg + ffprobe on PATH
git clone https://github.com/Waleed-Ahmad-dev/Spotify_Download.git
cd Spotify_Download
pip install -r requirements.txt
python main.py # …or just double-click run.batOptional extras (Whisper lyrics, Genius, richer Hinglish):
pip install -r requirements-optional.txtBuild a standalone .exe (so the target machine needs no Python):
powershell -ExecutionPolicy Bypass -File build_windows.ps1The packaged app appears under dist\spotify-downloader\ — distribute that whole
folder. FFmpeg/FFprobe are bundled into it automatically when present on PATH.
The application is operated entirely through main.py. The modular design allows you to run individual stages or the entire pipeline autonomously.
Capture your currently playing Spotify playlist directly from the desktop app (no account/API). Ensure the Spotify client is running and playing the desired playlist, with Shuffle OFF and Repeat ON.
# Linux
python3 main.py --record --input my_playlist.txt
# Windows
python main.py --record --input my_playlist.txtScan YouTube for the most accurate official audio matches based on your recorded text list.
python3 main.py --search --input my_playlist.txt --found urls.txt --notfound missing.txt --workers 5Process the found URLs, extract the audio, embed iTunes metadata, embed lyrics, and organize the files.
python3 main.py --download --format flac --quality 320 --organize --playlist "MyAwesomeMix"Note: If --format is omitted, an interactive terminal menu will appear prompting you to select your preferred audio format.
Execute the entire pipeline seamlessly from recording to final tagging.
python3 main.py --all --format mp3 --normalize --organizeClean up an existing music library by removing lower-quality duplicates. The algorithm keeps the version with the highest file size and embedded lyrics.
python3 main.py --dedupe /path/to/my/music/libraryA complete list of arguments accepted by main.py:
| Argument | Type | Default | Description |
|---|---|---|---|
--record |
Flag | False |
Initializes the Spotify recording module to capture tracks into a file. |
--search |
Flag | False |
Searches YouTube for tracks listed in the input file. |
--download |
Flag | False |
Downloads audio streams from found URLs and applies metadata tagging. |
--all |
Flag | False |
Runs the Record, Search, and Download pipelines sequentially. |
--input |
String | songs.txt |
Target file for reading track lists or saving recorded tracks. |
--found |
String | found.txt |
Output file for storing successfully matched YouTube URLs. |
--notfound |
String | not_found.txt |
Output file for logging tracks that yielded no search results. |
--output-dir |
String | songs |
The target root directory where audio files will be saved. |
--workers |
Integer | 5 |
The number of concurrent threads utilized during the search phase. |
--quality |
String | 192 |
Bitrate for lossy audio formats. Accepted values: 128, 192, 320. |
--format |
String | Prompts | Target audio container. Accepted values: mp3, flac, m4a. |
--organize |
Flag | False |
Automatically moves processed files into subdirectories named by Artist. |
--resume |
Flag | False |
Bypasses the YouTube search phase if the found URL file already exists. |
--normalize |
Flag | False |
Applies FFmpeg -14 LUFS volume normalization to mirror Spotify audio levels. |
--playlist |
String | None |
Generates an .m3u playlist with the specified name preserving record order. |
--dedupe |
String | None |
Path to a directory. Scans and removes duplicate audio files. Overrides all other flags. |
Contributions are highly encouraged to expand functionality, improve efficiency, or resolve issues. To maintain architectural integrity, please adhere to the following workflow:
- Fork the Repository: Create your own parallel workspace.
- Branch Strategically: Create a dedicated branch for your feature or bug fix (
git checkout -b feature/advanced-cachingorgit checkout -b fix/youtube-rate-limit). - Strict Typing & PEP 8: Ensure all Python code includes type hints (
typingmodule) and strictly conforms to PEP 8 style guidelines. - Modular Design: Additions to the core pipeline must be separated into appropriate modules. Avoid monolithic additions to
main.py. - Commit Conventionally: Use standardized commit messages (e.g.,
feat: implemented asynchronous I/O for API calls). - Pull Request Review: Submit a detailed PR explaining the motivation, architectural decisions, and testing validation of your changes.
Important Disclaimer: This software is provided strictly for educational and personal archiving purposes. The developers and contributors do not endorse, encourage, or facilitate digital piracy or copyright infringement. Users are solely responsible for ensuring they possess the legal rights to access and create personal backups of the media they process using this tool.
This project is open-source and distributed under the standard GitHub repository parameters. All third-party APIs (iTunes, LRCLIB, YouTube) are accessed in accordance with standard web request paradigms.
Copyright © 2026 Waleed-Ahmad-dev.