Musicbrainz Stage
The Musicbrainz Stage matches your Play data with the MusicBrainz database. If the match score is high enough then Multi-Scrobbler uses the match to correct and fill-in missing information in your Play data.
This Stage is useful for standardizing your Scrobble's Play data, regardless of the Source it is coming from.
Even if you have have strong opinions about the way your existing music is already tagged/organized you should consider adding the Musicbrainz Stage to your Sources, if only to benefit from adding MBIDs to scrobbled metadata.
Why Should I Prefer MusicBrainz?
More Than Mainstream Data
The MusicBrainz database contains
- 37 million+ tracks
- 5 million+ albums
- 2.7 million+ artists
in over 200 languages, contributed by 10,000+ editors each year with many more users voting on edits.
The database covers a much wider range of music than most commercial services since it isn't restricted by licensing or incentivized to prioritize mainstream music due to business interests. You are much more likely to find data for obscure, indie, and international artists.
As The Artist Intended
While some large services (Spotify) may be more consistent in data structure, the MusicBrainz equivalent data is likely to be more true to the way the Artist originally intended since individuals can devote effort to individual artists. A fan of an artist is much more likely to "get it right" for their favorite band than a corporate business trying to do the least amount of work for the largest result.
If you are using ENV Config for multi-scrobbler and just want a quick and easy setup, skip to ENV Configuration.
Set up Valkey Caching to cache Musicbrainz API calls for faster processing.
Configuration
API Setup
To avoid rate limiting, MusicBrainz requires API users to identify themself using a User-Agent that contains an email or URL. You must set this in the data for your stage configuration in your AIO Config:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
]
},
}
]
}
Additional Musicbrainz Servers
Other, or additional, Musicbrainz Servers/Mirrors can be added to the API configuration. If more than one server is defined then multi-scrobbler will round-robin load balance API calls.
Use url to define the base URL of the Musicbrainz server to use. If url is not defined multi-scrobbler assumes it is the primary Musicbrainz server, https://musicbrainz.org.
Example of multiple servers:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
// uses default Musicbrainz server https://musicbrainz.org
},
// additional server
{
"contact": "contact@mydomain.com",
"url": "https://my.mb.mirror.domain.com"
}
]
},
}
]
}
Stage Configuration
All of the properties found in Matching with Musicbrainz section are configured in Stage Configuration as defaults.
Example:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
],
"defaults": {
"releaseStatusPriority": ["official"],
"releaseAllowEmpty": true
}
},
}
]
}
Rules and Hooks
Add your Stage to a Source or Client by specifying it in a Hook:
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB"
}
]
}
}
}
]
Each Stage Rule should be either a boolean, specifying if the transformed data should be used for this field, or a when condition:
Example
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB"
// ...
"title": false, // will not apply any changes to Play title
"artists": {
"when": {/* ... */}, // will only apply changes to Play artists if "when" is satisfied
/* ... */
},
"album": true // will always apply changes to Play album
"meta": true // adds MusicBrainz MBIDs to scrobble data
}
]
}
}
}
]
The defaults you set in Stage Configuration can be overriden/added to (per property) in each Hook.
Example
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
"releaseStatusPriority": ["psuedo-release"], // override from defaults
"searchOrder": ["freetext"] // add new property, combined with defaults
}
]
}
}
}
]
ENV Configuration
The general configuration shown above can also be configured from a selection of presets using ENV Config for individual Sources/Clients.
You must always include the MB_CONTACT ENV to identify your application:
MB_CONTACT=contact@mydomain.com
To configure stage defaults use MB_PRESETS with a comma-delimited list of presets you wish to apply. More than one preset can be applied, in which case they combine. You must choose at least one of the presets below:
default- Adds the defaultsearchOrderisrc+basic(same as using no presets that affectsearchOrder)id- AddssearchOrdermethods that priorites searching by ID:isrc+mbidrecording+basicOrIds+basicnative- Adds Extracted Artists (artist) innativemode tosearchOrderaggressive- Adds Free Text Search (freetext) tosearchOrderfields- Applies Field Scoring to match sorting so match text is baised towards similarity to original scrobblesensible- Applies the Sensible Default configuration for sorting releases
Finally, use ENV *_TRANSFORMS=musicbrainz on each Source/Client you wish to apply this stage to. This applies the stage in the preTransform Hook with all Rules enabled.
The * stands for the prefix used for each Source/Client's ENV keys. Refer to the individual Source/Client Configuration sections to find this. Example:
- All Subsonic Source ENVs look like
SUBSONIC_USER=myuseretc... - Use
SUBSONIC_TRANSFORMS=musicbrainz
Example Full Docker Deploy with ENV Configuration
Using Jellyfin + Maloja example from Quickstart:
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
container_name: multi-scrobbler
environment:
- MB_CONTACT=contact@mydomain.com
# searches with sensible release sorting with the searchOrder
# isrc => basic => artist (native mode)
- MB_PRESETS=default,sensible,native
- JELLYFIN_URL=192.168.0.110:8096
- JELLYFIN_APIKEY=c9fae8756fbf481ebd9c5bb56b
- JELLYFIN_USER=MyUser
# applies musicbrainz Stage to preTransform of Jellyfin source
- JELLYFIN_TRANSFORMS=musicbrainz
# maloja receives enhanced scrobble from Jellyfin
- MALOJA_URL=http://192.168.0.100:42010
- MALOJA_API_KEY=myApiKey
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
Matching with Musicbrainz
All properties found in this section are optional.
If you just want a sensible default for configuraion refer to the Best Practices section.
Matching your Scrobble's Play data with a result from Musicbrainz is comprised of two steps:
- Searching Musicbrainz using parts of your Scrobble as queries
- Refining matched results to select the desired/allowed match
Both steps have separate configuration.
Searching
Should MS Search?
Before MS begins a search it checks if your Scrobble data already contains:
- MBIDs for artists, album, and specific track/recording
- and duration
If it already has all required data types then the entire Musicbrainz Stage is skipped. If any are missing then a search is performed.
Define which data types are required using:
searchWhenMissing(defaults to all) - A list containing any of:artiststitlealbumdurationforceSearch(defaultfalse) - Force searching even if all required data is present
Example
Stage Configuration example:
// ...
"defaults": {
// only search if MBIDs for artists or album is missing
"searchWithMissing": ["artists", "album"]
// uncomment to make the stage always search, even if above data is present
//forceSearch: true
}
If required data is missing then the next step is making search queries to the Musicbrainz database to try to get potential candidates.
Search Methods
Multi-scrobbler can search for Musicbrainz matches using multiple methods. You control:
- the search methods that are used
- the order in which search methods are executed
All search methods will be run in the order they were defined until one method returns at least one match.
The methods you choose, and the order they run in, can drastically change how many API calls are needed to get a match, and what types of matches are returned. See Search Considerations for guidance on how to decide on methods based on Source.
To set search methods and their order use the searchOrder option in your Stage Configuration:
// ...
"defaults": {
// only searches using these methods, in the order they are listed here
"searchOrder": ["isrc", "mbidrecording", "basic","freetext"]
}
If searchOrder is undefined then Multi-scrobbler will default to using isrc then basic method.
Available Methods
ISRC (isrc)
If your Scrobble data contains an ISRC (usually from Spotify) then Multi-scrobbler can search using this ID, only.
Stage Configuration example:
// ...
"defaults": {
// will only search using isrc
"searchOrder": ["isrc"]
}
Track MBID (mbidrecording)
If your Scrobble data contains an Track (Recording) MBID then Multi-scrobbler can search using this MBID, only.
Stage Configuration example:
// ...
"defaults": {
// will only search using recording mbid
"searchOrder": ["mbidrecording"]
}
Album, Artist, and Title Fields (basic)
Will search Musicbrainz using any/all available text fields from your scrobble: Album, Artists(s), and Title. Does not leverage any existing MBIDs.
Stage Configuration example:
// ...
"defaults": {
// will only search using album, artist(s), and title
"searchOrder": ["basic"]
}
Album/Artist/Title OR MBIDs (basicOrIds)
This is the same as the above Album, Artist, and Title Fields search except that if the scrobble data contains any corresponding MBIDs it will use those instead of the plain text field.
Stage Configuration example:
// ...
"defaults": {
// will only search using album, artist(s), and title
"searchOrder": ["basicOrIds"]
}
Example:
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup"]
"albumMbid": "c9f91cdc-984e-4303-9a51-4ac0dfa2348f",
"album": "My Cool Album"
}
Multi-scrobbler will search Musicbrainz using title, artists, and albumMbid but NOT album.
Album And Title Only (album)
If your Scrobble data contains a title, artist(s), and an album (all three fields) then Multi-scrobbler can search using only title and album by using album for searchOrder:
Stage Configuration example:
// ...
"defaults": {
// will only search using only title + album name
"searchOrder": ["album"]
}
Extracted Artists (artist)
If your scrobble data contains only one artist string then Multi-scrobbler can attempt to extract multiple artists from your artist and track string.
Use artist with searchOrder and optionally specify the extraction mode with searchArtistMethod:
Stage Configuration example:
// ...
"defaults": {
// will only search using title/album + extracted artists
"searchOrder": ["artist"],
//searchArtistMethod: 'native' // optional
}
searchArtistMethod can be set to Native or Naive mode:
- Native (Recommended)
- Naive
Native (native) mode uses an aggressive configuration of the Native Stage to extract artists using common delimiters and common "joined" artist patterns from the artist and title string of your Scrobble data.
If you already have a Native Stage configured you should use that instead, running it before the Musicbrainz stage.
Native Mode Example
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup & Punk Rock Factory, My Cool Band"]
}
- Extracts
Bowling For SoupPunk Rock FactoryMy Cool Bandfrom artist string - Extracts
Wheatusfrom title string- Removes
(feat. Wheatus)from title string because it found an artist there
- Removes
Resulting data used for Musicbrainz search:
{
"title": "Endless Possibility",
"artists": ["Bowling For Soup", "Punk Rock Factory", "My Cool Band", "Wheatus"]
}
Stage Configuration example:
// ...
"defaults": {
// will only search using title/album + native extracted artists
"searchOrder": ["artist"],
"searchArtistMethod": "native"
}
Naive (naive) mode looks for the first found common delimiter in the artist string. If it finds one then it uses the preceding value as the only artist in the Musicbrainz search. It does not try to extract additional artists from the artist string, or extract anything from the title string.
Naive Mode Example
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup, Punk Rock Factory & Wheatus"]
}
- Finds
&as first common delimiter, extracts "Bowling For Soup"
Resulting data used for Musicbrainz search:
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup"]
}
Stage Configuration example:
// ...
"defaults": {
// will only search using title/album + naive extracted artists
"searchOrder": ["artist"],
"searchArtistMethod": "naive"
}
Free Text (freetext)
This will search Musicbrainz for all text of your Scrobble data artist/title/album, without constraint.
Free text search is unconstrained which means that Musicbrainz will match text in any part of a Recording (artist, release, or recording field), regardless of where it is found. This may lead to results that are unexpected and undesired.
If you know your Source's Play data is well organized you should not enable this. Free Text search should only be used if:
- your music is not well organized or
- there may be many alternative titles/artists for the music you listen to (such as with psuedo-releases)
- you can tolerate that matches may not be accurate for releases.
- Generally, if you keep score high then matched releases should at least be the right artist or what you would expect within a reason, as a match. The release may not be the one you actually listened to but it would be "close enough".
Stage Configuration example:
// ...
"defaults": {
// ...
// will only search using free text search of all artist/album/title
"searchOrder": ["freetext"],
}
If all defined search methods do not return any results then the stage is marked as failed (onFailure) for Flow Control.
Refining
Score
Each match returned by MusicBrainz contains a numeric score representing how close it was to the search parameters. Set score in configuration to set a minimum score that must be met by matches. Default is 90.
{
// ...
"score": 90 // matches must score 90 or higher to be considered
}
Filtering
There are several attributes associated with the Release a Recording (individual Track/song) belongs to that you may be interested in controlling. MS can use these attributes to filter what the final Recording selected to match against your Play data is.
An easy way to think about this:
- Do you prefer Albums, Singles, or EPs?
- Do you always want to use an official album release, or are bootleg or cancelled albums okay to use?
- Should a track that belongs to a Compilation album be allowed to match?
- What country do you prefer an album release to be from?
Release Attributes
These attributes (attribute_name in config) are:
- Release Status (
releaseStatus) - Is this release/album/ep official, promotional, bootleg, etc... - Release Group Primary Type (
releaseGroupPrimaryType) - Is this release an Album, Single, EP, etc... - Release Group Secondary Type (
releaseGroupSecondaryType) - Is this release a compilation, soundtrack, remix, etc... - Release Country (
releaseCountry) - What ISO2 country was this released in? US, GB, MX, etc...- MusicBrainz uses the special code
XWto represent a "Worldwide" release AKA release not made specifically for a country
- MusicBrainz uses the special code
Each of the above attributes can be used to filter matches using allow (explicitly include) or deny (exclude) terms. The correct property name for each is like so:
[attribute_name]Allow = [...]
[attribute_name]Deny
EX to explicitly allow only release status "official"
"releaseStatusAllow": ["official"]
EX to exclude compilations
"releaseGroupSecondaryTypeDeny": ["compilation"]
Empty Releases
Sometimes a Recording may not have any associated Releases. This may be because there is not enough information about the Recording yet, or it was never included on an actual Release.
You may want to filter the majority of your matches by releases but allow matching a Recording that has no releases to begin with. To allow this set releaseAllowEmpty to true in configuration:
// ...
"defaults": {
// ...
"releaseAllowEmpty": true // don't remove a match during filtering just because it has no releases
}
Sorting
After matches have been filtered, the remaining matches and their releases* can be sorted. Matches/Releases with an attribute that does not match are not removed, but they are sorted lower than matches that do match.
Sorting can be a good alternative to filtering: with filters there is a possibility your filters may eliminate all matches; if you want to ensure that some match will be used then sorting can ensure that the best choice out of those given will always be used, without accidentally ending up with no choice.
Sorting can be used instead of filters, or in conjunction with filters, it's your choice.
Release Attributes
Each Release Attribute has one additional property that can be used to rank releases based on the order of the values you give it. This is the priority property.
In configuration:
[attribute_name]Priority = [...]
EX to prefer "official" releases over everything else
"releaseStatusPriority": ["official"]
EX to prefer albums, then singles, over everything else
"releaseGroupPrimaryTypePriority": ["album", "single"]
Field Scoring
Matches can additionally be sorted/ranked based on how similar their fields are to the original Scrobble. Use these properties for sorting when you want the final Musicbrainz match to be as closely matched to the original Scrobble, as opposed to what may be the most "correct" match based on the Musicbrainz score or suggested Release.
Example Scenario
You scrobble this track from spotify, which has an English title, Album name, and Artist name.
{
"track": "Price",
"artists": ["ATLUS Sound Team"],
"album": "PERSONA5 ORIGINAL SOUNDTRACK"
}
However, the Recording found by Musicbrainz has multiple Releases (albums). The first suggested release is a related Album with similar name (Persona 25th Anniversary Deluxe Vinyl Box Set) but it's not the same as your album. Additionally, the artists for this album are in Japanese, rather than English.
You have used releaseStatusPriority to prioritize psuedo-release which does work but there are still multiple releases chosen, and some are non-English (『ペルソナ5』オリジナル・サウンドトラック).
Using "albumWeight": 0.4 and "artistWeight": 0.3 ensures that the releases that have an album name, and artist names, more similar to your original scrobble are ranked higher. Resulting in the correct Release (PERSONA5 ORIGINAL SOUNDTRACK) being chosen as the final match.
Add one or more of these weight properties to your Stage Configuration to enable Field Scoring:
// ...
"defaults": {
// ...
// enables album text similiarity scoring
"albumWeight": 0.33,
// enables title text similiarity scoring
"titleWeight": 0.33,
// enables artist text similiarity scoring
"artistWeight": 0.33
}
While not enforced, it's a good idea to keep these weights under 1. And if using more than one weight, they should be add up to 1.
How Scoring is Combined
The score similarity from albumWeight will be added to the score accumulated by Release Attributes to affect the final ranking of each Release for a Match/Recording.
In the final sorting of Recordings, title score + artist score is combined with the top ranked release album score. The top ranked score is then used to choose the matched Recording.
Best Practices
Sensible Default
Generally, the Musicbrainz Stage can be used without any of the optional configuration and you should still see good results from matches. The top scored match is, anecdotally, good enough for correcting and filling in surface-level play data like Title and Artist names.
For a more opinionated match that will mirror what you would expect from data from large music services:
{
// use official release over anything else
"releaseStatusPriority": ["official"],
// prefer album, then single, then ep
"releaseGroupPrimaryTypePriority": ["album", "single", "ep"],
// prefer worldwide release
"releaseCountryPriority": ["XW"]
}
Consider adding Artist Extraction (artist) in Native Mode if any of your Sources do not support multiple artists or your music collection is not tagged well.
Details
{
// use official release over anything else
"releaseStatusPriority": ["official"],
// prefer album, then single, then ep
"releaseGroupPrimaryTypePriority": ["album", "single", "ep"],
// prefer worldwide release
"releaseCountryPriority": ["XW"],
// search using extracted artist as last search attempt
"searchOrder": ["isrc", "basic", "artist"],
"searchArtistMethod": "native"
}
Search Considerations
How complete, and accurate, your scrobble data is from a certain Source should dictate what Search Methods you should use for matching.
Musicbrainz agressively normalizes artist, album, and title fields in its database which means that if your Scrobble data contains major innaccuracies or phrases fields in a non-normal way, it's possible Musicbrainz won't find any matches. This is a more common occurrence when trying to match Scrobble data from Sources that don't support multiple artist data, like Subsonic and Last.fm.
Examples of Bad Data
Last.fm Scrobble returns an Artist in the title and combines two artists into one string:
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup & Punk Rock Factory"]
}
The corresponding Musicbrainz Recording has all artists separated and no artist in the title:
{
"title": "Endless Possibility",
"artists": ["Bowling For Soup", "Punk Rock Factory", "Wheatus"]
}
In general, you should prioritize methods that search by unique identifiers (isrc mbidRecording basicOrIds) if you know your Sources may contain accurate data for these. Such as: Spotify, Jellyfin, Plex, and Listenbrainz (Source).
Use field-based methods if your Sources do not return IDs consistently (or at all). Add more field-based methods the more inaccurate your scrobble data may be, but be aware that more aggressive/broad searches may return less accurate results.
Last.fm is inconsistent when it comes to matching your scrobbles. It will accept (almost) any fields for track/title/album and aggressively attempt to match/correct these, regardless of your intentions.
Unless the client scrobbling to Last.fm is also sending an mbid, it's likely your scrobble will not be consistently matched correctly and so the mbid supplied by last.fm in its scrobble data will be wrong.
Therefore, you should avoid using mbidRecording and basicOrIds as the primary search methods (or understand the risks of using them). Instead, prefer to use field-based methods before falling back to id-based methods.
Filter Considerations
When using your own filters consider:
- Prefer
denyoverallow- Releases come in all kinds of formats. Since
allowis explicit you may filter out your desired match without realizing it (correct data except for release type). Or the Musicbrainz data for a higher scored match may be appropriate but you did not include it, exhaustively.
- Releases come in all kinds of formats. Since
- Prefer Sorting over Filtering
- Sorting does not eliminate any matches. It is, generally, better to get some match than it is to have your Play data completely uncorrected because filtering eliminated all matches
Using Partial Match
Use Rules to apply MusicBrainz match data selectively.
If you know that your music collection is well organized and you do not want to change the artists/title/album etc... sent to a Client, you can still benefit from matches by only applying MBIDs using meta so that any Client that supports Musicbrainz data (Koito, Tealfm, Listenbrainz, Rocksky) can still get that data.
Example
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
"title": false,
"artists": false,
"album": false,
"albumArtists": false,
"meta": true
}
]
}
}
}
]
Logging
If
- Musicbrainz is not returning matches
- Multi-scrobbler is using the wrong match
- or the resulting enhanced Scrobble is not what you expected
Enable logging by turning on Debug Mode to help diagnose any issues with the Musicbrainz API and Scrobble enhancement. Before creating an issue please enable logging and include any logs with your issue as this is needed to debug.
If you have multiple Modification Stages and need to see the diff for your Play between each Stage, enable "log": "all" in the individual Modification Stage.
Example
In a Subsonic File Config:
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"log": "all",
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
}
]
}
}
}
]
Examples
Minimal
Example
Your AIO Config:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
]
},
}
]
}
In a Subsonic File Config:
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB"
}
]
}
}
}
]
Sensible Default
Using the config shown in Sensible Default with File/AIO config, instead of ENV Config.
Example
Your AIO Config:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
]
},
"defaults": {
"releaseStatusPriority": ["official"],
"releaseGroupPrimaryTypePriority": ["album", "single", "ep"],
"releaseCountryPriority": ["XW"],
"searchArtistMethod": "native"
"searchOrder": ["isrc", "basic", "artist"]
}
}
]
}
In a Subsonic File Config:
[
{
"name": "MySubsonic",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB"
}
]
}
}
}
]
Add Metadata Only (No Scrobble Modification)
If you do not want your scrobble data to be modified (artists/album/title) but still want to benefit from associating the scrobble with a Musicbrainz match (for Scrobble Clients like Tealfm, Rocksky, and Koito), then use Partial Match rules to specify only meta to be updated.
Example
Your AIO Config:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
]
},
"defaults": {
// maybe something like Sensible Default?
}
}
]
}
In a Jellyfin File Config:
[
{
"name": "MyJellyfin",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
"title": false,
"artists": false,
"album": false,
"albumArtists": false,
"meta": true // only update scrobble metadata with MBIDs
}
]
}
}
}
]
Use Native Stage if no Musicbrainz Matches
- Musicbrainz Stage configured with
- Sensible Defaults
- Fallback search with Artist Extraction
- Default Native Stage
- Uses Flow Control to run Native only if there are no Musicbrainz matches
Example
Your AIO Config:
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
]
},
"defaults": {
"releaseStatusPriority": ["official"],
"releaseGroupPrimaryTypePriority": ["album", "single", "ep"],
"releaseCountryPriority": ["XW"],
"searchArtistMethod": "native",
"searchOrder": ["isrc","basic", "artist"]
}
}
]
}
In a Jellyfin File Config:
[
{
"name": "MyJellyfin",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
// if musicbrainz is successful then do NOT run native,
// only run native if musicbrainz fails to find a match (onFailure)
"type": "musicbrainz",
"name": "MyMB"
"onSuccess": "stop",
"onFailure": "continue"
},
{
"type": "native"
}
]
}
}
}
]
Different Search Methods Based on Source (Last.fm and Spotify)
Last.fm has unreliable MBIDs and Spotify provides an ISRC and consistent formatting.
- For Spotify, we want to rely on ID searches and matches that are close to original scrobble text
- For Last.fm, we want to use only text searches and take whatever correction is given to us
Use Per Component Overrides with the default (or sensible) Stage Configuration to specify different search behavior for each Source.
Example
Stage Configuration
{
// ...
"transformers": [
{
"type": "musicbrainz",
"name": "MyMB",
"data": {
"apis": [
{
"contact": "contact@mydomain.com"
}
],
"defaults": {} // maybe use sensible?
},
}
]
}
[
{
"name": "MyLFM",
"configureAs": "source"
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
"searchArtistMethod": "native"
// does not use any ID searches
// fallback to more aggressive/broad searches
"searchOrder": ["basic", "artist", "freetext"]
}
]
}
}
}
]
[
{
"name": "MySpotify",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MyMB",
// use ISRC as first search
"searchOrder": ["isrc", "basic"]
// bias matches towards similarity to original data
"albumWeight": 0.33,
"titleWeight": 0.33,
"artistWeight": 0.33
}
]
}
}
}
]