subsonic-duplicates (1.2.0)
Installation
[registries.forgejo]
index = "sparse+ " # Sparse index
# index = " " # Git
[net]
git-fetch-with-cli = truecargo add subsonic-duplicates@1.2.0 --registry forgejoAbout this package
subsonic-duplicates
A CLI tool to find and manage duplicate tracks in a Subsonic-compatible music server (Navidrome, Airsonic, etc.). It detects duplicates via fuzzy title/artist matching and MusicBrainz IDs, then lets you interactively pick the canonical version of each group. The result is exported as a Subsonic playlist of non-canonical tracks that you can exclude from shuffle/playback.
Installation
From the Forgejo registry:
cargo install --registry forgejo subsonic-duplicates
Or from source:
cargo install --path crates/cli
# or
cargo build --release && ./target/release/subsonic-duplicates --help
Configuration
Run the interactive setup wizard to create the config file:
subsonic-duplicates setup
It prompts for the server URL, username, and password (masked), plus optional settings. It can optionally test the connection before saving. Re-running setup shows current values and lets you update individual fields.
Or create ~/.config/subsonic_duplicates/config.toml manually:
url = "http://your-navidrome:4533"
username = "admin"
password = "secret"
# Optional settings (shown with their defaults):
# client = "subsonic-duplicates"
# playlist_name = "Duplicates"
# db_path = "duplicates.db"
# reference_playlist = "My Reference Playlist"
Use --config <path> to specify a different config file location, and --db-path <path> to override the database path for a single run.
Workflow
just run # sync + find + review in one step (main interactive workflow)
just export # upload the Duplicates playlist to Subsonic
Or step by step:
just sync # pull track metadata from Subsonic into duplicates.db
just find # detect duplicate groups (idempotent)
just review # interactively pick the canonical track for each group
Utilities:
just search "QUERY" # find track IDs; optionally link all results as a group
just link TRACK_A TRACK_B # manually mark two tracks as duplicates
just evaluate [TRACK_ID] # show one group non-interactively (for AI-assisted review)
just clear-db # delete duplicates.db
After rating tracks or syncing updated metadata, ratings can drift out of sync within a decided group (e.g. the canonical is rated 4★ but a duplicate copy is still at 3★). Fix this with:
subsonic-duplicates sync-ratings
This finds all decided groups where the canonical and at least one duplicate have different ratings, shows them one by one, and propagates the canonical's rating to the out-of-sync duplicates on the Subsonic server (requires network credentials). It also updates the local database cache so the next review session sees consistent ratings.
Review UI
Each group shows all duplicate tracks with colour coding:
- Green — obvious canonical (only track not in the reference playlist, no warnings)
- Yellow — Various Artists compilation track
- Red — track from the reference playlist
Commands at the prompt:
| Input | Action |
|---|---|
1–N |
Pick track N as the canonical |
s |
Skip this group |
q |
Quit review |
r <1-5> |
Rate all tracks in the group |
x <n> [m ...] |
Split: track(s) n [m …] form one sub-group, the rest form another |
Groups where every track is unrated are skipped automatically (reported at the end). If all tracks except one share a rating, you are asked whether to auto-rate the unrated track before picking a canonical.
Status
v1.0 — The author's full music collection has been reviewed and deduplicated using this tool.
Further Reading
- REQUIREMENTS.md — full feature specification, detection rules, configuration reference
- ARCHITECTURE.md — crate layout, data flow, schema details, test infrastructure
Dependencies
| ID | Version |
|---|---|
| anyhow | ^1 |
| clap | ^4 |
| dirs | ^5 |
| opensubsonic | ^0.3 |
| rpassword | ^7 |
| rusqlite | ^0.32 |
| rusqlite_migration | ^1 |
| serde | ^1 |
| strsim | ^0.11 |
| thiserror | ^2 |
| tokio | ^1 |
| toml | ^0.8 |
| hound | ^3 |
| id3 | ^1 |
| reqwest | ^0.12 |
| serde_json | ^1 |
| tempfile | ^3 |
| tokio | ^1 |
| uuid | ^1 |