Bulk-upgrade your music library from lossy to lossless via Soulseek
slskd-transform scans your local music library, searches the Soulseek network through slskd for matching FLAC versions of each track, and automatically enqueues them for download. It matches songs by audio duration rather than filenames alone, ensuring you get the correct track every time.
A companion rename command handles post-download organization, renaming all downloaded FLACs into a clean Artist - Title.flac structure using embedded metadata.
- Duration-based matching -- Compares local track duration against search results with a configurable tolerance (default: 15 seconds).
- Recursive scanning -- Point it at your existing music library with
--recursive, no need to flatten files first. - Multi-threaded search -- Distributes searches across multiple threads (default: 5) for faster processing.
- Flexible configuration -- Config file, environment variables, or CLI flags. No code editing required.
- Automatic enqueue -- Matched FLAC files are enqueued for download directly through the slskd API.
- CSV reporting -- Tracks that could not be found are written to
unfound_songs.csv. - Metadata-based renaming -- Reads FLAC tags and renames files to
Artist - Title.flac. - Docker support -- Run alongside slskd in the same compose stack.
- Python 3.10+
- slskd running and accessible
- A valid slskd API key (configured in slskd's settings)
pip install git+https://github.com/GeiserX/slskd-transform.gitOr for development:
git clone https://github.com/GeiserX/slskd-transform.git
cd slskd-transform
pip install -e ".[dev]"# Set your API key (or put it in config.yml)
export SLSKD_API_KEY="your-api-key-here"
# Search for FLAC versions of all files in ./music
slskd-transform search
# Search recursively in your existing library
slskd-transform search --music-dir /path/to/library --recursive
# Rename downloaded FLACs using metadata
slskd-transform rename --source-dir /path/to/downloads --dest-dir /path/to/organizedslskd-transform loads configuration from multiple sources with this priority:
CLI flags > Environment variables > Config file > Defaults
Create config.yml in your working directory or ~/.config/slskd-transform/config.yml:
# slskd connection
host: "http://127.0.0.1:5030"
api_key: "your-api-key"
verify_ssl: false
# Search settings
music_dir: "./music"
duration_tolerance: 15
num_threads: 5
search_timeout: 60
format: "flac"
recursive: false
# Rename settings
source_dir: "./downloads"
destination_dir: "./organized"All settings can be configured via SLSKD_ prefixed environment variables:
| Variable | Description | Default |
|---|---|---|
SLSKD_HOST |
slskd instance URL | http://127.0.0.1:5030 |
SLSKD_API_KEY |
slskd API key | -- |
SLSKD_VERIFY_SSL |
Enable SSL verification | false |
SLSKD_MUSIC_DIR |
Source directory with lossy files | ./music |
SLSKD_DURATION_TOLERANCE |
Max duration difference (seconds) | 15 |
SLSKD_NUM_THREADS |
Concurrent search threads | 5 |
SLSKD_SEARCH_TIMEOUT |
Wait time for search results (seconds) | 60 |
SLSKD_FORMAT |
Target format to search for | flac |
SLSKD_RECURSIVE |
Scan directories recursively | false |
SLSKD_SOURCE_DIR |
Download directory for rename | ./downloads |
SLSKD_DESTINATION_DIR |
Output directory for rename | ./organized |
slskd-transform [OPTIONS] COMMAND [ARGS]...
Options:
-c, --config PATH Path to config.yml
--host TEXT slskd host URL
--api-key TEXT slskd API key
--no-verify-ssl Disable SSL verification
-t, --threads INTEGER Number of search threads
--help Show help
Commands:
search Search Soulseek for lossless versions and enqueue downloads
rename Rename downloaded FLACs using metadata
search options:
-m, --music-dir PATH Directory with lossy source files
-r, --recursive Scan music directory recursively
-f, --format TEXT Target format (default: flac)
--tolerance INTEGER Duration match tolerance in seconds
--timeout INTEGER Seconds to wait for search results
rename options:
-s, --source-dir PATH Directory where slskd downloads land
-d, --dest-dir PATH Destination for renamed files
docker run --rm \
-e SLSKD_HOST=http://slskd:5030 \
-e SLSKD_API_KEY=your-key \
-v /path/to/lossy:/app/music:ro \
-v /path/to/downloads:/app/downloads \
ghcr.io/geiserx/slskd-transform:2.0.0 search --recursiveOr in a compose stack alongside slskd:
services:
slskd:
image: slskd/slskd:0.21.4
ports:
- "5030:5030"
volumes:
- ./slskd-data:/app
slskd-transform:
image: ghcr.io/geiserx/slskd-transform:2.0.0
environment:
SLSKD_HOST: http://slskd:5030
SLSKD_API_KEY: your-key
volumes:
- /path/to/lossy:/app/music:ro
- ./slskd-data/downloads:/app/downloads
command: ["search", "--recursive"]Local library Soulseek network Your disk
(lossy files) (FLAC files)
song.mp3 ──────> Search "song flac" ──────> song.flac
│ │ │
read duration compare duration enqueue if
with mutagen (+/- 15 seconds) match found
│ │ │
└──── no match ──> unfound_songs.csv │
v
slskd-transform rename
Artist - Title.flac
| Project | Description |
|---|---|
| telegram-slskd-local-bot | Automated music discovery and download via Telegram |
| audio-transcode-watcher | Automated multi-format audio transcoding with lyrics fetching |
| jellyfin-encoder | Automatic 720p HEVC/AV1 transcoding for Jellyfin |
This project is licensed under the GPL-3.0 License.