Cover Art Archive Stage
The Cover Art Archive Stage finds album art for your Play using Cover Art Archive, a free and open collection of album art that is part of MusicBrainz.
This Stage is useful for adding artwork to scrobbles from Sources that do not provide any art.
This Stage is simpler than other Stages: it only changes the art of your Play and only runs when your Play does not already have art (by default).
This Stage finds art by using the MusicBrainz ID (MBID) of the album that is already in your Play data. It does not search using the album name or artist name.
If your Play does not have an album MBID then this Stage cannot find art. Use a Stage that adds MBIDs, like the Musicbrainz Stage or the Rocksky Stage, before this Stage. See Get MBIDs First.
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 Cover Art Archive API calls for faster processing.
Configuration
API Setup
No API setup is required. APIs can still be configured in the event you are using mirrors, a proxy, or want to configure different rate limiting.
To use the default Stage in Rules and Hooks either omit name or specify it as "name": "MSDefault".
Non-Default Servers and Rate Limiting
Other, or additional, Cover Art Archive Servers/Mirrors can be added to the API configuration. If more than one server is defined then multi-scrobbler will load balance requests based on available rate capacity.
Use url to define the base URL of the Cover Art Archive server to use. If url is not defined multi-scrobbler assumes it is the primary Cover Art Archive server, https://coverartarchive.org.
Example of multiple servers:
{
// ...
"transformers": [
{
"type": "coverartarchive",
"name": "MyCAA",
"data": {
"apis": [
{
"enable": true
// uses default Cover Art Archive server https://coverartarchive.org
},
// additional server
{
"enable": true,
"url": "https://my.caa.mirror.domain.com"
}
]
},
}
]
}
Rate Limiting
Cover Art Archive servers can optionally be configured with rate limiting.
Rate limiting is defined by max number of requests within timespan of N seconds. If no rate limit is configured then a default of 100 req/s is used.
Example of configuring rate limit:
{
// ...
"transformers": [
{
"type": "coverartarchive",
"name": "MyCAA",
"data": {
"apis": [
{
"enable": true,
"rate": {
// IE 10 req/s
"requests": 10, // maximum of 10 requests
"perTime": 1 // can be made within 1 second
}
}
]
},
}
]
}
Stage Configuration
All of the properties found in the Finding Art section are configured in Stage Configuration as defaults.
Example:
{
// ...
"transformers": [
{
"type": "coverartarchive",
"name": "MyCAA",
"defaults": {
"allowedTypes": ["any"],
"preferredSizes": ["500"]
}
}
]
}
Rules and Hooks
Add your Stage to a Source or Client by specifying it in a Hook:
[
{
"name": "MyDiscord",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "coverartarchive",
"name": "MSDefault"
}
]
}
}
}
]
This Stage only has one Stage Rule: art. It should be either a boolean, specifying if the found art should be used, or a when condition. If art is not set it defaults to true.
Example
[
{
"name": "MyDiscord",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "coverartarchive",
"name": "MSDefault",
"art": {
"when": {/* ... */}, // will only apply art to Play if "when" is satisfied
}
}
]
}
}
}
]
The defaults you set in Stage Configuration can be overriden/added to (per property) in each Hook.
Example
[
{
"name": "MyDiscord",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "coverartarchive",
"name": "MSDefault",
"allowedTypes": ["any"], // override from defaults
}
]
}
}
}
]
ENV Configuration
The general configuration shown above can also be configured from a selection of presets using ENV Config for individual Sources/Clients.
To configure stage defaults use CAA_PRESETS with a comma-delimited list of presets you wish to apply. More than one preset can be applied, in which case they combine. If CAA_PRESETS is not set the stage will use defaults.
default- Only uses art that is marked as the front cover of the album. This is the same as using no presets.any- Uses art of any type: front cover, back cover, or booklet.
Finally, use ENV *_TRANSFORMS=coverartarchive on each Source/Client you wish to apply this stage to. This applies the stage in the preCompare 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 Jellyfin Sources ENVs look like
JELLYFIN_URL=192.168.0.110:8096etc... - Use
JELLYFIN_TRANSFORMS=coverartarchive
Stages in *_TRANSFORMS run in the order they are written. To get MBIDs first, list the stage that adds MBIDs before coverartarchive, like JELLYFIN_TRANSFORMS=musicbrainz,coverartarchive
Example Full Docker Deploy with ENV Configuration
Using Jellyfin example from Quickstart with the Musicbrainz Stage and the Cover Art Archive Stage:
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
container_name: multi-scrobbler
environment:
- MB_PRESETS=default
# allow any type of art, not only front covers
- CAA_PRESETS=any
- JELLYFIN_URL=192.168.0.110:8096
- JELLYFIN_APIKEY=c9fae8756fbf481ebd9c5bb56b
- JELLYFIN_USER=MyUser
# adds MBIDs with Musicbrainz Stage, then finds art with Cover Art Archive Stage
- JELLYFIN_TRANSFORMS=musicbrainz,coverartarchive
- MALOJA_URL=http://domain.tld:42010
- MALOJA_API_KEY=1234
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
To use the configured ENV stage in Rules and Hooks with File/AIO config either omit name or specify it as "name": "MSEnv".
Finding Art
All properties found in this section are optional.
Should MS Search?
Before MS searches for art it checks if your Play already has album art. By default, if your Play has album art then the Stage is skipped.
Use these options to change when MS searches:
forceSearch(defaultfalse) - Always search, even when your Play already has album art
Example
Stage Configuration example:
// ...
"defaults": {
// uncomment to make the stage always search, even if album art is present
//"forceSearch": true
}
How MS Searches
MS looks up art using the MBIDs in your Play, in this order:
- The album MBID (MusicBrainz calls this a Release). This is the exact version of the album you listened to, like a special edition or a specific country's release.
- The album group MBID (MusicBrainz calls this a Release Group). This covers all versions of the same album. MS only uses it when step 1 does not find art that meets your requirements.
When one step finds art that meets your requirements, MS stops and uses that art.
If your Play has neither MBID, or no art meets your requirements, then the stage is marked as failed (onFailure) for Flow Control.
Art Type
Cover Art Archive labels each image with what it shows. Use allowedTypes to choose which images MS may use. Can contain any of:
front- The front cover of the albumback- The back cover of the albumbooklet- A page from the booklet that comes with the albumany- Any image, no matter what it shows
The default is ["front"].
If you list more than one type then an image must be labeled with all of them. For example, ["front", "back"] only allows images labeled as both a front and a back cover. To allow any image use ["any"].
Note: Not all art is labelled correctly, or at all, on CAA. If you just want some album art for your data then you should use any.
// ...
"defaults": {
// allow any image
"allowedTypes": ["any"]
}
Art Size
Cover Art Archive has each image in different sizes. Sizes are measured in pixels (the width of the image). Available sizes are:
250- small500- medium1200- large
There are two options for sizes:
allowedSizes(default["any"]) - Only use images that are available in these sizes. An image must be available in at least one size you list, or useanyto allow any image.preferredSizes(default["250", "500", "1200"]) - The sizes you want, in order. MS uses the first size in your list that is available. If none are available, MS uses any size the image has.
// ...
"defaults": {
// allow art with either 1200 or 500 sizes
"allowedSizes": ["1200","500"],
// prefer the largest size first
"preferredSizes": ["1200", "500"]
}
Best Practices
Caching
You should setup metadata caching to reduce API calls, improve transform performance, and reduce memory usage when using this stage.
Get MBIDs First
This Stage needs an album MBID in your Play. Many Sources do not provide MBIDs. Put a Stage that adds MBIDs, like Musicbrainz or Rocksky, before this Stage in the same Hook.
Set failureReturnPartial: true on this Stage. Then, if this Stage cannot find art, the changes from the earlier Stage are still kept.
Example
[
{
"name": "MyJellyfin",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
// adds MBIDs to the Play
"type": "musicbrainz",
"name": "MSDefault"
},
{
// uses the MBIDs to find art
"type": "coverartarchive",
"name": "MSDefault",
// keep Musicbrainz changes even if no art is found
"failureReturnPartial": true
}
]
}
}
}
]
Examples
Minimal
Example
In a Jellyfin Source File Config:
[
{
"name": "MyJellyfin",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "coverartarchive",
"name": "MSDefault"
}
]
}
}
}
]
Or using a Jellyfin Source with ENV Config:
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
environment:
# ... your source ENVs go here
#
# applies Cover Art Archive Stage to preCompare of Jellyfin Source
- JELLYFIN_TRANSFORMS=coverartarchive
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
Add Album Art for Discord
The Discord Client shows album art when your Play has art. Use the Musicbrainz Stage and the Cover Art Archive Stage on the preCompare hook for your Discord client so that missing art is added.
Example
- ENV
- File
- AIO
Using the ENV Configuration from above, add these fields to your docker compose environment:
- CAA_PRESETS=any
- DISCORD_TRANSFORMS=musicbrainz,coverartarchive
In your Discord File Config:
[
{
"name": "MyDiscord",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MSDefault"
},
{
"type": "coverartarchive",
"name": "MSDefault",
"failureReturnPartial": true
}
]
}
}
}
]
Your AIO Config:
{
// ...
"clients": [
{
"name": "MyDiscord",
"type": "discord",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "musicbrainz",
"name": "MSDefault"
},
{
"type": "coverartarchive",
"name": "MSDefault",
"failureReturnPartial": true
}
]
}
}
}
]
}