Skip to content

Rocksky Stage

The Rocksky Stage matches your Play with metadata from Rocksky. If the match score is high enough then Multi-Scrobbler uses the match to correct and fill-in some missing information in your Play data.

This Stage is useful for normalizing plays for the Rocksky scrobbler or adding metadata ids and artwork from a fast metadata provider.

No API setup is required at this time. APIs can still be configured in the event you using 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, Rocksky 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 Rocksky server to use. If url is not defined multi-scrobbler assumes it is the primary Rocksky server, https://api.rocksky.app.

Example of multiple servers:

config.json
{
// ...your AIO Config
"transformers": [
{
"type": "rocksky",
"name": "MyRocksky",
"data": {
"apis": [
{
"enable": true1
},
{2
"enable": true,
"url": "https://my.rs.mirror.domain.com"
}
]
},
}
]
}
  1. 1.uses default Rocksky server https://api.rocksky.app
  2. 2.additional server

Rate Limiting

Rocksky servers can optionally be configured with rate limiting.

Rate limiting is defined by max number of requests within timespan of N seconds.

These constraints apply:

  • Official Rocksky server (https://api.rocksky.app or when no url is defined) is hard-limited to 1000 req / 30s
  • No limits for other, custom servers but a default 1 req/s limit is applied when none is configured

Example of configuring rate limit:

config.json
{
// ...your AIO Config
"transformers": [
{
"type": "rocksky",
"name": "MyRocksky",
"data": {
"apis": [
{
"enable": true1
},
{2
"enable": true,
"url": "https://my.rs.mirror.domain.com",
"rate": {3
"requests": 6,4
"perTime": 15
}
}
]
},
}
]
}
  1. 1.uses default Rocksky server https://api.rocksky.app, hard-limited to 1000 req / 30s
  2. 2.additional server
  3. 3.IE 6 req/s
  4. 4.maximum of 6 requests
  5. 5.can be made within 1 second

All of the properties found in Matching with Rocksky section are configured in Stage Configuration as defaults.

Example:

config.json
{
// ...your AIO Config
"transformers": [
{
"type": "rocksky",
"name": "MyRocksky",
"defaults": {
"searchWhenMissing": ['duration','mbid'],
"allowNoMatch": false
}
}
]
}

Add your Stage to a Source or Client by specifying it in a Hook:

rocksky.json
[
{
// ...your Rocksky File Config
"name": "Rocky",
"configureAs": "client",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault"
}
]
}
}
}
]

Each Stage Rule should be either a boolean, specifying if the transformed data should be used for this field, or a when condition:

Example
rocksky.json
[
{
// ...your Rocksky File Config
"name": "Rocky",
"configureAs": "client",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault",
// ...
"title": false,1
"album": {
"when": {/* ... */},2
/* ... */
},
"meta": true3
}
]
}
}
}
]
  1. 1.will not apply any changes to Play title
  2. 2.will only apply changes to Play album if "when" is satisfied
  3. 3.adds MusicBrainz MBIDs to scrobble data

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 RS_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 default searchOrder isrc+basic (same as using no presets that affect searchOrder)
  • id - Adds searchOrder methods that priorites searching by ID: isrc + mbid + basic
  • native - Adds Extracted Artists (artist) in native mode to searchOrder

Finally, use ENV *_TRANSFORMS=rocksky 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 Rocksy Clients ENVs look like ROCKSKY_USER=myuser etc…
  • Use ROCKSKY_TRANSFORMS=rocksky
Example Full Docker Deploy with ENV Configuration

Using Jellyfin example from Quickstart with Rocksky and the Rocksky Stage:

docker-compose.yml
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
container_name: multi-scrobbler
environment:
- RS_PRESETS=default1
- JELLYFIN_URL=192.168.0.110:8096
- JELLYFIN_APIKEY=c9fae8756fbf481ebd9c5bb56b
- JELLYFIN_USER=MyUser
- ROCKSKY_ID=Rocky
- ROCKSKY_HANDLE=alice.bsky.social
- ROCKSKY_APP_PW=1234567
- ROCKSKY_TRANSFORMS=rocksky2
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
  1. 1.searches with the searchOrder isrc => basic
  2. 2.applies Rocksky Stage to preTransform of Rocksky Client

To use the configured ENV stage in Rules and Hooks with File/AIO config either omit name or specify it as "name": "MSEnv".

Rocksky metadata is still maturing so the data MS ultimately applies your scrobbles is artifically restricted at this time.

Using Rules for Play Data we can usually categorically transform any part of our Play (scrobble) using the data produced by a stage:

Example
{1
"type": "rocksky",
// ...
"title": false,2
//"albumArtists": true, // always applies
//"artists": true // always applies
"album": false,3
//"duration": true, // always applies
//"meta": true, // always applies
//"art": true, // always applies
}
  1. 1.all properties *not* explicitly set default to true
  2. 2.will not apply rocksky changes to Play title
  3. 3.will never apply changes to Play album

But for the Rocksky Stage some of these transformations come with conditions and some are completely disabled.

You can still set all Rules normally, like any other Stage, but these prerequisites will always be checked, and the property transformation skipped, if they are not met:

  • title and album are only applied if the original scrobble is missing them
  • albumArtists is never applied
  • artists are only applied if the original scrobble
    • has no artists
    • has only 1 artist and Rocksky returned multiple
  • meta is only applied if the original scrobble is missing them (MBIDs) or only has recording MBID

All other parts behave as normal.

Matching your Scrobble’s Play data with a result from Musicbrainz is comprised of two steps:

  • Searching Rocksky using parts of your Scrobble as queries
  • Refining matched results to select the desired/allowed match

Both steps have separate configuration.

Before MS begins a search it checks if your Scrobble data already contains:

  • A track title, artists, album, and duration
  • An associated recording MBID

If it already has all required data types then the entire Rocksky 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: artists track album duration mbid
  • forceSearch (default false) - Force searching even if all required data is present
Example
"defaults": {
"searchWhenMissing": ["duration", "mbid"],1
//forceSearch: true2
}
  1. 1.only search if duration or recording MBID is missing
  2. 2.uncomment to make the stage always search, even if above data is present

If required data is missing then the next step is making search queries to Rocksky’s metadata API to try to get potential candidates.

Multi-scrobbler can search for Rocksky 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": {
"searchOrder": ["isrc", "basic", "artist"]1
}
  1. 1.only searches using these methods, in the order they are listed here

Available Methods

ISRC (isrc)

If your Scrobble data contains an ISRC (usually from Spotify) then Multi-scrobbler can search using this ID, title, and artist only.

"defaults": {
"searchOrder": ["isrc"]1
}
  1. 1.will only search using isrc
Recording MBID (mbid)

If your Scrobble data contains a Recording MBID then Multi-scrobbler can search using this MBID, title, and artist only.

"defaults": {
"searchOrder": ["mbid"]1
}
  1. 1.will only search using recording mbid
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.

"defaults": {
"searchOrder": ["basic"]1
}
  1. 1.will only search using album, artist(s), and title
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 a recording MBID it will use those as well as the plain text field.

"defaults": {
"searchOrder": ["basicorids"]1
}
  1. 1.will only search using album, artist(s), and title
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:

"defaults": {
"searchOrder": ["artist"],1
//searchArtistMethod: 'native' // optional
}
  1. 1.will only search using title/album + extracted artists

searchArtistMethod can be set to Native or Naive mode:

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.

Native Mode Example
{
"title": "Endless Possibility (feat. Wheatus)",
"artists": ["Bowling For Soup & Punk Rock Factory, My Cool Band"]
}
  • Extracts Bowling For Soup Punk Rock Factory My Cool Band from artist string
  • Extracts Wheatus from title string
    • Removes (feat. Wheatus) from title string because it found an artist there

Resulting data used for Rocksky search:

{
"title": "Endless Possibility",
"artists": ["Bowling For Soup", "Punk Rock Factory", "My Cool Band", "Wheatus"]
}
"defaults": {
"searchOrder": ["artist"],1
"searchArtistMethod": "native"
}
  1. 1.will only search using title/album + native extracted artists

Each match returned by Rocksky can contain a list of matched external provider entries (Spotify, Deezer, etc…) that contain 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 any of these entries. Default is 90.

{
// ...
"score": 901
}
  1. 1.external provider entries must score 90 or higher to be considered

Rocksky may still return a match even if no external provider entries were associated.

You can configure whether a match is still considered valid when no entries are associated by setting allowNoMatch. The default is to allow matches with no associated entries.

{
// ...
"allowNoMatch": false1
}
  1. 1.consider a match invalid if not associated with an external provider

You should setup metadata caching to reduce API calls, improve transform performance, and reduce memory usage when using this stage.

How complete, and accurate, your scrobble data is from a certain Source should dictate what Search Methods you should use for matching.

Rocksky is generally pretty good at finding the right match given mostly good/consistent data but if you are not confident of the ID-type data in your scrobbles (MBID, ISRC) you should consider omitting these search method types.

Matching Scrobbles from Last.fm

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 mbid 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.

Use Rules to apply Rocksky 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 MBID using meta so that any Client that supports Musicbrainz data (Koito, Tealfm, Listenbrainz, Rocksky) can still get that data.

Example
rocksky.json
[
{
// ...your Rocksky File Config
"name": "Rocky",
"configureAs": "client",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault",
"title": false,
"artists": false,
"album": false,
"albumArtists": false,
"meta": true
}
]
}
}
}
]
Example
rocksky.json
[
{
// ...your Rocksky File Config
"name": "Rocky",
"configureAs": "client",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault"
}
]
}
}
}
]

Or using a Rocksky Client with ENV Config:

docker-compose.yml
services:
multi-scrobbler:
image: foxxmd/multi-scrobbler
environment:
- RS_PRESETS=default1
# ... your source ENVs go here
#
- ROCKSKY_ID=Rocky
- ROCKSKY_HANDLE=alice.bsky.social
- ROCKSKY_APP_PW=1234567
- ROCKSKY_TRANSFORMS=rocksky2
volumes:
- "./config:/config"
ports:
- "9078:9078"
restart: unless-stopped
  1. 1.searches with the searchOrder isrc => basic
  2. 2.applies Rocksky Stage to preTransform of Rocksky Client

Add Metadata Only (No Scrobble Modification)

Section titled “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
jellyfin.json
[
{
// ...your Jellyfin File Config
"name": "MyJellyfin",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault",
"title": false,
"artists": false,
"album": false,
"albumArtists": false,
"meta": true1
}
]
}
}
}
]
  1. 1.only update scrobble metadata with MBIDs

Different Search Methods Based on Source (Last.fm and Spotify)

Section titled “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
  • For Last.fm, we want to use only text searches and take whatever correction is given to us

Use Per Component Overrides to specify different search behavior for each Source.

Example
lastfm.json
[
{
// ...your Last.fm File Config
"name": "MyLFM",
"configureAs": "source",
"data": { /* ... */},
"options": {
"playTransform": {
"preCompare": [
{
"type": "rocksky",
"name": "MSDefault",
"searchArtistMethod": "native",
"searchOrder": ["basic", "artist"]1
}
]
}
}
}
]
  1. 1.does not use any ID searches

The Discord Client can fetch album art images from Cover Art Archive if the Scrobble data contains a Release MBID. Use the Rocksky Stage on the preCompare hook for your Discord client so that missing Rocksky IDs are populated for this functionality.

Example

Using the ENV Configuration from above, add these fields to your docker compose environment:

- RS_PRESETS=default
- DISCORD_TRANSFORMS=rocksky