All versions since 0.19.0
0.19.0
This is huge release that brings a ton of new Play/Scrobble modification options to MS!
What’s New?
Simpler Config For Teal/Rocksky Sources
App Password has been removed from required config for Teal.fm and Rocksky Sources. It still required for Clients (scrobblers).
Simpler Config for Musicbrainz Transformer
Due to the lack of required config since the change to the Musicbrainz API in 0.18.0, explicit setup of the Musicbrainz transformer is no longer required. It is now built-in to MS with a default configuration that can be used without needing to specify apis or anything in your AIO/ENV config.
You can still configure rate limiting for the default server, or add additional servers, using the same config. It’s just not required to explicitly set anything anymore.
Example
If you currently have this in your config.json
{ // ... "transformers": [ // your empty musicbrainz transform { "type": "musicbrainz", "name": "MyMB", "data": { "apis": [ { "enable": true } ] }, }, // ...maybe more transforms here ], // ...}You can remove the musicbrainz object entirely. If it’s the only entry in your transforms array then you can remove that too.
Then, in your Source/Client transform hooks change this
"playTransform": { "preCompare": [ { "type": "musicbrainz", "name": "MyMB" } ] }to this
"playTransform": { "preCompare": [ { "type": "musicbrainz", "name": "MSDefault" } ] }or entirely remove "name": "MSDefault" and MS will use whatever is configured first.
Rocksky PDS Client
The Rocksky Client has been rewritten to use the sdk agent for scrobbling rather than scrobbling through the Rocksky server.
This change, along with using the new Rocksky matchSong metadata API, means Multi-Scrobbler can now:
- give you immediate feedback on when a scrobble does not meet Rocksky’s standard of quality and
- directly write scrobbles to your PDS repository
This is a huge improvement in user experience over the old “submit scrobble to rocksky server and find out later if it was accepted” approach. Use this in conjunction with the new Rocksky Transformer to get (essentially) guaranteed scrobbles to Rocksky with verifiable writes.
An additional benefit of the PDS client is that MS now supports Now Playing for Rocksky.
Rocksky Transformer
A new scrobble enhancement stage is available, the Rocksky Transformer.
This stage uses Rocksky’s metadata API to match multiple providers (deezer, spotify, etc…) and returns an enriched metadata result that Multi-Scrobbler can use to add Musicbrainz Recording MBID, ISRC, artists, etc… similar to how the Musicbrainz Stage works.
Rocksky’s metadata API is still a work-in-progress so the resulting transformation is limited for now, but it is extremely fast and provides good results!
Use this in conjunction with the Rocksky PDS Client to guarantee scrobbles for Rocksky or as a fast-and-cheap alternative to Musicbrainz.
Spotify Transformer
A new scrobble enhancement stage is available, the Spotify Transformer. All of the research, config options, and initial implementation was contributed by @DigitalStarSys :tada:
This stage works similarly to Rocksky and Musicbrainz transformers in that it is useful for fixing/enriching your scrobble data.
It is advantageous to use, over Musicbrainz, if you prefer a simpler setup with fast API responses and formatted data that is familiar to a mainstream audience (vs. having to configure Musicbrainz and filter through all the different release types).
Note: This transform requires a premium Spotify account (same as the Spotify Source) to use the Spotify API.
Cover Art Archive Transformer and Art Transforms
A new scrobble enhancement stage is available, the Cover Art Archive Transformer. This is standalone version of the Cover Art Archive functionality found in Discord.
When this Stage is used, if your scrobble data has Musicbrainz’ MBIDs for album or release-group and is missing album art, MS will use the CAA API to fetch an album art URL.
Art In Other Transformers
As part of this improvement, both the Rocksky and Spotify Transformer can also populate album art URLs when they are missing. This is enabled automatically as part of Stage Rules and can be explicitly disabled with a rule "art": false.
Device Info for Listenbrainz-Compatible Scrobblers
Thanks to @rpschube reported device info from Sources can now be safely submitted as scrobble data to listenbrainz-compatible clients (Listenbrainz and Koito) without leaking any PII by using an allowlist of scrubbed identifiers to match with real device ids.
See the Scrobbling Device Data expandable section on Listenbrainz and Koito clients to see how this works.
Reduced Docker Build Size
More cleanup done after 0.18.0 revealed a large number of files in docker file build layers that could be easily pruned. A minor rewrite of the Dockerfile has eliminated these and improved build times as well. The cleaned up docker image is 20% smaller than 0.18.1.
Typescript Strict Mode
The entire project has been refactored to compile with typescript strict mode on. This “enables a wide range of type checking behavior that results in stronger guarantees of program correctness” which in laymen’s terms means that ongoing development of Multi-Scrobbler is less likely to introduce new bugs. Just moving to strict mode fixed at least 30+ undiscovered bugs!
Dynamic Transformer Loading and Usage
The logic that loads code for tranformers has been refactored so that all transformers and their dependencies loaded just before a Source/Client actually uses them instead of on startup. This should result in less memory usage for all users but especially those that don’t use any transformers at all.
Additionally, the names of built-in transformers and the order they are used in has been changed to be deterministic and give you more options for which you would like to use, between built-in, ENV configured, or file/aio configured. See the Breaking Changes section below for these changes.
Breaking Changes
Rocksky Auth API Key Removal and Token Deprecation
- The previously-deprecated API Key authentication for Rocksky has been removed
- Access Token authentication for Rocksky is now deprecated in favor of handle/app password auth that uses the new functionality from above.
- Review the Rocksky Client docs for how to set this up
Discord Cover Art Archive Deprecation
The automatic Cover Art Archive usage currently found in the Discord Scrobbler is now deprecated and should be replaced with a Cover Art Archive Transformer.
Example
For Discord Scrobbler with ENV add this to your environmental variables:
DISCORD_TRANSFORMS=coverartarchiveFor File/AIO add the example playTransform block to your config options (or just add the coverartarchive stage config if you already have hooks configured):
{ "name": "MyDiscord", "data": { /* ... */}, // add this "options": { "playTransform": { "preCompare": [ { "type": "coverartarchive", } ] } } }A new Kitchensink example shows a more complex example, here.
Transform Names and Fallbacks
Transform stages are specified by type and name when used in a Source/Client, however the name is optional.
Example
[ { "name": "MySubsonic", "data": { /* ... */}, "options": { "playTransform": { "preCompare": [ { "type": "musicbrainz", "name": "MyMB" // name is optional } ] } } }]Previously when name was omitted MS used the first non-default transformer, then tried the default.
Now, names and order of selection (when name is omitted in configuration) looks like this:
- MS looks for a non-default, non-ENV config first
- MS falls back to ENV config (name is
MSEnv) if it exists - MS falls back to default config (name is
MSDefault) if it exists
Steps to migrate:
- If you only use
named configs that aren’tMSDefaultthere are no changes necessary - If you only use ENV configuration there are no changes necessary
- If you use the
nameMSDefaultbut do not mix ENV transforms with AIO/File config, no changes are necessary - If you use the
nameMSDefaultand also have ENV transforms configured (musicbrainz)- Rename
nametoMSEnv
- Rename
See more about Stage Names and Defaults in this new section in the docs.
Logs Directory for Non-Docker Users
More attention has gone into the Data Directory Standardization work that began in 0.15.0. Now, the directory logs are written to has been standardized, alongside the existing data and config directories.
This change only affects non-docker users.
The logs directory is now determined by, in order of priority:
LOGS_DIRENVLOGS_DIRECTORYENV (used by systemd)- OS-specific standardized path
You can see OS-specific paths here in the documentation.
If you are running multi-scrobbler locally with nodejs you’ll likely want to set LOGS_DIR=./config/logs
Other Changelog Highlights
- fix(endpointlz): Missing ‘import’ enum for listen_type on submit payload #732
- fix: Update dbcomponent at runtime when name changes #721
0.19.1
Changelog
⛰️ Features
- (musicbrainz) Disallow audiobook and music videos with config options #734
🐛 Bug Fixes
- (transform) Add missing musicbrainz default transform #737
0.19.2
Changelog
🐛 Bug Fixes
- (transform) Don’t try to initialize transformers that are already initializing, reduces noisy logging on startup
- (transform) Fix async transform initialization race condition and type/name key case sensitivity #739
v0.20.0
What’s New?
Play Editing and Search
Plays can now (finally) be edited! If your scrobbles fail you can now edit the data to correct it manually before resending it.
A plain text mode is initially used where you can edit everything related to fields and metadata ids
Additionally a search mode is available to search all of the metadata providers you have setup. Musicbrainz, Spotify, and Rocksky can all be searched concurrently. Selecting a result fills in that field, any associated fields (track can set artists + album), and meta ids.
Musicbrainz and Rocksky providers are automatically setup. All providers automatically inherit from your existing transformers. You can also set up preferred providers to only use some of them, or use with alternative configuration.
See the docs for more information.
Tuneshine Client
Tuneshine, a wifi-connected hardware device with an aesthetic, low-count LED display for showcasing the album art of the music you are currently listening to, is now integrated as a Scrobble Client.
Like Discord, it can be used to display Now Playing activity from any of your Sources.
Mixcloud Source
Mixcloud is now integrated as a Scrobble Source thanks to @anandghegde
This source records the mixes you listen to as scrobbles. It supports both free and Pro Mixcloud accounts.
Metadata Overhaul
Previously, metadata like track identifiers from Spotify/Musicbrainz/etc… and album art, were stored alongside a Play but they were not strongly associated with specific parts of the Play. This lead to situations where some functionality would require assertions like “Artist 1 has metadata artist ID 1” but it was not possible to guarantee this.
Now, Play data has been restructured to tightly associate all of this metadata to the field it belongs to. This change does not affect any end-user functionality but it dramatically simplifies developer experience. The Play Editing functionality above would have been much more difficult without this change, for example.
Changelog Highlights
⛰️ Features
- (endpointlz) Allow disabling artist extraction from ingress payload #750 #751
- (deezer) Add ISRC and optional title variant to parsed data #752 #754
- (koito) Add includePlayPosition to koito scrobbler implementation #741 #742
- (spotify) Periodically backfill songs from spotify history api for missed live playback state #735 thanks to @sudbrack
- (No Category) Consolidate SSE for logs into events to reduce connection pool usage for HTTP/1.1
- (No Category) Consolidate global SSE connections with coordinator
🐛 Bug Fixes
- (docs) Resource static asset link broken by trailingSlash #573
- (listenbrainz) Only use original artist_name in naive play if no artists credits were extracted #750
- (stats) Persist lifetime discovered/scrobbled counts across restarts #745 @dylangovender
- (No Category) Improve detection of repeat plays when listen range is close to end of a position player
📚 Documentation
- (discord) Update kasmweb/discord service example
- (metadata) Add editing and metadata search
- (No Category) Add reverse proxy recommendation and tips
🚜 Refactor
- (No Category) Decouple transform manager init
- (No Category) Circular dependency elimination
⚙️ Miscellaneous Tasks
- (No Category) Add docs and devcontainer modifications to ease discord IPC development with kasmcord
v0.20.1
This release bumps the Nodejs version used in the docker image to 24.22.1 in order to include the october security release fixes in the distributed docker image.
You should upgrade as soon as possible in any case, but users who run MS in a way that exposes it to the public internet (API or UI accessible from a non-authenticated URL) are particularly vulnerable as this fixes an exploit for remote code execution. Do not delay upgrading if you are in this scenario.
v0.20.2
This is another security fix that removes compromised eMudhra certificates from the base docker image. #759
v0.20.3 Latest
What’s New?
Docs Moved to Starlight
Documentation has been migrated from Docusaurus to Astro ✨Starlight✨
Docusaurus has been great but Starlight, and Astro being a general static site build system, is more flexible and lighter. Along with the already-strong community plugin support it has enabled more functionality for the MS docs that was not possible with Docusaurus.
The docs now have a fresh look with clearer/more readable styling. Particularly awesome new features:
- Code blocks get walkthroughs, footnotes, inline linking, stylized focus, dynamic placeholders, and much more thanks to starlight-codeblocks
- Changelogs are now built into the public site
Additionally, the developer experience for docs is greatly simplified. Same build commands but many things, like og image generation and open api doc generation, are all built-in now.
Improved Shutdown Behavior
MS now handles all exit signals (SIGNIT and SIGTERM) instead of just SIGINT. On exit signal it now tries to gracefully stop all Source/Clients by letting all currently processing Plays/scrobbles finish before closing the database and shutting down.