Sync your Last.fm play counts and loved tracks including timestamps to Navidrome with intelligent caching.
-
Install dependencies:
git clone https://github.com/zeroquinc/NaviSync.git cd NaviSync pip install -r requirements.txt -
Configure: Copy
env.exampleto.envand fill in your details:NAVIDROME_DB_PATH=Z:/navidrome/navidrome.db NAVIDROME_URL=http://192.168.0.50:4533 LASTFM_API_KEY=lastfmapikey LASTFM_USER=Username LASTFM_API_SECRET=yoursessionkey LASTFM_SESSION_KEY=optional SCROBBLED_FIRSTARTISTONLY=True FIRST_ARTIST_WHITELIST=["Suzan & Freek", "Simon & Garfunkel", "AC/DC"] ENABLE_FUZZY_MATCHING=True FUZZY_MATCHING_THRESHOLD=85 # Minimum similarity score to consider a fuzzy candidate FUZZY_MATCHING_AUTO_THRESHOLD=95 # Automatically accept a fuzzy match at or above this score PLAYCOUNT_CONFLICT_RESOLUTION=ask SYNC_LOVED_TO_LASTFM=False ALBUM_MATCHING_MODE=album_agnostic DUPLICATE_RESOLUTION=ask AUTO_CONFIRM=False
Navidrome must be stopped while sync runs so the database can be updated safely.
-
Run:
python main.py -
It is important to delete the cache and json folders when updating from this repo, as they may contain some changes.
- Keep your play counts in sync - Never lose track of your listening history by updating Navidrome play counts
- Sync your loved tracks - Last.fm hearts become Navidrome stars
- Reverse sync (optional) - Sync Navidrome stars TO Last.fm as loved tracks (requires authentication)
- Fast after first run - Only processes new plays, not your entire history
- Intelligent fuzzy matching - Finds potential matches for track name variations:
- Handles
&vsand, special characters, accents, and minor differences - Prompts you to confirm uncertain matches and can auto-accept high-confidence matches
- Shows similarity scores to help you decide
- Remembers your choices - confirmed matches are saved and used automatically in future runs
- You have full control over which tracks get matched
- Handles
# Extract first artist from collaborations (e.g. "Artist A feat. Artist B" → "Artist A")
SCROBBLED_FIRSTARTISTONLY=True
FIRST_ARTIST_WHITELIST=["Simon & Garfunkel", "AC/DC"] # Keep these exactENABLE_FUZZY_MATCHING=True # Default: True
FUZZY_MATCHING_THRESHOLD=85 # Minimum similarity score to consider a fuzzy candidate
FUZZY_MATCHING_AUTO_THRESHOLD=95 # Automatically accept a fuzzy match at or above this scoreOptions:
True- Enable fuzzy matching with prompts for similar tracks (recommended for accuracy)False- Only exact matches, no prompts (faster but fewer matches)
Threshold settings:
FUZZY_MATCHING_THRESHOLDcontrols the minimum combined similarity score used to find fuzzy candidatesFUZZY_MATCHING_AUTO_THRESHOLDenables automatic acceptance of the top fuzzy match when its score meets or exceeds this percentage
When enabled, the script intelligently finds potential matches for track name variations. With FUZZY_MATCHING_AUTO_THRESHOLD set, high-confidence matches are accepted automatically, while lower-confidence matches still prompt for confirmation.
PLAYCOUNT_CONFLICT_RESOLUTION=ask # Options: ask, navidrome, lastfm, higher, incrementConflict Options:
ask- Prompt for each conflict (default)navidrome- Keep Navidrome when higherlastfm- Always use Last.fmhigher- Use whichever is higherincrement- Add counts together
ALBUM_MATCHING_MODE=album_agnostic # Options: album_agnostic, album_aware, promptAlbum Handling Options:
album_agnostic- Combine scrobbles for same artist/title regardless of album (default, current behavior)- Example: "Track A" on "Album X" and "Compilation Y" both get 100 plays total from Last.fm
- When multiple album versions exist, prompts user to choose which to update
album_aware- Match by artist/title/album, allowing different play counts per album- Example: "Track A" on "Album X" gets 60 plays, same track on "Compilation Y" gets 40 plays
- Ideal for mixed albums, compilations, and avoiding duplicate play counts in smart playlists
prompt- Like album_agnostic, but always asks which album version(s) to update (no auto-selection)
DUPLICATE_RESOLUTION=ask # Options: ask, all, first, skipDuplicate Options:
ask- Prompt for each duplicate track version (default)all- Update all duplicate versions automaticallyfirst- Update only the first version foundskip- Skip tracks that have duplicates
AUTO_CONFIRM=False # Default: FalseOptions:
False- Show final confirmation prompt before applying updates (default)True- Skip final confirmation and apply updates immediately
Sync Navidrome starred tracks TO Last.fm as loved tracks:
SYNC_LOVED_TO_LASTFM=True # Default: FalseSetup (one-time):
-
Get your API Secret from Last.fm API Account
-
Add to
.env:LASTFM_API_SECRET=yourapisecret
-
Get session key (interactive):
python -c "from src.lastfm import get_session_key; get_session_key()" -
Follow the prompts, authorize in browser, then add the session key to
.env:LASTFM_SESSION_KEY=yoursessionkey
-
Enable reverse sync:
SYNC_LOVED_TO_LASTFM=True
View cache status: python cache_info.py --info
View fuzzy match mappings: python cache_info.py --fuzzy
Reset sync status: python cache_info.py --reset
Clear album cache/fuzzy matches entries: python clear_album_cache.py
Fuzzy Match Mappings: Once you confirm a fuzzy match (e.g., "The Great Hall and The Prophecy" → "The Great Hall & The Prophecy"), it's saved in the cache. Future runs will automatically use this mapping without prompting you again.
Setup issues: python check_setup.py
First run slow: Normal - fetches all historical scrobbles. Subsequent runs are fast!
MIT License - see LICENSE file for details.