Overview
A Client is an application that stores the historical information about what songs you have played (scrobbles). Examples are Maloja, Last.fm, Listenbrainz...
Clients
| Name | Now Playing |
|---|---|
| Discord | ✅ |
| Last.fm | ✅ |
| Libre.fm | ✅ |
| Listenbrainz | ✅ |
| Koito | ❌ |
| Maloja | ❌ |
| Rocksky | ❌ |
| Teal.fm | ❌ |
Features
Duplicate Detection
Before a Play is scrobbled to a client MS checks existing scrobbles from the Client's API to see if the Play has already been scrobbled.
For each Play, MS fetches (cached) scrobbles from the Client in a time range inclusive of the Play's listening timestamp and then scores existing scrobbles against the Play based on:
- Similarity of Title, Artists, and Album
- Temporal closeness of the Play's timestamp to the existing scrobble's timestamp
- Whether MS detected the Play as a repeat (applicable to Sources that report realtime Player data)
Detailed scoring breakdowns against each existing scrobble are logged at the TRACE level.
Detailed Explanation
A candidate (to be scrobbled) Play is first transformed using the configured compare.candidate Hook, if any exists.
Next, MS checks (up to) the last 100 scrobbles in-memory scrobbles that it has made. These are not from the Client but the actual scrobbles MS made while it has been running. The data from these scrobbles is much richer than what is usually parsed from the Client which makes it easier to detect duplicates from.
If no in-memory scrobble matches then MS starts comparing the candidate against historical scrobbles fetched from an inclusive time range of the candidate's timestamp.
Matching Title/Artist/Album
For these string-based values MS uses an token-order-invariant method that scores string similarity based on a (token count) weighted average of two similarity algorithms, Levenshtien Distance and Dice's Coefficient. The weighted average ensures that very long strings (Track titles) are scored with a confidence proportional to their length.
Matching Timestamp
Timestamps are scored on how temporally close they are. There are four possible scores with decreasing value:
- Exact - Timestamps are within 1 second of each other
- Close - Timestamps are within
thresholdseconds of each other- This is determined by the smallest update interval of Source
- Some Sources (subsonic) only update every 60 seconds so this is the smallest "close" value possible. Most are 10 seconds. Signified by
(Needed <10s)in the breakdown example below.
- Some Sources (subsonic) only update every 60 seconds so this is the smallest "close" value possible. Most are 10 seconds. Signified by
- This is determined by the smallest update interval of Source
- Fuzzy - One timestamp is within
thresholdseconds of the end of the other timestamp- Sources can set the scrobble timestamp at different times. Some do it when the track is started listening to, some when it ends, some when the player stops.
- Where possible, MS knows and keeps track of when this timestamp should be, for each Source. If it's not possible then Fuzzy may be allowed.
- None - There is no correlation between timestamps
Scoring and Breakdows
A candidate Play must score >= 1 to be detected as a duplicate of an existing scrobble.
Each score and a breakdown of the scores for its individual components can be see at the TRACE logging level or in the debug data for a scrobble. An example:
* Artist: 0.06 * 0.3 = 0.02
* Title: 0.04 * 0.4 = 0.02
* Time: (Exact) 1 * 0.5 = 0.50
* Existing: 19:13:33-04:00 - Candidate: 19:13:33-04:00
* Temporal Sameness: Exact
* Play Diff: 0s (Needed <10s)
* Range Comparison N/A
Score 0.54 => No Match
In each component equation, the first number is the similarity (or temporal closeness).
- 0 = no correlation
- 1 = exactly the same
The second number is the weight of that component in the final score.
Dead Scrobbles
If multi-scrobbler is unable to submit a scrobble to a Client then it places the scrobble into a queue which is retried every 5 minutes for a number of times before it gives up.
After it stops automatically retrying the scrobble still exists and can be retried from the dashboard. Dead scrobbles persist between restart so you will never lose a scrobble that hasn't been successfully submitted yet.
Now Playing
Multi-scrobbler can report the currently playing tracks it is monitoring to some Scrobble Clients via their individual Now Playing functionality.
Now Playing is default enabled for all Clients that support it.
The behavior multi-scrobbler uses for determining Now Playing reporting:
- Now Playing can be explicitly enabled or disabled globally using ENV
NOW_PLAYING=trueorNOW_PLAYING=false- This only affects Clients that don't have behavior set via File/AIO (below)
- Now Playing will be only be reported to the same Clients a Source is configured to scrobble to
- A Source's Player status must be Playing, IE active, for reporting to occur
- This status can be verified via Player UI on the Dashboard
- If multiple Sources having active Players then the scrobble Client will default to reporting the track based on Source configuration name, alphabetically
- This is the
nameproperty set in File or AIO source configs
- This is the
Clients can customize the Now Playing behavior individually using File or AIO source configs:
[
{
"name": "myLastFmClient",
"configureAs": "client",
"data": {
// ...
},
"options": {
// disable or enable
//"nowPlaying": true
//
// OR define a list of Source *config* names that should be allowed to report Now Playing
// order of the list determines priority for reporting Now Playing
//"nowPlaying": ["mySpotify1","myJellyfin2"]
}
},
]