Skip to content

Changelog

0.8.4

What’s New?

Jellyfin Source API

A new Jellyfin Source that uses the official API library has been implemented. This supersedes and deprecates the existing webhook-plugin-based Jellyfin Source. Benefits of new implementation:

  • More accurate information about plays fixes multiple artists reporting
  • Eliminates need for exposed MS instance (to Jellyfin) which simplifies networking
  • User can authenticate using user/pass OR Api Key
  • More attention/development on @jellyfin/sdk should mean better support going forward

See the Jellyfin Source docs for migration steps from webhook to API. The webhook Source will be removed in a future version of MS.

Scrobble Modification Conditions

Scrobbles Modifications, introduced in the last release, can now have “conditional” criteria to help you decide when a search-replace operation on a scrobble should occur.

See the Scrobble Modification docs for how to use this and examples.

Development Improvements

Git Workflow

Workflows for MS have been simplified. The develop branch has been removed in favor of using master as the active development branch. All PRs should now target master instead of develop. Additionally, the develop docker image has been renamed edge.

VS Code

VS Code settings have been committed and docs have been added to make MS development with VS Code as close to one-click as possible. Settings include debug configurations, test running, typescript build, and devcontainer environment.

Full Changelog

Bug Fixes

  • (jellyfin) Map AlbumArtist Name property
  • (plex) Refactor plex webhook formdata parsing to be more defensive
  • (No Category) Bump @foxxmd/logging version to fix read-only system issues – thanks to @jackwilsdon for the fix in https://github.com/FoxxMD/logging/pull/2
  • (No Category) Strip wrapping quotes from base url
  • (No Category) Freeze typescript to fix weird unused error directive problem

Features

  • (jellyfin) Update schema
  • (jellyfin) Refactor Jellyfin source to use Jellyfin API
  • (jellyfin) Implement partial WS client for future use
  • (modifications) Implement “when” conditions for scrobble modifications
  • (modifications) Refactor hooks to accept an array of parts
  • (No Category) Improve upstream scrobble refresh logic and caching controls
  • (No Category) Add VSCode native dev settings
  • (No Category) Add VSCode devcontainer

Documentation

  • (No Category) Fix link – thanks to @jackwilsdon
  • (No Category) Fix redirect for local documentation – thanks to @jackwilsdon
  • (No Category) Fix youtube music identifier
  • (No Category) Update development docs for VSCode usage
  • (No Category) Add when condition docs and examples
  • (No Category) Add scrobble modification logging docs

Miscellaneous Tasks

  • (ci) Disable alpine builds for PR image
  • (ci) Add dependabot PR test gh action
  • (deps) Bump the npm_and_yarn group across 2 directories with 7 updates
  • (vscode) Add default built task
  • (No Category) Refactor git/dev workflow to use master as unstable branch
  • (No Category) Fix latest/tag for images and disable alpine builds
  • (No Category) Update faker to official release
  • (No Category) Update dockerfile to ignore devcontainer and vscode settings

Testing

  • (No Category) Add missing version prop for test components

Full Changelog: https://github.com/FoxxMD/multi-scrobbler/compare/0.8.3...0.8.4

v0.8.3

What’s New?

VLC as Source

VLC has been implemented as a Source. In addition to scrobbling based on reported fields (ID3 tags) of audio tracks played in VLC a user can specify regular expressions to parse artist/title/album information from filenames when no ID3 tag is present.

Recent Scrobbles bug fix

A major bug was fixed that caused a scrobble client to not store upstream scrobbles (used for duplicate checking) on startup.

Youtube Music Woes

Improvements to logging and handling of inconsistent YTM upstream data has been added as well as entries in the FAQ regarding these problems.

Full Changelog

Features

  • (vlc) Implement vlc Source #177
  • (vlc) Use regex from configuration to extract metadata from filenames
  • (youtube) Increase level of auth update logging when configured to output changes #158
  • (youtube) Use just-validated history as recently played on new plays #156

Bug Fixes

  • (maloja) Improve handling for Maloja warnings-as-errors #180
  • (No Category) Actually store recent scrobbles

Documentation

  • (vlc) Add VLC docs
  • (vlc) Some fixes for VLC docs
  • (youtube) Add FAQ entries for YTM auth and scrobble issues

v0.8.2

What’s New?

MPD (Music Player Daemon) Source

MPD is now a supported Source.

Scrobble Modification

Multi-scrobbler now supports modifying a scrobble (artists, album, track) in-flight using search-and-replace or regex patterns from configuration. The scrobble can be modified:

  • on discovery from a source
  • during comparison when checking duplicates
  • before sending to scrobble client

Why?

You may need to “clean up” data from a Source or before sending to a scrobble Client due to any number of reasons:

  • ID3 tags in your music collection are dirty or have repeating garbage IE [YourMusicSource.com] My Artist - My Title
  • A Source’s service often incorrectly adds data to some field IE My Artist - My Title (Album Version) when the title should just be My Title
  • An Artist you listen to often is spelled different between a Source and a Client which causes duplicate scrobbles

In any scenario where a repeating pattern can be found in the data it would be nice to be able to fix it before the data gets downstream or to help prevent duplicate scrobbling. Multi-scrobbler can help you do this. See the documentation for examples and usage.

Deezer Deprecation

Deezer has discontinued support for their API and so the Deezer Source is now deprecated. The Source will continue to function and will not be removed any time soon but it is still recommended to switch to a more stable alternative such as Deezer -> last.fm -> lfm source for multi-scrobbler.

See this issue for more information.

Full Changelog

Bug Fixes

  • (tests) Do not re-use scrobbler between tests

Features

  • (mpd) Implement MPD Source MVP
  • (mpd) Use idle event to wake up from polling early
  • (musikcube) Provide more error logging and example config
  • (scrobble) Enable forcing existing scrobbles refresh on every scrobble #173
  • (ui) Add timestamp to recent pages #167
  • (No Category) On polling error retry check source is initialized and reinitialize if not
  • (No Category) Implement common play transform functionality
  • (No Category) Add album option to play string building function
  • (No Category) Improve logging for play transforms
  • (No Category) Implement play transforms in source/client logic #173
  • (No Category) Implement removing field if field is an empty string after transforming

Documentation

  • (deezer) Deprecate due to discontinued API support #175
  • (No Category) Add Play Transform docs
  • (No Category) Fix compare example

Miscellaneous Tasks

  • (ci) Update untagged package schedule to run once a week

Refactor

  • (listenbrainz) Simplify scrobble api calls and logging
  • (scrobbler) Consolidate refresh logic and add more logging
  • (scrobbler) Change refresh force to user-configurable staleness time #173

Testing

  • (No Category) Use faker 9.1RC for more plausible artist/album names in generated data

v0.8.1

What’s New?

This release is entirely for documentation and developer experience improvement.

100% Docusaurus and Self-Hosted Docs

While MS was already using Docusaurus for the docs website the prior approach to writing docs was to keep them as plain markdown as possible so they were still accessible without needing access to an external website. With the “plain” markdown docs you could potentially browse from your own markdown reader in a cloned repository.

The downside to this interoperability is that docs, specifically configuration, had grown to be very long and full of nested/too many headers for each iteration of env/file + regular sections for clients/services. Adding additional examples made the problem even worse.

The solution, then, was to make the Docusaurus documentation part of multi-scrobbler! Now the same docs found at https://foxxmd.github.io/multi-scrobbler can also be found at the /docs URL on your multi-scrobbler instance (http://yourHost:9078/docs)

This enabled me to lean fully into Docusaurus and all of the layout, styling, and organization it offers. Alongside general improvements new docs have been added to help onboarding. Some highlights:

  • A Quickstart guide has been added for aiding onboarding
  • Improved readability and usefulness of all content in Configuration docs
    • ENV, File, and all-in-one File configuration has moved to Tabs under each Source/Client
      • Switching config type syncs tabs selection across all sections and in the URL
    • Full configuration examples are displayed for file and AIO-file parsed from the examples in the config directory
  • Improved styling across all docs
    • Copious usage of collapsed sections for examples to make scanning docs easier
    • Improved Table of Contents with only important headings
    • Admonition elements for increasing readability for tips/notes/warnings…
  • Installation docs use Tabs for docker and docker-compose examples
  • Actual development docs and tutorial (!)

And many more…check out the docs site or click on Docs in your MS dashboard to see the updated site.

Flatpak Convenience Setup

A bash script for automating building flatpak from source has been added at flatpak/setup.sh:

  • Removes node_modules and generates sources for flatpak-builder for both MS and the docsite
  • Builds the flatpak app in a given directory

Effectively making flatpak builds a one-line process rather than the manual 7-8 commands it was before.

See flatpak build instructions in the new docs.

Full Changelog

Documentation

  • (feat) Add architecture overview, common dev structures, and dev guidance for Sources
  • (fix) Update package scripts to use npx to invoke docusarus
  • (fix) Add missing docsite build steps to alpine docker variant
  • (flatpak) Implement bash setup script and move flatpak instructions to docsite
  • (No Category) Update docusaurus to v3
  • (No Category) Update docusaurs playground schema for MS to latest
  • (No Category) Improve TOC for docusaurus and github
  • (No Category) Implement self-hosted docs
  • (No Category) Replace manual notes with admonitions
  • (No Category) Lean 100% into docusaurus documentation
  • (No Category) Refactor installation.md for docusaurus
  • (No Category) Update kitchensink.md code block titles
  • (No Category) Parse and render config examples from repository
  • (No Category) Add quick start guide
  • (No Category) Use relative paths for volume mounting

v0.8.0

What’s New?

Musikcube Source

Musikcube, a cross-platform terminal-based music player, is now supported as a Source.

Configuration Normalization

In previous versions many of the common, optional options for source/clients, such as maxRequestRetries or maxPollRetries, were mixed into the data property for configs alongside properties that were specific to that source/client. Additionally, there was an existing options property that already had some common properties, but not all…

jellyfin.json

[
{
"name": "default",
"enable": false,
"clients": [],
"data": {
"maxRequestRetries": 3,
"scrobbleThresholds": {
"percent": 30,
"duration": 30
},
"users": ["MyUser"]
},
"options": {
"logPayload": false
}
}
]

These common properties have been refactored into the options object so that data is now solely for data that is specific to the source/client. This should make configs easier to reason about as well as making programmatic config validity checks easier.

[
{
"name": "default",
"enable": false,
"clients": [],
"data": {
"users": ["MyUser"]
},
"options": {
"logPayload": false,
"maxRequestRetries": 3,
"scrobbleThresholds": {
"percent": 30,
"duration": 30
}
}
}
]

This is potentially a breaking change, behaviorally, but MS will continue to operate without any changes to your config. The options that have been moved are all optional, minor settings that help fine-tune your experience with MS but do not majorly affect how it works or functionally affect how your sources/clients behave.

If you use any of the properties that have been migrated but have not moved them then MS will simply ignore them until they are moved.

For a complete list of moved properties and how to migrate them see this comment.

Docker Image Change

Due to consistent issues with DNS in alpine-based images ( #160 #126 #134) the image base is being changed to Debian. The image size will increase relatively significantly ( 60MB -> 120MB ) but the benefit is a more stable experience for docker users. Thanks to @Ardakilic for helping diagnose docker image issues and extensive testing/usage of the debian image.

This is not a breaking change but is still a significant refactor. If you have issues with the new default image please open an issue. Alternatively, there will still be an alpine-based image published with a -alpine suffix so you can continue to use the original image if you would prefer, though this may go away in the future.

TLDR

Previously…

  • latest or develop or 0.7.1 -> alpine based
  • latest-debian or develop-debian … -> debian-based

Now…

  • latest or develop or 0.8.0 -> debian based
  • latest-alpine or develop-alpine … -> alpine-based and may go away in the future

Youtube Music Improvements

The monitoring behavior for YTM has been improved to prevent duplicate scrobbling as well as provide insight into YTM history issues. #156

Additionally, the authentication method for YTM has been improved to save updated cookies from YTM if/when they are changed which may help with authentication issues in long-running MS instances.

Full Changelog

Bug Fixes

  • (chromecast) Add missing avahi-utils package for debian image
  • (spotify) Convert URL to string for redirectUri
  • (vite) Use default base string if no other path detected
  • (webscrobbler) Add preflight route #157
  • (webscrobbler) Fix formatting of slug url in logs
  • (youtube) Catch auth issues that occur during polling #158
  • (No Category) Refactor Base URL normalization to cover more cases #155

Documentation

  • (No Category) BREAKING: Update schema
  • (No Category) Clarify BASE_URL usage and add more examples #155
  • (No Category) Add scripting on deploy for plausible analytics
  • (No Category) Update screenshot

Features

  • (client) Implement initial refresh count and config control #153
  • (docker) BREAKING: Use debian image as default
  • (youtube) Surface library history playlist and raw recently played for debugging #156
  • (youtube) Sync cookies with those returned from YTM responses #158
  • (youtube) Use full-fat list diffing to watch for new plays #156
  • (No Category) Update normalize-url to prevent port erasure #155

Miscellaneous Tasks

  • (ci) Update setup-node to v4 to squash node deprecation warnings
  • (No Category) Npm audit fixes
  • (No Category) Update dependencies

Refactor

  • (client) Use same init logic as source
  • (config) BREAKING: Move scrobble thresholds to options
  • (config) BREAKING: Move source retry config to options
  • (config) BREAKING: Move remaining common options out of source data and into options
  • (config) BREAKING: Move common options out of client config and into new option property
  • (No Category) Move all init logic into common abstract base class
  • (No Category) Use @foxxmd/get-version to render app version

Ci

  • (No Category) Use checked out repo to get git info rather than GH variables
  • (No Category) Implement gated automated PR building
  • (No Category) Add package cleanup and manual triggers

v0.7.1

What’s New?

Apprise Notification

Support for notifying of scrobbles and errors via Apprise using an apprise-api server. See the docs for configuration.

Disable Web

The API and Dashboard can now be disabled. This can be useful for users who do not want a point of ingress in to MS on insecure networks.

Full Changelog

Documentation

  • (No Category) Add config section and config example for disabling web server #150

Features

  • (mpris) Less noisy error handling
  • (No Category) Implement option for disabling web server #150
  • (No Category) Implement notifications via Apprise

Miscellaneous Tasks

  • (No Category) Remove some unused packages
  • (No Category) Update schema
  • (No Category) Bump version for release

Refactor

  • (logging) Reduce noise for polling interval logging
  • (logging) Balance debug/verbose level logging
  • (No Category) Reduce usage of ErrorWithCause
  • (No Category) Optimize imports
  • (No Category) Use updated logger to reduce log file path logic complexity
  • (No Category) Remove pony-cause dependency

v0.7.0

See the majority of changes in the RC1 release

New Since RC1

  • Updated flatpak appstream metadeta to conform with new guidelines
  • Fixed flatpak build manifest to work with new ESM module configuration

0.6.5

What’s New?

Upstream Recent

Prior to 0.5.0 MS let you see “recently played” directly returned from a Source’s upstream API (for those that have it IE spotify, lastfm, listenbrainz…) This was useful for determining if the Source’s API was “behind” what had actually been played – for instance sometimes Spotify’s “recently played” can be delayed by minutes/hours which could result in backlogging not returning what you “know” was played more recently.

This is entirely a convenience for the user, rather than new functionality for MS, but had been missing as a feature. This release returns this feature to the frontend.

UI Improvements for Source-of-Truth

For some sources (Lastfm, Listenbrainz) MS always uses the recently played data as the source-of-truth for scrobbling to your clients, rather than MS’s “player”. This is due to information returned for “now playing” for these sources being less accurate than recently played data. This has functionally not changed but this discrepancy is now more clearly presented to the user in the UI via a ? tooltip icon.

Google Cast Stability Improvements

I have rewritten parts of the third-party library providing google cast (chromecast) functionality to be more stable and less prone to crashing the entire MS application. Reconnecting events should now be more reliable as well.

Last.fm Timeout Fixes

An issue causing requests to Last.fm to hang forever has been fixed and will now cause the request to timeout in a reasonable amount of time instead of freeze up MS #134

Existing Scrobble checks for non-english characters

A bug causing scrobbles with non-english character-symbols to potentially not match existing scrobbles from client has been fixed. #121

Docker Image Alternatives

An alternative debian-based docker image is now provided for x86/x64 host architectures through a *-debian flavored tag. This image may be used as a workaround if you experience sporadic networking issues with the regular docker images. #126

Full Changelog

Features

  • (chrome) Used improved library
  • (lastfm) Implement nowPlaying lfm api call
  • (source) Implement recent from API
  • (sources) Improve Source of Truth usage and presentation to user #134
  • (No Category) Add debug logging for user api requests
  • (No Category) Improved logging for last.fm api network errors #115
  • (No Category) Implement debian-based image #126

Bug Fixes

  • (frontend) Fix scss division deprecation warnings
  • (lastfm) Patch lfm library to actually implement a request timeout #134
  • (scrobbler) Fix erasing non-english characters #121
  • (No Category) Add patch-package as postinstall script so packages actually get patched

Documentation

  • (No Category) Add workarounds for rollup issues and flatpak disclaimer
  • (No Category) Add debian docker image network workaround to docs #126 #134

Miscellaneous Tasks

  • (No Category) Remove some unused packages
  • (No Category) Ignore apple cert extensions
  • (No Category) Make container image build tags agnostic to default branch name
  • (No Category) Add matrix for building debian flavor tag

v0.6.4

What’s New?

Google Cast Source

Support for Google Cast devices as Sources. This is particularly exciting because music platforms that do not have an API for exposing user Now Playing info (Pandora, Tidal, MixCloud, Soundcloud) can now be monitored if you play them through a Google Cast device. Additionally, since the Cast platform exposes generic Now Playing information virtually any app that plays music through Casting can now be monitored by MS.

Application tooling restructure and frontend platform migration

This is no functional change for end-users. This is an internal/development refactor but brings with it many benefits:

  • Refactored project from cjs to esm (new module standard)
  • Moved away from dead frontend platform (CRA) to Vite
    • Removed dependency on webpack
    • Removed api proxy required by CRA
    • Simplified app entry – Vite is served through express middleware instead of having nodemon spawn separate processes for front/backend
  • Refactored project to use tsx runtime wrapper – no longer need to compile to js to run dev/prod
    • Side-effect of this is stack traces reported in prod now point to actual source files with correct lines numbers

The only visible changes are:

  • a slight increase in docker image size due to bundling typescript/source files
  • developers do not need to use API_PORT anymore – use PORT for both dev/prod now.

Source init improvements

All sources have been refactored to have more granular init stages:

  • build data – any data that needs to be parsed (URLs for mopidy), built, or verified (credentials) happens here
  • test connection – if the source can be checked for reach-ability it is done here
  • test auth – if the source requires auth it is tested here

If any stage fails more descriptive errors are logged for the failure and the stage it failed at is also described, giving users more insight into why a source failed to start as well as improving debugging.

App Crash Logging

App-crashing errors should now be logged before the app crashes. The easiest way to capture these logs is to set file logging to warn log level so they are stored to file. In your file-based config.json`:

{
"logging": {
"level": "debug",
"file": "warn"
}
// ...
}

Deprecations and Future Changes

Maloja

  • Support for Maloja versions below 3.0.0 is now deprecated
    • Likely no one is using these versions as they are almost 2 years old but MS still supports them with additional logic that could (should) be simplified
  • A warning is emitting if Maloja version is below 3.2.0 due to lack of support for scrobbling album information

Spotify Credentials

A future release will include a migration from the current spotify api library to the official spotify web sdk. The information stored for Spotify credentials in releases prior to 0.6.4 is insufficient and will require reauthentication by the user if, for example, the user upgrades directly from 0.6.2 -> 0.6.5+.

0.6.4 will store all required credential information needed for future releases. Simply upgrade to this version and wait a few hours for Spotify credentials to be refreshed.

Full Changelog

Features

  • (chrome) Improve mdns discovery for docker
  • (chrome) Implement user filtering media by type
  • (chrome) Allow manual device connections
  • (chrome) Refactor mdns discovery to run on source heartbeat as well as startup
  • (chrome) Catch buffering media
  • (deezer) Fix credentials check during build data stage
  • (maloja) Improve error handling
  • (spotify) Prepare for future spotify lib migration by writing completing credential data
  • (subsonic) Improve error/response parsing and report errors correctly on startup #129
  • (No Category) Improve discovery for network exceptions in error causes
  • (No Category) Improve data init stage log wording
  • (No Category) Log when heartbeat tasks start

Bug Fixes

  • (No Category) Actually throw auth failure so initialization fails correctly
  • (No Category) Fix isReady logic
  • (No Category) Fix status indicator color based on status text
  • (No Category) Fix status text based on initialization OK values
  • (No Category) Fix return values for source init startup
  • (No Category) Fix when to check connection
  • (No Category) Fix where retries are checked
  • (No Category) Better handling of uncaught exceptions and rejections

Documentation

  • (No Category) Chromecast docs and schema
  • (No Category) Add local source reference to flatpak manifest

Miscellaneous Tasks

  • (chrome) Switch to scoped chromecast-client to fix flatpak source generation limitation
  • (maloja) Deprecate support for versions below 3.0.0

v0.6.3

Changelog

Features

  • (player) Handle state transfer for single-platform sources #124
  • (player) Improved player deletion behavior
  • (scrobbler) Change fuzzy diff threshold to be inclusive
  • (scrobbler) Use play data to extract non-joined track name when comparing for duplicate check
  • (scrobbler) Improve log readability for duplicate checking
  • (scrobblers) Implement user-initiated (re)start mechanism #114
  • (source) Improve (re)start behavior and ui
  • (webscrobbler) Log the best-guess URL for requests using configured slug
  • (No Category) Implement play completion context #121
  • (No Category) Improve track credits parsing to recognize post-feat suffixes #121

Bug Fixes

  • (jellyfin) Split musicbrainz mbid artist identifier semicolon #114
  • (lastfm) Fix handling of non-string mbid string values #114
  • (listenbrainz) Treat 400 responses as non-showstopping #114
  • (mopidy) Fix album artist parsing #110
  • (player) Fix listen range default value
  • (spotify) Undefined player state data when in private session - thanks @brunohpaiva
  • (webscrobbler) Correct ENV names to match those documented #111

Refactor

  • (scrobblers) Consolidate scrobbler client startup surface area
  • (source) Start consolidating isReady behavior
  • (No Category) Improve string comparison robustness
  • (No Category) Move Play time comparison code into own file
  • (No Category) Temporal comparison result data improvements #121

Documentation

  • (webscrobbler) Add where to find connector list #112
  • (webscrobbler) Move slug into data #111
  • (No Category) Update schema for logging enums
  • (No Category) Add contributing guidelines and PR template
  • (No Category) Correct json-schema.app links - thanks @Bujiraso

Miscellaneous Tasks

  • (tests) Fix TS compile warning on test for bad data