Metadata-Version: 2.4
Name: SpotiFLAC
Version: 0.5.6
Summary: Get Spotify tracks in true FLAC from Tidal, Qobuz & Amazon Music — no account required.
Author: ShuKurenais, BartolomeoRusso9
License: MIT
Project-URL: Homepage, https://github.com/ShuShuzinhuu/SpotiFLAC-Module-Version
Project-URL: Repository, https://github.com/ShuShuzinhuu/SpotiFLAC-Module-Version
Project-URL: Bug Tracker, https://github.com/ShuShuzinhuu/SpotiFLAC-Module-Version/issues
Keywords: spotify,flac,downloader,music,lossless,lossless-music,tidal,qobuz,amazon-music,audio,SpotiFLAC,spotify-downloader,no-account,hi-res
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: End Users/Desktop
Classifier: Intended Audience :: Developers
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.32.3
Requires-Dist: mutagen>=1.47.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: pycryptodome>=3.20.0
Requires-Dist: packaging>=23.0
Requires-Dist: yt-dlp>=2024.04.09
Dynamic: license-file

# SpotiFLAC Python Module

[![PyPI - Version](https://img.shields.io/pypi/v/spotiflac?style=for-the-badge&logo=pypi&logoColor=ffffff&labelColor=000000&color=7b97ed)](https://pypi.org/project/SpotiFLAC/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/spotiflac?style=for-the-badge&logo=python&logoColor=ffffff&labelColor=000000&color=7b97ed)](https://pypi.org/project/SpotiFLAC/) [![Pepy Total Downloads](https://img.shields.io/pepy/dt/spotiflac?style=for-the-badge&logo=pypi&logoColor=ffffff&labelColor=000000)](https://pypi.org/project/SpotiFLAC/)


Integrate **SpotiFLAC** directly into your Python projects. Perfect for building custom Telegram bots, automation tools, bulk downloaders, downloading music for Jellyfin or web interfaces.

> **Looking for a standalone app?**
### [SpotiFLAC (Desktop)](https://github.com/afkarxyz/SpotiFLAC)

Download music in true lossless FLAC from Tidal, Qobuz & Amazon Music for Windows, macOS & Linux

### [SpotiFLAC (Mobile)](https://github.com/zarzet/SpotiFLAC-Mobile)

SpotiFLAC for Android & iOS — maintained by [@zarzet](https://github.com/zarzet)

---

## Installation

```bash
pip install SpotiFLAC
```

---

## Quick Start

The easiest way to use SpotiFLAC is through the built-in Interactive Wizard. Just run the command without any arguments:
```bash
SpotiFLAC
```
> (Or python launcher.py if running from source)

---
## Interactive Mode

SpotiFLAC features a smart Interactive Wizard that guides you step-by-step. On launch it automatically runs a **service health check** before asking any questions, so you always know which providers are reachable.

**What the wizard does at startup:**

1. **Service Health Check** — probes all provider endpoints and shows availability inline (✅ / ❌) before asking anything
2. **URL History** — shows your last 8 downloads so you can re-run one with a single keypress
3. **Folder Memory** — remembers your last output directory and offers it as the default
4. **Profile Load** — optionally restores a full saved configuration

**Smart URL Detection:** If you input an Artist URL, it will ask if you want to download "Featuring" tracks. It skips this question for albums or playlists.

**Smart File Paths:** If you input a Single Track URL, it will ask if you want to set a specific `.flac` output path. If you do, it intelligently skips all questions about filename formatting and subfolder organization.

**Unified Quality Profiles:** Automatically translates your desired quality tier across different services (like Tidal and Qobuz).

**CLI Generator:** At the end of the configuration, it generates and prints the exact CLI command for your specific setup, so you can copy and reuse it in your automated scripts.

**Profile Save:** After confirming the download, you can save the entire configuration as a named profile to reuse later.

---

```python
from SpotiFLAC import SpotiFLAC

# Simple Download
SpotiFLAC(
    url="https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
    output_dir="./downloads"
)
```

CLI usage:
```bash
spotiflac url ./out --service tidal
```

---

### Supported URL Types

SpotiFLAC supports the following URL formats for **Spotify**, **Tidal**, **Apple Music**, **SoundCloud**, **YouTube** and **Pandora**:

| Type                         | Spotify                         | Tidal                                            | Apple Music                                       | SoundCloud                              | YouTube / YT Music                              | Pandora                                        |
|------------------------------|---------------------------------|--------------------------------------------------|---------------------------------------------------|-----------------------------------------|-------------------------------------------------|------------------------------------------------|
| Track                        | `open.spotify.com/track/...`    | `listen.tidal.com/track/...`                     | `music.apple.com/.../song/...`                    | `soundcloud.com/artist/track-slug`      | `youtube.com/watch?v=...` · `youtu.be/...`      | `pandora.com/artist/.../song/TR:...` · `pandora.app.link/...` |
| Album / Set                  | `open.spotify.com/album/...`    | `listen.tidal.com/album/...`                     | `music.apple.com/.../album/...`                   | `soundcloud.com/artist/sets/set-slug`   | `music.youtube.com/playlist?list=OLAK5uy_...`   | —                                              |
| Playlist                     | `open.spotify.com/playlist/...` | `listen.tidal.com/playlist/...`                  | `music.apple.com/.../playlist/...`                | —                                       | `youtube.com/playlist?list=PL...`               | —                                              |
| Discography (via artist URL) | `open.spotify.com/artist/...`   | `listen.tidal.com/artist/.../discography/albums` | `music.apple.com/.../artist/...`                  | —                                       | —                                               | —                                              |

> **Note:** SoundCloud and YouTube tracks are downloaded as **MP3** (neither platform distributes lossless audio). Apple Music downloads as **M4A/ALAC** (lossless) or **AAC** depending on the selected quality. Pandora downloads as **MP3** (mp3_192 by default) or **M4A** (aac_64 / aac_32). All other services deliver **FLAC**.
>
> SoundCloud short links (`on.soundcloud.com/...`) and mobile links (`m.soundcloud.com/...`) are automatically resolved. Tracking parameters (e.g. `?utm_source=...`) are stripped before processing.
>
> Apple Music track links with an `?i=` song parameter (e.g. `music.apple.com/us/album/album-name/id?i=trackid`) are also supported.
>
> Pandora app links (`pandora.app.link/...`) are automatically resolved to their canonical web URL. Pandora pretty URLs (e.g. `pandora.com/artist/artist-name/album-name/song-name/TR:...`) are fully supported.

---

## Advanced Configuration

You can customize the download behavior, prioritize specific streaming services, and organize your files automatically into folders.

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://open.spotify.com/album/41MnTivkwTO3UUJ8DrqEJJ",
    output_dir="./MusicLibrary",
    services=["qobuz", "amazon", "tidal", "spoti"],
    filename_format="{year} - {album}/{track}. {title}",
    use_artist_subfolders=True,
    use_album_subfolders=True,
    loop=60,                     # retry duration in minutes
    track_max_retries=2,         # extra per-track retries on failure
    post_download_action="notify"
)
```

---

## Service Health Check

SpotiFLAC can probe all provider endpoints before downloading to verify which ones are currently reachable.

In **Interactive Mode** this runs automatically at startup. In code or scripts you can call it directly:

```python
from SpotiFLAC.core.health_check import (
    run_health_check,
    print_health_report,
    get_working_providers,
)

results = run_health_check(["tidal", "qobuz", "deezer", "soundcloud", "pandora"])
print_health_report(results)

working = get_working_providers(results)
print("Available providers:", working)
```

```bash
# CLI: check all services then download
spotiflac https://open.spotify.com/track/... ./out --service tidal qobuz
```

The health check runs **in parallel** with a configurable timeout (default: 5 s per endpoint) and never blocks your download if a check fails.

---

## Configuration Profiles

Save and reuse complete download configurations without re-typing them every time.

### Save a profile

```bash
# Save current flags as "hires-tidal"
spotiflac https://... ./out \
  --service tidal \
  --quality HI_RES_LOSSLESS \
  --use-album-subfolders \
  --filename-format "{year} - {album}/{track}. {title}" \
  --save-profile hires-tidal
```

### Load a profile

```bash
# Load "hires-tidal" — flags override profile values when both are present
spotiflac https://... ./out --profile hires-tidal
```

### In Python

```python
from SpotiFLAC.core.profiles import save_profile, get_profile, list_profiles

# Save
save_profile("hires-tidal", {
    "services":             ["tidal"],
    "quality":              "HI_RES_LOSSLESS",
    "use_album_subfolders": True,
    "filename_format":      "{year} - {album}/{track}. {title}",
})

# Load and use
cfg = get_profile("hires-tidal")
print(list_profiles())  # ['hires-tidal']
```

Profiles are stored at `~/.cache/spotiflac/profiles.json`. In the Interactive Wizard, you are prompted to load a profile at startup and optionally save one at the end.

---

## Batch Downloads

Pass a list of URLs to download them all in sequence. Failed tracks per URL are collected and can be retried with `loop`.

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url=[
        "https://open.spotify.com/album/41MnTivkwTO3UUJ8DrqEJJ",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
        "https://listen.tidal.com/album/364272512",
    ],
    output_dir="./MusicLibrary",
    services=["tidal", "qobuz"],
    use_album_subfolders=True,
)
```

---

## Auto-Retry on Failure

Set `track_max_retries` (Python) or `--retries` (CLI) to automatically retry failed tracks.
Each retry cycles through **all configured providers** from the beginning, waiting exponentially longer between attempts (2 s → 4 s → 8 s …, capped at 30 s).

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://open.spotify.com/album/...",
    output_dir="./downloads",
    services=["tidal", "qobuz", "deezer"],
    track_max_retries=3,   # up to 3 extra attempts per track
)
```

```bash
spotiflac https://open.spotify.com/album/... ./out \
  --service tidal qobuz deezer \
  --retries 3
```

> **Tip:** Combine `--retries` with `--loop` for maximum resilience — `--retries` handles transient errors on individual tracks, while `--loop` re-queues permanently failed tracks after N minutes.

---

## Post-Download Actions

| Action        | Description                                                                       |
|---------------|-----------------------------------------------------------------------------------|
| `none`        | Do nothing (default)                                                              |
| `open_folder` | Open the output folder in the system file manager                                 |
| `notify`      | Send an OS desktop notification with a summary                                    |
| `command`     | Run a custom shell command — placeholders: `{folder}`, `{succeeded}`, `{failed}` |

```python
SpotiFLAC(url="...", output_dir="./downloads", post_download_action="open_folder")

SpotiFLAC(url="...", output_dir="./downloads",
          post_download_action="command",
          post_download_command="rsync -av {folder}/ user@nas:/music/")
```

```bash
spotiflac https://... ./out --post-action notify
spotiflac https://... ./out --post-action command --post-command "rsync -av {folder}/ user@nas:/music/"
```

---

## Discography Download

Download the complete discography of an artist. Duplicate tracks (same ISRC across different releases) are automatically skipped.

```python
from SpotiFLAC import SpotiFLAC

# Spotify — albums + singles
SpotiFLAC(url="https://open.spotify.com/artist/1Xyo4u8uXC1ZmMpatF05PJ", output_dir="./MusicLibrary",
          services=["qobuz", "tidal"], use_album_subfolders=True, filename_format="{year} - {album}/{track}. {title}")

# Tidal — full discography (append /discography/albums or /discography/singles to filter)
SpotiFLAC(url="https://listen.tidal.com/artist/7804", output_dir="./MusicLibrary",
          services=["tidal"], use_album_subfolders=True, filename_format="{year} - {album}/{track}. {title}")
```

```bash
spotiflac https://open.spotify.com/artist/... ./MusicLibrary \
  --service tidal --include-featuring \
  --use-album-subfolders --filename-format "{year} - {album}/{track}. {title}"
```

> Recommended layout: `--use-album-subfolders` + `--filename-format "{year} - {album}/{track}. {title}"`.

---

## SoundCloud Download

SoundCloud tracks are typically downloaded as MP3 128kbps, though the provider attempts to fetch the highest quality transcoding available (including Opus or Ogg if supported).

```python
from SpotiFLAC import SpotiFLAC

# Single track
SpotiFLAC(url="https://soundcloud.com/artist/track-slug", output_dir="./downloads", services=["soundcloud"])

# Playlist / set
SpotiFLAC(url="https://soundcloud.com/artist/sets/set-slug", output_dir="./downloads", services=["soundcloud"], use_album_subfolders=True)

# Artist page (all public tracks)
SpotiFLAC(url="https://soundcloud.com/artist", output_dir="./downloads", services=["soundcloud"], use_artist_subfolders=True)
```

---

## Deezer Download

SpotiFLAC can use Deezer as a **download service** when sourcing tracks identified by other input platforms (Spotify, Tidal, etc.). Deezer is resolved by ISRC, with an automatic text-search fallback. The output format is **FLAC**.

> **Note:** Deezer URLs cannot be used as input — use a Spotify or Tidal link and set `deezer` as the service.

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
    output_dir="./downloads",
    services=["deezer", "tidal"],   # Deezer first, Tidal as fallback
)
```

---

## Apple Music Download

SpotiFLAC supports Apple Music as both an **input URL source** and a **download service**. The output format is **M4A** (ALAC lossless or AAC depending on quality).

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://music.apple.com/us/album/album-name/123456789?i=987654321",
    output_dir="./downloads",
    services=["apple"],
    quality="alac",
)
```

> **Apple Music quality options:** `alac` (lossless, default), `atmos` (Dolby Atmos Spatial Audio), `ac3` (Dolby Digital), `aac`, `aac-legacy`.

---

## YouTube Download

SpotiFLAC can download tracks, playlists and albums from **YouTube Music** (and standard YouTube). The output format is always **MP3**.

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://music.youtube.com/watch?v=dQw4w9WgXcQ",
    output_dir="./downloads",
    services=["youtube"],
)
```

---

## Pandora Download

SpotiFLAC can download individual tracks from **Pandora** using both web URLs and app links. Output: **MP3** (`mp3_192` default) or **M4A** (`aac_64` / `aac_32`). Album and playlist downloads are not supported.

```python
from SpotiFLAC import SpotiFLAC

# Web URL
SpotiFLAC(url="https://www.pandora.com/artist/name/album/song/TR:12345678",
          output_dir="./downloads", services=["pandora"], quality="mp3_192")

# App link — resolved automatically
SpotiFLAC(url="https://pandora.app.link/abcdef1234", output_dir="./downloads", services=["pandora"])

# With fallback to Tidal
SpotiFLAC(url="https://www.pandora.com/artist/.../TR:12345678",
          output_dir="./downloads", services=["pandora", "tidal"])
```

```bash
spotiflac https://www.pandora.com/artist/.../TR:12345678 ./downloads --service pandora --quality aac_64
```

> **Quality options:** `mp3_192` (High, default), `aac_64` (Medium), `aac_32` (Low).

---

## Custom Output Path (single tracks)

For single track downloads you can specify the **exact file path** instead of relying on `output_dir` + `filename_format`.

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
    output_dir="./downloads",
    output_path="files/song.flac"
)
```

> **Note:** `output_path` is automatically ignored when the URL points to an **album**, **playlist**, or **artist/discography**.

---

## Qobuz Token (Optional)

Setting a personal Qobuz token improves metadata resolution reliability. The token is used as a **last resort fallback** — requests are first attempted anonymously, and only if they fail (HTTP 400/401) the token is injected. A **free Qobuz account** is sufficient.

### How to Extract Your Token

1. Log in to [play.qobuz.com](https://play.qobuz.com)
2. Open DevTools with **F12** → go to the **Network** tab
3. Play any track or perform any search to trigger API calls
4. Filter requests by typing `api.json` in the search bar
5. Click on any request to `www.qobuz.com/api.json/...`
6. In the **Request Headers** panel, look for: **x-user-auth-token: your_token_here**
7. Copy the value — that is your token

### How to Apply Qobuz Token in SpotiFLAC

**Interactive Wizard:** The wizard prompts you to paste your Qobuz token during configuration.

**Environment Variable:**

```bash
export QOBUZ_AUTH_TOKEN="YOUR_TOKEN_HERE"
```

**Python:**
```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="URL",
    output_dir="./downloads",
    qobuz_token="YOUR_QOBUZ_TOKEN",
)
```

**config.json:**
```json
{
    "qobuz_token": "YOUR_QOBUZ_TOKEN"
}
```

---

## Custom Tidal API Instance

SpotiFLAC connects to a shared pool of public hifi-api mirrors to fetch Tidal streams.
If you want guaranteed availability and full control, you can self-host your own instance
and point SpotiFLAC to it — it will always be tried first, before any public mirror.

> **How to deploy your own instance:** [github.com/binimum/hifi-api](https://github.com/binimum/hifi-api)

### Python

```python
from SpotiFLAC import SpotiFLAC

SpotiFLAC(
    url="https://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT",
    output_dir="./downloads",
    services=["tidal"],
    tidal_custom_api="https://your-instance.example.com",
)
```

### CLI

```bash
spotiflac https://open.spotify.com/track/... ./downloads \
  --service tidal \
  --tidal-api "https://your-instance.example.com"
```

### Interactive Wizard

The wizard prompts for a custom Tidal API URL at step **12.5**, right after the optional tokens section.

### config.json

```json
{
    "tidal_custom_api": "https://your-instance.example.com"
}
```

> **Note:** The custom instance is also saved and restored when using `--save-profile` / `--profile`.

---

<h2>CLI program usage</h2>
<p>Program can be downloaded for <b>Windows</b>, <b>Linux (x86 and ARM)</b> and <b>MacOS</b>. The downloads are available under the releases.<br>
Program can also be ran by downloading the python files and calling <code>python launcher.py</code> with the arguments.</p>

<h4>Windows example usage:</h4>

```bash
./SpotiFLAC-Windows.exe url
                        output_dir
                        [--service tidal qobuz deezer amazon spoti soundcloud youtube apple pandora]
                        [--filename-format "{title} - {artist}"]
                        [--output-path "files/song.flac"]
                        [--quality LOSSLESS]
                        [--use-track-numbers]
                        [--use-album-track-numbers]
                        [--use-artist-subfolders]
                        [--use-album-subfolders]
                        [--first-artist-only]
                        [--qobuz-token TOKEN]
                        [--tidal-api URL]
                        [--loop minutes]
                        [--verbose]
                        [--no-lyrics]
                        [--lyrics-providers spotify apple musixmatch amazon lrclib]
                        [--no-enrich]
                        [--enrich-providers deezer apple qobuz tidal soundcloud]
                        [--retries N]
                        [--post-action none|open_folder|notify|command]
                        [--post-command "CMD with {folder} {succeeded} {failed}"]
                        [--profile NAME]
                        [--save-profile NAME]
```

<h4>Linux / Mac example usage:</h4>

```bash
chmod +x SpotiFLAC-Linux-arm64
./SpotiFLAC-Linux-arm64 url
                        output_dir
                        [--service tidal qobuz deezer amazon spoti soundcloud youtube apple pandora]
                        [--filename-format "{title} - {artist}"]
                        [--output-path "files/song.flac"]
                        [--quality LOSSLESS]
                        [--use-track-numbers]
                        [--use-album-track-numbers]
                        [--use-artist-subfolders]
                        [--use-album-subfolders]
                        [--first-artist-only]
                        [--qobuz-token TOKEN]
                        [--tidal-api URL]
                        [--loop minutes]
                        [--verbose]
                        [--no-lyrics]
                        [--lyrics-providers spotify apple musixmatch amazon lrclib]
                        [--no-enrich]
                        [--enrich-providers deezer apple qobuz tidal soundcloud]
                        [--retries N]
                        [--post-action none|open_folder|notify|command]
                        [--post-command "CMD with {folder} {succeeded} {failed}"]
                        [--profile NAME]
                        [--save-profile NAME]
```

*(For ARM devices like Raspberry Pi, replace `x86_64` with `arm64`)*

---

## API Reference

### `SpotiFLAC()` Parameters

| Parameter                      | Type    | Default                                                   | Description                                                                                                                                                                                                                                                                  |
|--------------------------------|---------|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`url`**                      | `str` / `list[str]` | *Required*                                   | A single URL or a **list of URLs** (batch mode) for Spotify, Tidal, Apple Music, SoundCloud, YouTube or Pandora.                                                                                                                                                             |
| **`output_dir`**               | `str`   | *Required*                                                | The destination directory path where the audio files will be saved.                                                                                                                                                                                                          |
| **`output_path`**              | `str`   | `None`                                                    | Exact destination file path for **single track** downloads. Overrides `output_dir` + `filename_format`. Automatically ignored for albums, playlists and artist discographies.                                                                                                |
| **`services`**                 | `list`  | `["tidal"]`                                               | Specifies which services to use and their priority order. Choices: `tidal`, `qobuz`, `deezer`, `amazon`, `spoti`, `soundcloud`, `youtube`, `apple`, `pandora`.                                                                                                               |
| **`filename_format`**          | `str`   | `"{title} - {artist}"`                                    | Format for naming downloaded files. See placeholders below.                                                                                                                                                                                                                  |
| **`use_track_numbers`**        | `bool`  | `False`                                                   | Prefixes the filename with the track number.                                                                                                                                                                                                                                 |
| **`use_album_track_numbers`**  | `bool`  | `False`                                                   | Uses the track's original album number instead of the download queue position.                                                                                                                                                                                               |
| **`use_artist_subfolders`**    | `bool`  | `False`                                                   | Automatically organizes downloaded files into subfolders by artist.                                                                                                                                                                                                          |
| **`use_album_subfolders`**     | `bool`  | `False`                                                   | Automatically organizes downloaded files into subfolders by album.                                                                                                                                                                                                           |
| **`first_artist_only`**        | `bool`  | `False`                                                   | Uses only the first artist in tags and filename.                                                                                                                                                                                                                             |
| **`include_featuring`**        | `bool`  | `False`                                                   | When downloading an artist discography, also includes tracks where the artist appears as a featured artist.                                                                                                                                                                  |
| **`tidal_custom_api`**         | `str`   | `None`                                                    | URL of a self-hosted [hifi-api](https://github.com/binimum/hifi-api) instance. Takes priority over all public mirrors.                                                                                                                                                       |
| **`loop`**                     | `int`   | `None`                                                    | Duration in minutes to keep retrying **permanently failed** tracks after a full session completes.                                                                                                                                                                           |
| **`track_max_retries`**        | `int`   | `0`                                                       | Extra download attempts **per track** when all providers fail on the first try. Each retry cycles through all providers again with exponential backoff (2 s → 4 s → 8 s …, capped at 30 s).                                                                                  |
| **`quality`**                  | `str`   | `"LOSSLESS"`                                              | Download quality. Tidal: `"DOLBY_ATMOS"`, `"HI_RES_LOSSLESS"`, `"LOSSLESS"`, `"HIGH"`, `"LOW"`. Qobuz: `"6"` (CD), `"7"` (Hi-Res), `"27"` (Hi-Res Max). Apple Music: `"alac"`, `"atmos"`, `"ac3"`, `"aac"`, `"aac-legacy"`. Pandora: `"mp3_192"`, `"aac_64"`, `"aac_32"`.    |
| **`allow_fallback`**           | `bool`  | `True`                                                    | Automatically falls back to the next available quality tier if the requested quality is unavailable.                                                                                                                                                                         |
| **`log_level`**                | `int`   | `logging.WARNING`                                         | Python logging level.                                                                                                                                                                                                                                                        |
| **`embed_lyrics`**             | `bool`  | `True`                                                    | Whether to fetch and embed synchronized lyrics (LRC) into the audio file.                                                                                                                                                                                                    |
| **`lyrics_providers`**         | `list`  | `["spotify", "apple", "musixmatch", "lrclib", "amazon"]`  | Priority order of lyrics providers to attempt.                                                                                                                                                                                                                               |
| **`enrich_metadata`**          | `bool`  | `True`                                                    | Enables multi-provider metadata enrichment (HD covers, BPM, Labels, etc.).                                                                                                                                                                                                   |
| **`enrich_providers`**         | `list`  | `["deezer", "apple", "qobuz", "tidal", "soundcloud"]`     | Priority order of metadata providers to attempt.                                                                                                                                                                                                                             |
| **`qobuz_token`**              | `str`   | `None`                                                    | Optional Qobuz user auth token used as fallback for metadata resolution. Fallback: env `QOBUZ_AUTH_TOKEN`.                                                                                                                                                                   |
| **`post_download_action`**     | `str`   | `"none"`                                                  | Action after all downloads finish: `"none"`, `"open_folder"`, `"notify"`, `"command"`.                                                                                                                                                                                       |
| **`post_download_command`**    | `str`   | `""`                                                      | Shell command to run when `post_download_action="command"`. Supports `{folder}`, `{succeeded}`, `{failed}` placeholders.                                                                                                                                                     |

### Filename Format Placeholders

When customizing the `filename_format` string, you can use the following dynamic tags:

* `{title}` — Track title
* `{artist}` — Track artist(s)
* `{album}` — Album name
* `{album_artist}` — The artist(s) of the entire album
* `{disc}` — The disc number
* `{track}` — The track's original number in the album
* `{position}` — Download queue / Playlist position (zero-padded, e.g. `01`)
* `{date}` — Full release date (e.g., YYYY-MM-DD)
* `{year}` — Release year (e.g., YYYY)
* `{isrc}` — Track ISRC code

---

## CLI Flag Reference

| Flag                        | Short | Default                                       | Description                                                                                                                                                                                                 |
|-----------------------------|-------|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--service`                 | `-s`  | `tidal`                                       | One or more providers in priority order. Choices: `tidal`, `qobuz`, `deezer`, `amazon`, `spoti`, `soundcloud`, `youtube`, `apple`, `pandora`.                                                               |
| `--filename-format`         | `-f`  | `{title} - {artist}`                          | Filename template with placeholders.                                                                                                                                                                        |
| `--output-path`             | `-o`  | `None`                                        | Exact output file path for single track downloads. Ignored for albums, playlists and discographies.                                                                                                         |
| `--quality`                 | `-q`  | `LOSSLESS`                                    | Audio quality. Tidal: `DOLBY_ATMOS`, `HI_RES_LOSSLESS`, `LOSSLESS`, `HIGH`, `LOW`. Qobuz: `6`, `7`, `27`. Apple Music: `alac`, `atmos`, `ac3`, `aac`, `aac-legacy`. Pandora: `mp3_192`, `aac_64`, `aac_32`. |
| `--use-track-numbers`       |       | `False`                                       | Prefix filenames with track numbers.                                                                                                                                                                        |
| `--use-album-track-numbers` |       | `False`                                       | Use the track's original album number instead of queue position.                                                                                                                                            |
| `--use-artist-subfolders`   |       | `False`                                       | Organize files into per-artist subfolders.                                                                                                                                                                  |
| `--use-album-subfolders`    |       | `False`                                       | Organize files into per-album subfolders.                                                                                                                                                                   |
| `--first-artist-only`       |       | `False`                                       | Use only the first artist in tags and filename.                                                                                                                                                             |
| `--include-featuring`       |       | `False`                                       | Include tracks where the artist appears as a featured artist. Only applies to artist/discography URLs.                                                                                                      |
| `--qobuz-token`             |       | `None`                                        | Qobuz user auth token (`x-user-auth-token`).                                                                                                                                                                |
| `--tidal-api`               |       | `None`                                        | URL of a self-hosted [hifi-api](https://github.com/binimum/hifi-api) instance. Takes priority over the built-in public mirror pool.                                                                         |
| `--loop`                    | `-l`  | `None`                                        | Keep retrying permanently failed tracks every N minutes.                                                                                                                                                    |
| `--retries`                 |       | `0`                                           | Extra per-track download attempts on failure. Cycles through all providers with exponential backoff.                                                                                                        |
| `--verbose`                 | `-v`  | `False`                                       | Enable debug logging.                                                                                                                                                                                       |
| `--no-lyrics`               |       | `False`                                       | Disable lyrics embedding (lyrics are embedded **by default**).                                                                                                                                              |
| `--lyrics-providers`        |       | `spotify apple musixmatch lrclib amazon`      | Lyrics provider priority order.                                                                                                                                                                             |
| `--no-enrich`               |       | `False`                                       | Disable multi-provider metadata enrichment (enrichment is **enabled by default**).                                                                                                                          |
| `--enrich-providers`        |       | `deezer apple qobuz tidal soundcloud`         | Metadata enrichment provider priority order.                                                                                                                                                                |
| `--post-action`             |       | `none`                                        | Action after all downloads finish: `none`, `open_folder`, `notify`, `command`.                                                                                                                              |
| `--post-command`            |       | `""`                                          | Shell command for `--post-action=command`. Placeholders: `{folder}`, `{succeeded}`, `{failed}`.                                                                                                             |
| `--profile`                 |       | `None`                                        | Load a saved profile. CLI flags override profile values.                                                                                                                                                    |
| `--save-profile`            |       | `None`                                        | Save current CLI configuration as a named profile after the run.                                                                                                                                            |

---

## MusicBrainz Enrichment

SpotiFLAC automatically queries **MusicBrainz** in the background (when an ISRC is available) while the audio is being downloaded, adding professional-grade tags at no extra time cost. Fields written when found:

| Tag                             | Description                               |
|---------------------------------|-------------------------------------------|
| `GENRE`                         | Genre(s), sorted by popularity (up to 5)  |
| `BPM`                           | Beats per minute                          |
| `LABEL` / `ORGANIZATION`        | Record label name                         |
| `CATALOGNUMBER`                 | Catalog number                            |
| `BARCODE`                       | Release barcode / UPC                     |
| `ORIGINALDATE` / `ORIGINALYEAR` | First-ever release date                   |
| `RELEASECOUNTRY`                | Country of release                        |
| `RELEASESTATUS`                 | Release status (e.g. `Official`)          |
| `RELEASETYPE`                   | Release type (e.g. `Album`, `Single`)     |
| `MEDIA`                         | Media format (e.g. `CD`, `Digital Media`) |
| `SCRIPT`                        | Script of the release text                |
| `ARTISTSORT`                    | Artist sort name for file managers        |
| `MUSICBRAINZ_TRACKID`           | MusicBrainz recording ID                  |
| `MUSICBRAINZ_ALBUMID`           | MusicBrainz release ID                    |
| `MUSICBRAINZ_ARTISTID`          | MusicBrainz artist ID                     |
| `MUSICBRAINZ_RELEASEGROUPID`    | MusicBrainz release group ID              |
| `MUSICBRAINZ_ALBUMARTISTID`     | MusicBrainz album artist ID               |
| `ALBUMARTISTSORT`               | Album artist sort name for file managers  |

---

## Download Validation

After each download, SpotiFLAC validates the file to detect common issues:

- **Preview detection** — if the expected duration is ≥ 60 s but the downloaded file is ≤ 35 s, the file is deleted and the download is retried with the next provider.
- **Duration mismatch** — for tracks longer than 90 s, a deviation greater than 25% (or 15 s minimum) from the expected duration is treated as a corrupt download and the file is removed.

---

### Want to support the project?

_If this software is useful and brings you value,
consider supporting the project by buying me a coffee.
Your support helps keep development going._

[![Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/shukurenais)

## API Credits

[Song.link](https://song.link) · [hifi-api](https://github.com/binimum/hifi-api) · [dabmusic.xyz](https://dabmusic.xyz) · [afkarxyz](https://github.com/afkarxyz) · [MusicBrainz](https://musicbrainz.org) · [SoundCloud](https://soundcloud.com) · [Apple Music](https://music.apple.com) · [YouTube Music](https://music.youtube.com) · [Pandora](https://www.pandora.com)

> [!TIP]
>
> **Star Us**, You will receive all release notifications from GitHub without any delay
