[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
0

Configure Feed

Select the types of activity you want to include in your feed.

docs: Lean 100% into docusaurus documentation

Since docs are now generated alongside builds and hosted on the app server there is no longer a barrier to using docusaurus docs as the main documentation presentation. Any user looking for docs can use the GH Pages hosted site or a "versioned" docs site hosted on their MS app. Due to this we can fully commit to docusaurus and take advantage of MDX layouts to simplify docs.

* Replace env/file configs headings in configuration with MDX tabs to make reading easier
* Remove superfluous TOCs
* Replace internal links in repo readme with links to docsite

FoxxMD (Jul 16, 2024, 2:11 PM EDT) ee399136 ab54422a

+1249 -1233
+1 -2
.github/workflows/publishImage.yml
··· 10 10 - '*.*.*' 11 11 # don't trigger if just updating docs 12 12 paths-ignore: 13 - - '**.md' 13 + - 'README.md' 14 14 - '.github/**' 15 - - 'docsite/**' 16 15 - 'flatpak/**' 17 16 # use release instead of tags once version is correctly parsed 18 17 # https://github.com/docker/metadata-action/issues/422
+25 -25
README.md
··· 12 12 A javascript app to scrobble music you listened to, to [Maloja](https://github.com/krateng/maloja), [Last.fm](https://www.last.fm), and [ListenBrainz](https://listenbrainz.org) 13 13 14 14 * Supports scrobbling from many **Sources** 15 - * [Spotify](/docsite/docs/configuration/configuration.md#spotify) 16 - * [Plex](/docsite/docs/configuration/configuration.md#plex) or [Tautulli](/docsite/docs/configuration/configuration.md#tautulli) 17 - * [Subsonic-compatible APIs](/docsite/docs/configuration/configuration.md#subsonic) (like [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/)) 18 - * [Jellyfin](/docsite/docs/configuration/configuration.md#jellyfin) 19 - * [WebScrobbler](/docsite/docs/configuration/configuration.md#webscrobbler) 20 - * [Youtube Music](/docsite/docs/configuration/configuration.md#youtube-music) 21 - * [Last.fm](/docsite/docs/configuration/configuration.md#lastfm-source) 22 - * [ListenBrainz](/docsite/docs/configuration/configuration.md#listenbrainz--source-) 23 - * [Deezer](/docsite/docs/configuration/configuration.md#deezer) 24 - * [MPRIS (Linux Desktop)](/docsite/docs/configuration/configuration.md#mpris) 25 - * [Mopidy](/docsite/docs/configuration/configuration.md#mopidy) 26 - * [JRiver](/docsite/docs/configuration/configuration.md#jriver) 27 - * [Kodi](/docsite/docs/configuration/configuration.md#kodi) 28 - * [Google Cast (Chromecast)](/docsite/docs/configuration/configuration.md#google-cast--chromecast-) 29 - * [Musikcube](/docsite/docs/configuration/configuration.md#muikcube) 15 + * [Spotify](https://foxxmd.github.io/multi-scrobbler/docs/configuration#spotify) 16 + * [Plex](https://foxxmd.github.io/multi-scrobbler/docs/configuration#plex) or [Tautulli](https://foxxmd.github.io/multi-scrobbler/docs/configuration#tautulli) 17 + * [Subsonic-compatible APIs](https://foxxmd.github.io/multi-scrobbler/docs/configuration#subsonic) (like [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/)) 18 + * [Jellyfin](https://foxxmd.github.io/multi-scrobbler/docs/configuration#jellyfin) 19 + * [WebScrobbler](https://foxxmd.github.io/multi-scrobbler/docs/configuration#webscrobbler) 20 + * [Youtube Music](https://foxxmd.github.io/multi-scrobbler/docs/configuration#youtube-music) 21 + * [Last.fm](https://foxxmd.github.io/multi-scrobbler/docs/configuration#lastfm-source) 22 + * [ListenBrainz](https://foxxmd.github.io/multi-scrobbler/docs/configuration#listenbrainz-source) 23 + * [Deezer](https://foxxmd.github.io/multi-scrobbler/docs/configuration#deezer) 24 + * [MPRIS (Linux Desktop)](https://foxxmd.github.io/multi-scrobbler/docs/configuration#mpris) 25 + * [Mopidy](https://foxxmd.github.io/multi-scrobbler/docs/configuration#mopidy) 26 + * [JRiver](https://foxxmd.github.io/multi-scrobbler/docs/configuration#jriver) 27 + * [Kodi](https://foxxmd.github.io/multi-scrobbler/docs/configuration#kodi) 28 + * [Google Cast (Chromecast)](https://foxxmd.github.io/multi-scrobbler/docs/configuration#google-cast-chromecast) 29 + * [Musikcube](https://foxxmd.github.io/multi-scrobbler/docs/configuration#muikcube) 30 30 * Supports scrobbling to many **Clients** 31 - * [Maloja](/docsite/docs/configuration/configuration.md#maloja) 32 - * [Last.fm](/docsite/docs/configuration/configuration.md#lastfm) 33 - * [ListenBrainz](/docsite/docs/configuration/configuration.md#listenbrainz) 34 - * Monitor status of Sources and Clients using [webhooks (Gotify, Ntfy, Apprise)](/docsite/docs/configuration/configuration.md#webhook-configurations) or [healthcheck endpoint](/docsite/docs/configuration/configuration.md#health-endpoint) 31 + * [Maloja](https://foxxmd.github.io/multi-scrobbler/docs/configuration#maloja) 32 + * [Last.fm](https://foxxmd.github.io/multi-scrobbler/docs/configuration#lastfm) 33 + * [ListenBrainz](https://foxxmd.github.io/multi-scrobbler/docs/configuration#listenbrainz) 34 + * Monitor status of Sources and Clients using [webhooks (Gotify, Ntfy, Apprise)](https://foxxmd.github.io/multi-scrobbler/docs/configuration#webhook-configurations) or [healthcheck endpoint](https://foxxmd.github.io/multi-scrobbler/docs/configuration#health-endpoint) 35 35 * Supports configuring for single or multiple users (scrobbling for your friends and family!) 36 36 * Web server interface for stats, basic control, and detailed logs 37 37 * Graceful network and client failure handling (queued scrobbles that auto-retry) 38 38 * Smart handling of credentials (persistent, authorization through app) 39 39 * Easy configuration through ENVs or JSON 40 - * Install using [Docker images for x86/ARM](/docsite/docs/installation/installation.md#docker), [flatpak](/docsite/docs/installation/installation.md#flatpak), or [locally with NodeJS](/docsite/docs/installation/installation.md#nodejs) 40 + * Install using [Docker images for x86/ARM](https://foxxmd.github.io/multi-scrobbler/docs/installation#docker#docker), [flatpak](https://foxxmd.github.io/multi-scrobbler/docs/installation#docker#flatpak), or [locally with NodeJS](https://foxxmd.github.io/multi-scrobbler/docs/installation#docker#nodejs) 41 41 42 42 [**Read The Docs to get started**](https://foxxmd.github.io/multi-scrobbler/docs/installation) 43 43 ··· 52 52 53 53 **But I already scrobble my music to Last.fm/ListenBrainz, is multi-scrobbler for me?** 54 54 55 - Yes! You can use [Last.fm as a **Source**](/docsite/docs/configuration/configuration.md#lastfm-source) or [Listenbrainz as a **Source**](/docsite/docs/configuration/configuration.md#listenbrainz-source) to forward scrobbles from your profile to any other Client! That way you can keep your current scrobble setup as-is but still get the benefit of capturing your data to a self-hosted location. 55 + Yes! You can use [Last.fm as a **Source**](https://foxxmd.github.io/multi-scrobbler/docs/configuration#lastfm-source) or [Listenbrainz as a **Source**](https://foxxmd.github.io/multi-scrobbler/docs/configuration#listenbrainz-source) to forward scrobbles from your profile to any other Client! That way you can keep your current scrobble setup as-is but still get the benefit of capturing your data to a self-hosted location. 56 56 57 57 ## How Does multi-scrobbler (MS) Work? 58 58 ··· 79 79 80 80 ## Installation 81 81 82 - [See the **Installation** documentation](/docsite/docs/installation/installation.md) 82 + [See the **Installation** documentation](https://foxxmd.github.io/multi-scrobbler/docs/installation) 83 83 84 84 ## Configuration 85 85 86 - [See the **Configuration** documentation](/docsite/docs/configuration/configuration.md) 86 + [See the **Configuration** documentation](https://foxxmd.github.io/multi-scrobbler/docs/configuration) 87 87 88 88 ## Usage 89 89 ··· 98 98 99 99 ## Help/FAQ 100 100 101 - Having issues with connections or configuration? Check the [FAQ](/docsite/docs/FAQ.md) before creating an issue! 101 + Having issues with connections or configuration? Check the [FAQ](https://foxxmd.github.io/multi-scrobbler/docs/FAQ) before creating an issue! 102 102 103 103 ## Development 104 104 105 - [Detailed architecture and development guides for Sources/Clients](/docsite/docs/development/dev-common.md) 105 + [Detailed architecture and development guides for Sources/Clients](https://foxxmd.github.io/multi-scrobbler/docs/development/dev-common) 106 106 107 107 ## License 108 108
+1 -1
config/README.md
··· 8 8 9 9 Documentation at 10 10 11 - * [internal docs](../docsite/docs/configuration/configuration.md) 11 + * [internal docs](../docsite/docs/configuration/configuration.mdx) 12 12 * External Link: https://foxxmd.github.io/multi-scrobbler/docs/configuration
+6 -36
docsite/docs/FAQ.md
··· 3 3 toc_max_heading_level: 5 4 4 --- 5 5 6 - <details> 7 - 8 - <summary>Table of Contents</summary> 9 - 10 - <!-- TOC --> 11 - * [Connection Issues](#connection-issues) 12 - * [Plex/Tautulli/Jellyfin/Webscrobbler don't connect](#plextautullijellyfinwebscrobbler-dont-connect) 13 - * [Troubleshooting](#troubleshooting) 14 - * [Turn on Debug Logging](#turn-on-debug-logging) 15 - * [Check Host name and URL](#check-host-name-and-url) 16 - * [Check Firewall and Port Forwarding](#check-firewall-and-port-forwarding) 17 - * [Check Source Service Logs](#check-source-service-logs) 18 - * [Plex](#plex) 19 - * [Tautulli](#tautulli) 20 - * [Jellyfin](#jellyfin) 21 - * [Webscrobbler](#webscrobbler) 22 - * [Jellyfin has warnings about undefined or missing data](#jellyfin-has-warnings-about-undefined-or-missing-data) 23 - * [Jellyfin has warnings about missing headers](#jellyfin-has-warnings-about-missing-headers) 24 - * [Spotify/Deezer/LastFM won't authenticate](#spotifydeezerlastfm-wont-authenticate) 25 - * [Configuration Issues](#configuration-issues) 26 - * [Config could not be parsed](#config-could-not-be-parsed) 27 - * [Scrobbling Issues](#scrobbling-issues) 28 - * [Last.fm does not scrobble tracks with multiple artists correctly](#lastfm-does-not-scrobble-tracks-with-multiple-artists-correctly) 29 - * [Jellyfin does not scrobble tracks with multiple artists correctly](#jellyfin-does-not-scrobble-tracks-with-multiple-artists-correctly) 30 - * [Google Cast track information is missing/incorrect or MS player has weird times](#google-cast-track-information-is-missingincorrect-or-ms-player-has-weird-times) 31 - * [Google Cast device does not track media](#google-cast-device-does-not-track-media) 32 - <!-- TOC --> 33 - 34 - </details> 35 - 36 6 ## Connection Issues 37 7 38 8 ### Plex/Tautulli/Jellyfin/Webscrobbler don't connect ··· 69 39 70 40 ##### Check Host name and URL 71 41 72 - The URLs examples in the [configuration](configuration/configuration.md) documentation assume you are running Plex/Tautulli/Jellyfin/Webscrobbler on the same server as multi-scrobbler. If these are not the same machine then you need to determine the IP address or domain name that multi-scrobbler is reachable at and use that instead of `localhost` when configuring these sources. **This is likely the same host name that you would use to access the web interface for multi-scrobbler.** 42 + The URLs examples in the [configuration](configuration/configuration.mdx) documentation assume you are running Plex/Tautulli/Jellyfin/Webscrobbler on the same server as multi-scrobbler. If these are not the same machine then you need to determine the IP address or domain name that multi-scrobbler is reachable at and use that instead of `localhost` when configuring these sources. **This is likely the same host name that you would use to access the web interface for multi-scrobbler.** 73 43 74 44 EX `http://localhost:9078/plex` -> `http://192.168.0.140:9078/plex` 75 45 ··· 100 70 ### Jellyfin has warnings about undefined or missing data 101 71 102 72 Make sure you have 103 - * [Configured the webhook plugin correctly](configuration/configuration.md#jellyfin) 73 + * [Configured the webhook plugin correctly](configuration/configuration.mdx#jellyfin) 104 74 * Checked the **Send All Properties(ignores template)** option in the webhook settings and **Saved** 105 75 106 76 multi-scrobbler is known to work on Jellyfin `10.8.9` with Webhook version `11.0.0.0`. ··· 135 105 A workaround that may fix this: 136 106 137 107 * In Webhook settings: 138 - * [In the webhook you have already configured...](configuration/configuration.md#jellyfin) 108 + * [In the webhook you have already configured...](configuration/configuration.mdx#jellyfin) 139 109 * Add Request Header... 140 110 * **Key:** `Content-Type` 141 111 * **Value:** `application/json` ··· 184 154 185 155 The Google Cast integration relies on a few common fields in the data it receives from your casting device. Every platform that can cast (Spotify, Pandora, etc...) *should* use these fields the same but there are slight differences between their implementations that may confuse multi-scrobbler. Specific platforms may also return more information in non-common fields that are undocumented. 186 156 187 - To diagnose these issues you [**must enable payload logging**](configuration/configuration.md#cast-troubleshooting) for your google cast Source, run MS, and then include logs with this output from that run. Without the raw data logged from your cast device it will be nearly impossible to resolve your issue. 157 + To diagnose these issues you [**must enable payload logging**](configuration/configuration.mdx#cast-troubleshooting) for your google cast Source, run MS, and then include logs with this output from that run. Without the raw data logged from your cast device it will be nearly impossible to resolve your issue. 188 158 189 159 ### Google Cast device does not track media 190 160 ··· 196 166 My Artist - Example Track has 'unknown' media type and allowUnknownMedia=false, will not track 197 167 ``` 198 168 199 - Refer to [Allow Unknown Media Type](configuration/configuration.md#allow-unknown-media-type) section to fix this 169 + Refer to [Allow Unknown Media Type](configuration/configuration.mdx#allow-unknown-media-type) section to fix this 200 170 201 171 ``` 202 172 My Artist - Example Track has 'movie' media type so will not track 203 173 ``` 204 174 205 - Refer to [Force Media Tracking](configuration/configuration.md#forcing-media-tracking) section to fix this 175 + Refer to [Force Media Tracking](configuration/configuration.mdx#forcing-media-tracking) section to fix this
-1113
docsite/docs/configuration/configuration.md
··· 1 - --- 2 - sidebar_position: 2 3 - title: Overview 4 - toc_max_heading_level: 3 5 - --- 6 - 7 - # Configuration 8 - 9 - <details> 10 - 11 - <summary>Table of Contents</summary> 12 - 13 - <!-- TOC --> 14 - * [Overview](#overview) 15 - * [ENV-Based Configuration](#env-based-configuration) 16 - * [File-Based Configuration](#file-based-configuration) 17 - * [All-in-One File Configuration](#all-in-one-file-configuration) 18 - * [Specific File Configuration](#specific-file-configuration) 19 - * [Application Options](#application-options) 20 - * [Base URL](#base-url) 21 - * [Source Configurations](#source-configurations) 22 - * [Spotify](#spotify) 23 - * [Plex](#plex) 24 - * [Tautulli](#tautulli) 25 - * [Subsonic](#subsonic) 26 - * [Jellyfin](#jellyfin) 27 - * [Last.fm (Source)](#lastfm-source) 28 - * [Listenbrainz (Source)](#listenbrainz-source) 29 - * [Deezer](#deezer) 30 - * [Youtube Music](#youtube-music) 31 - * [MPRIS](#mpris) 32 - * [Mopidy](#mopidy) 33 - * [JRiver](#jriver) 34 - * [Kodi](#kodi) 35 - * [WebScrobbler](#webscrobbler) 36 - * [Multiple Users](#multiple-users) 37 - * [Google Cast (Chromecast)](#google-cast-chromecast) 38 - * [Connecting Devices](#connecting-devices) 39 - * [What Media Does MS Scrobble?](#what-media-does-ms-scrobble) 40 - * [Cast Troubleshooting](#cast-troubleshooting) 41 - * [Musikcube](#musikcube) 42 - * [Client Configurations](#client-configurations) 43 - * [Maloja](#maloja) 44 - * [Last.fm](#lastfm) 45 - * [Listenbrainz](#listenbrainz) 46 - * [Monitoring](#monitoring) 47 - * [Webhook Configurations](#webhook-configurations) 48 - * [Gotify](#gotify) 49 - * [Ntfy](#ntfy) 50 - * [Health Endpoint](#health-endpoint) 51 - <!-- TOC --> 52 - 53 - </details> 54 - 55 - ## Overview 56 - 57 - [**Sources** and **Clients**](/#how-does-multi-scrobbler-ms-work) are configured using environmental (ENV) variables and/or json files. 58 - 59 - **MS will parse configuration from both configuration types.** You can mix and match configurations but it is generally better to stick to one or the other. 60 - 61 - TIP: Check the [**FAQ**](../FAQ.md) if you have any issues after configuration! 62 - 63 - ### ENV-Based Configuration 64 - 65 - This is done by passing environmental variables and so does not require any files to run MS. 66 - 67 - * Using a docker container EX `docker run -e "SPOTIFY_CLIENT_ID=yourId" -e "SPOTIFY_CLIENT_SECRET=yourSecret" ...` 68 - * Using a local installations by exporting variables before running MS EX `SPOTIFY_CLIENT_ID=yourId SPOTIFY_CLIENT_SECRET=yourSecret node index.js` 69 - 70 - Use ENV-based configuration if: 71 - 72 - * You are the only person for whom MS is scrobbling for 73 - * You have a very simple setup for MS such as one scrobble [Client](/#client) and one [Source](/#source) IE Plex -> Maloja 74 - 75 - ### File-Based Configuration 76 - 77 - MS will parse configuration files located in the directory specified by the `CONFIG_DIR` environmental variable. This variable defaults to: 78 - 79 - * Local installation -> `PROJECT_DIR/config` 80 - * Docker -> `/config` (in the container) -- see the [install docs](../installation/installation.md#docker) for how to configure this correctly 81 - 82 - Use File-based configuration if: 83 - 84 - * You have many [Sources](/#source) 85 - * You have many of each type of **Source** you want to scrobble from IE 2x Plex accounts, 3x Spotify accounts, 1x 86 - Funkwhale... 87 - * You have more than one scrobble **Client** you want to scrobble to IE multiple Maloja servers 88 - * You want only some **Sources** to scrobble to some **Clients** IE Fred's Spotify account scrobbles to Fred's Maloja 89 - server, but not Mary's Maloja server 90 - 91 - File-based configurations located in the `CONFIG_DIR` directory can be parsed from 92 - 93 - * an **all-in-one** config file named `config.json` that contains information for all Sources and Clients and/or 94 - * many **specific** files named based on the client/source to configure IE `plex.json` `spotify.json` 95 - 96 - There are **example configurations** for all Source/Client types and AIO config located in the [/config](https://github.com/FoxxMD/multi-scrobbler/tree/master/config) directory of this project. These can be used as-is by renaming them to `.json`. 97 - For docker installations these examples are copied to your configuration directory on first-time use. 98 - 99 - There is also a [**kitchensink example**](kitchensink.md) that provides examples of using all sources/clients in a complex configuration. 100 - 101 - #### All-in-One File Configuration 102 - 103 - [**Explore the schema for this configuration, along with an example generator and validator, here**](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 104 - 105 - Example directory structure: 106 - 107 - ``` 108 - /CONFIG_DIR 109 - config.json 110 - ``` 111 - 112 - <details> 113 - <summary>Config Example</summary> 114 - 115 - ```json5 title="config.json" 116 - { 117 - //... 118 - "sources": [ 119 - { 120 - "name": "myConfig", 121 - "type": "spotify", 122 - "clients": [ 123 - "myMalojaClient" 124 - ], 125 - "data": { 126 - "clientId": "anExample" 127 - //... 128 - } 129 - } 130 - ], 131 - "clients": [ 132 - { 133 - "name": "myFirstMalojaClient", 134 - "type": "maloja", 135 - "data": { 136 - "url": "http://myMalojaServer.example", 137 - // ... 138 - } 139 - } 140 - ] 141 - } 142 - ``` 143 - 144 - </details> 145 - 146 - `config.json` can also be used to set default behavior for all sources/clients using `sourceDefaults` and `clientDefaults` properties. 147 - 148 - See [config.json.example](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/config.json.example) for an annotated example or check out [the kitchen sink example](kitchensink.md). 149 - 150 - #### Specific File Configuration 151 - 152 - Each file is named by the **type** of the Client/Source found in below sections. Each file as an **array** of that type of Client/Source. 153 - 154 - Example directory structure: 155 - 156 - ``` 157 - /CONFIG_DIR 158 - plex.json 159 - spotify.json 160 - maloja.json 161 - ``` 162 - 163 - <details> 164 - <summary>Config Example</summary> 165 - 166 - ```json5 167 - // in maloja.json 168 - [ 169 - { 170 - "name": "myFirstMalojaClient", 171 - "data": { 172 - "url": "http://myMalojaServer.example", 173 - "apiKey": "myKey" 174 - } 175 - }, 176 - { 177 - "name": "mySecondMalojaClient", 178 - "data": { 179 - "url": "http://my2ndMalojaServer.example", 180 - "apiKey": "myKey" 181 - } 182 - } 183 - ] 184 - 185 - ``` 186 - 187 - </details> 188 - 189 - See the [/config](https://github.com/FoxxMD/multi-scrobbler/blob/master/config) directory of this project for examples of each type of config file or reference specific files below. 190 - 191 - ## Application Options 192 - 193 - These options affect multi-scrobbler's behavior and are not specific to any source/client. 194 - 195 - #### Base URL 196 - 197 - Defines the URL that is used to generate default redirect URLs for authentication on [spotify](#spotify), [lastfm](#lastfm), and [deezer](#deezer) -- as well as some logging hints. 198 - 199 - * Default => `http://localhost:9078` 200 - * Set with [ENV](#env-based-configuration) `BASE_URL` or `baseUrl` [all-in-one configuration](#all-in-one-file-configuration) 201 - * If protocol is `http` or no protocol is specified MS will try to use port `9078` -- to override this explicitly set the port or use `https` 202 - 203 - EX Lastfm Redirect Url is `BASE_URL:PORT/lastfm/callback` (when no other redirectUri is specified for [lastfm configuration](#lastfm)) 204 - 205 - * `BASE_URL=192.168.0.101` => Redirect URL is `http://192.168.0.101:9078/lastfm/callback` 206 - * `BASE_URL=http://my.domain.local` => Redirect URL is `http://my.domain.local:9078/lastfm/callback` 207 - * `BASE_URL=http://192.168.0.101/my/subfolder` => Redirect URL is `http://192.168.0.101:9078/my/subfolder/lastfm/callback` 208 - 209 - * `BASE_URL=my.domain.local:80` => Redirect URL is `http://my.domain.local:80/lastfm/callback` 210 - * `BASE_URL=my.domain.local:9000` => Redirect URL is `http://my.domain.local:9000/lastfm/callback` 211 - * `BASE_URL=192.168.0.101:4000/my/subfolder` => Redirect URL is `http://192.168.0.101:4000/my/subfolder/lastfm/callback` 212 - * `BASE_URL=https://192.168.0.101` => Redirect URL is `https://192.168.0.101:443/lastfm/callback` 213 - 214 - 215 - Useful when running with [docker](../installation/installation.md#docker) so that you do not need to specify redirect URLs for each configuration. 216 - 217 - #### Disable Web 218 - 219 - If you do not need the dashboard and/or ingress sources, or have security concerns about ingress and cannot control their hosting environment, the web server and API can be disabled. 220 - 221 - :::warning 222 - 223 - Any **ingress-based sources will be unusable** (Plex, Jellyfin, Tautulli, etc...) if this is disabled. 224 - 225 - :::: 226 - 227 - Disable using either: 228 - 229 - * ENV `DISABLE_WEB=true` 230 - * In [All-in-One File](#all-in-one-file-configuration) use the top-level property `"disableWeb": true` 231 - 232 - ## Source Configurations 233 - 234 - ### [Spotify](https://www.spotify.com) 235 - 236 - To access your Spotify history you must [register an application](https://developer.spotify.com/dashboard) to get a 237 - Client ID/Secret. Make sure to also whitelist your redirect URI in the application settings. 238 - 239 - :::note 240 - 241 - If your Spotify player has [Automix](https://community.spotify.com/t5/FAQs/What-is-Automix/ta-p/5257278) enabled and Spotify uses it for your playlist/queue then MS cannot accurately determine when a track will end. This is because the track is "mixed" in your queue with a shorter play time than its actual length and [Spotify does not report this modified play time in its API.](https://community.spotify.com/t5/Spotify-for-Developers/Wrong-duration-ms-of-track-with-Automix/m-p/5429147) This **does not affect MS's ability to scrobble** from Spotify but it will affect the accuracy of the duration MS reports was played. 242 - 243 - :::: 244 - 245 - #### ENV-Based 246 - 247 - | Environmental Variable | Required? | Default | Description | 248 - |----------------------------|-----------|----------------------------------|----------------------------------------------------| 249 - | `SPOTIFY_CLIENT_ID` | Yes | | | 250 - | `SPOTIFY_CLIENT_SECRET` | Yes | | | 251 - | `SPOTIFY_REDIRECT_URI` | No | `http://localhost:9078/callback` | URI must end in `callback` | 252 - 253 - #### File-Based 254 - 255 - See [`spotify.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/spotify.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSpotifySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 256 - 257 - ### [Plex](https://plex.tv) 258 - 259 - Check the [instructions](plex.md) on how to setup a [webhooks](https://support.plex.tv/articles/115002267687-webhooks) to scrobble your plays. 260 - 261 - #### ENV-Based 262 - 263 - | Environmental Variable | Required | Default | Description | 264 - |------------------------|----------|---------|-------------------------------------------------| 265 - | `PLEX_USER` | No | | The a comma-delimited list of usernames to scrobble tracks for. No usernames specified means all tracks by all users will be scrobbled. | 266 - 267 - #### File-Based 268 - 269 - See [`plex.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/plex.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FPlexSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 270 - 271 - ### [Tautulli](https://tautulli.com) 272 - 273 - Check the [instructions](plex.md) on how to setup a notification agent. 274 - 275 - #### ENV-Based 276 - 277 - | Environmental Variable | Required | Default | Description | 278 - |------------------------|----------|---------|-------------------------------------------------| 279 - | `TAUTULLI_USER` | No | | The a comma-delimited list of usernames to scrobble tracks for. No usernames specified means all tracks by all users will be scrobbled. | 280 - 281 - ####File-Based 282 - 283 - See [`tautulli.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/tautulli.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FTautulliSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 284 - 285 - ### [Subsonic](http://www.subsonic.org/) 286 - 287 - Can use this source for any application that implements the [Subsonic API](http://www.subsonic.org/pages/api.jsp) and supports the [`getNowPlaying`](http://www.subsonic.org/pages/api.jsp#getNowPlaying) endpoint (such as [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/)) 288 - 289 - **Known Issues:** 290 - * "Time played at" is somewhat inaccurate since the api only reports "played X minutes ago" so... 291 - * All scrobble times are therefore "on the minute" and you may experience occasional duplicate scrobbles 292 - * "played X minutes ago" sometimes is also not reported correctly 293 - * Multiple artists are reported as one value and cannot be separated 294 - * If using [Airsonic Advanced](https://github.com/airsonic-advanced/airsonic-advanced) the password used (under **Credentials**) must be **Decodable** 295 - 296 - #### ENV-Based 297 - 298 - | Environmental Variable | Required? | Default | Description | 299 - |----------------------------|-----------|----------------------------------|----------------------------------------------------| 300 - | `SUBSONIC_USER` | Yes | | | 301 - | `SUBSONIC_PASSWORD` | Yes | | | 302 - | `SUBSONIC_URL` | Yes | | Base url of your subsonic-api server | 303 - 304 - #### File-Based 305 - 306 - See [`subsonic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/subsonic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubSonicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 307 - 308 - ### [Jellyfin](https://jellyfin.org/) 309 - 310 - Must be using Jellyfin 10.7 or greater 311 - 312 - * In the Jellyfin desktop web UI Navigate to -> Administration -> Dashboard -> Plugins -> Catalog 313 - * Under Notifications -> **Webhook** -> Install, then restart your server 314 - * Navigate back to -> Administration -> Dashboard -> Plugins -> My Plugins -> Webhook 315 - * Click "..." -> Settings 316 - * In Webhook settings: 317 - * `Add Generic Destination` 318 - * In the new `Generic` dropdown: 319 - * Webhook Url: `http://localhost:9078/jellyfin` 320 - * Notification Type: `Playback Progress` 321 - * Item Type: `Songs` 322 - * Check `Send All Properties` 323 - * Save 324 - 325 - :::note 326 - 327 - If you see errors in the MS logs regarding `missing headers` when using Jellyfin [see this workaround.](../FAQ.md#jellyfin-has-warnings-about-missing-headers) 328 - 329 - :::: 330 - 331 - #### ENV-Based 332 - 333 - | Environmental Variable | Required? | Default | Description | 334 - |------------------------|-----------|---------|-------------------------------------------------------------------| 335 - | `JELLYFIN_USER` | | | Comma-separated list of usernames (from Jellyfin) to scrobble for | 336 - | `JELLYFIN_SERVER` | | | Comma-separated list of Jellyfin server names to scrobble from | 337 - 338 - #### File-Based 339 - 340 - See [`jellyfin.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jellyfin.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FJellySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 341 - 342 - ### [Last.fm (Source)](https://www.last.fm) 343 - 344 - See the [Last.fm (Client)](#lastfm) setup for registration instructions. 345 - 346 - #### ENV-Based 347 - 348 - No support for ENV based for Last.fm as a client (only source) 349 - 350 - #### File-Based 351 - 352 - See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example), change `configureAs` to `source`. Or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 353 - 354 - ### [Listenbrainz (Source)](https://listenbrainz.org) 355 - 356 - You will need to run your own Listenbrainz server or have an account [on the official instance](https://listenbrainz.org/login/) 357 - 358 - On your [profile page](https://listenbrainz.org/profile/) find your **User Token** to use in the configuration. 359 - 360 - :::note 361 - 362 - You cannot use ENV variables shown in the [Listenbrainz Client config](#listenbrainz) -- multi-scrobbler assumes Listenbrainz ENVs are always used for the **client** configuration. You must use the file-based config from below to setup Listenbrainz as a Source. 363 - 364 - :::: 365 - 366 - #### File-Based 367 - 368 - See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 369 - 370 - **Change `configureAs` to `source`** 371 - 372 - ### [Deezer](https://deezer.com/) 373 - 374 - Create a new application at [Deezer Developers](https://developers.deezer.com/myapps) 375 - 376 - * Application Domain must be the same as your multi-scrobbler domain. Default is `localhost:9078` 377 - * Redirect URL must end in `deezer/callback` 378 - * Default would be `http://localhost:9078/deezer/callback` 379 - 380 - After application creation you should have credentials displayed in the "My Apps" dashboard. You will need: 381 - 382 - * **Application ID** 383 - * **Secret Key** 384 - * **Redirect URL** (if not the default) 385 - 386 - **If no access token is provided...** 387 - 388 - After starting multi-scrobbler with credentials in-place open the dashboard (`http://localhost:9078`) and find your Deezer source. Click **(Re)authenticate and (re)start polling** to start the login process. After login is complete polling will begin automatically. 389 - 390 - #### ENV-Based 391 - 392 - | Environmental Variable | Required? | Default | Description | 393 - |----------------------------|-----------|-----------------------------------------|----------------------------------------------------| 394 - | `DEEZER_CLIENT_ID` | Yes | | Your **Application ID** | 395 - | `DEEZER_CLIENT_SECRET` | Yes | | Your **Secret Key** | 396 - | `DEEZER_REDIRECT_URI` | No | `http://localhost:9078/deezer/callback` | URI must end in `deezer/callback` | 397 - 398 - #### File-Based 399 - 400 - See [`deezer.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/deezer.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FDeezerSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 401 - 402 - ### [Youtube Music](https://music.youtube.com) 403 - 404 - :::note 405 - 406 - * YT Music authentication is "browser based" which means your credentials may expire after a (long?) period of time OR if you log out of https://music.youtube.com. In the event this happens just repeat the steps below to get new credentials. 407 - * Communication to YT Music is **unofficial** and not supported or endorsed by Google. This means that **this integration may stop working at any time** if Google decides to change how YT Music works in the browser. 408 - 409 - :::: 410 - 411 - Credentials for YT Music are obtained from a browser request to https://music.youtube.com **once you are logged in.** [Specific requirements are here and summarized below:](https://github.com/nickp10/youtube-music-ts-api/blob/master/DOCUMENTATION.md#authenticate) 412 - 413 - * Open a new tab 414 - * Open the developer tools (Ctrl-Shift-I) and select the “Network” tab 415 - * Go to https://music.youtube.com and ensure you are logged in 416 - 417 - Then... 418 - 419 - 1. Find and select an authenticated POST request. The simplest way is to filter by /browse using the search bar of the developer tools. If you don’t see the request, try scrolling down a bit or clicking on the library button in the top bar. 420 - 2. **Make sure **Headers** pane is selected and open 421 - 3. In the **Request Headers** section find and copy the **entire value** found after `Cookie:` and use this as the `cookie` value in your multi-scrobbler config 422 - 4. If present, in the **Request Headers** section find and copy the number found in `X-google-AuthUser` and use this as the value for `authUser` in your multi-scrobbler config 423 - 424 - ![Google Headers](google-header.jpg) 425 - 426 - 427 - #### File-Based 428 - 429 - See [`ytmusic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/ytmusic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FYTMusicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 430 - 431 - ### [MPRIS](https://specifications.freedesktop.org/mpris-spec/latest/) 432 - 433 - MPRIS is a standard interface for communicating with Music Players on **linux operating systems.** 434 - 435 - If you run Linux and have a notification tray that shows what media you are listening to, you likely have access to MPRIS. 436 - 437 - ![Notification Tray](mpris.jpg) 438 - 439 - multi-scrobbler can listen to this interface and scrobble tracks played by **any media player** that communicates to the operating system with MPRIS. 440 - 441 - :::note 442 - 443 - multi-scrobbler needs to be running as a [**Local Installation**](../installation/installation.md#nodejs) in order to use MPRIS. This cannot be used from docker. 444 - 445 - :::: 446 - 447 - #### ENV-Based 448 - 449 - | Environmental Variable | Required? | Default | Description | 450 - |------------------------|-----------|---------|----------------------------------------------------------------------------------| 451 - | MPRIS_ENABLE | No | | Use MPRIS as a Source (useful when you don't need any other options) | 452 - | MPRIS_BLACKLIST | No | | Comma-delimited list of player names not to scrobble from | 453 - | MPRIS_WHITELIST | No | | Comma-delimited list of players names to ONLY scrobble from. Overrides blacklist | 454 - 455 - #### File-Based 456 - 457 - See [`mpris.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mpris.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMPRISSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 458 - 459 - ### [Mopidy](https://mopidy.com/) 460 - 461 - Mopidy is a headless music server that supports playing music from many [standard and non-standard sources such as Pandora, Bandcamp, and Tunein.](https://mopidy.com/ext/) 462 - 463 - multi-scrobbler can scrobble tracks played from any Mopidy backend source, regardless of where you listen to them. 464 - 465 - #### File-Based 466 - 467 - See [`mopidy.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mopidy.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMopidySourceConfig/%23%2Fdefinitions%2FMopidyData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 468 - 469 - Configuration Options: 470 - 471 - ###### `url` 472 - 473 - The URL used to connect to the Mopidy server. You MUST have [Mopidy-HTTP extension](https://mopidy.com/ext/http) enabled. 474 - 475 - If no `url` is provided a default is used which assumes Mopidy is installed on the same server as multi-scrobbler: `ws://localhost:6680/mopidy/ws/` 476 - 477 - Make sure the hostname and port number match what is found in the Mopidy configuration file `mopidy.conf`: 478 - 479 - ``` 480 - ... 481 - 482 - [http] 483 - hostname = localhost 484 - port = 6680 485 - 486 - ... 487 - ``` 488 - 489 - The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 490 - If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 491 - 492 - Part => Default Value 493 - 494 - * Protocol => `ws://` 495 - * Hostname => `localhost` 496 - * Port => `6680` 497 - * Path => `/mopidy/ws/` 498 - 499 - <details> 500 - <summary>URL Transform Examples</summary> 501 - 502 - ```json 503 - { 504 - "url": "mopidy.mydomain.com" 505 - } 506 - ``` 507 - 508 - MS transforms this to: `ws://mopidy.mydomain.com:6680/mopidy/ws/` 509 - 510 - ```json 511 - { 512 - "url": "192.168.0.101:3456" 513 - } 514 - ``` 515 - 516 - MS transforms this to: `ws://192.168.0.101:3456/mopidy/ws/` 517 - 518 - ```json 519 - { 520 - "url": "mopidy.mydomain.com:80/MOPWS" 521 - } 522 - ``` 523 - 524 - MS transforms this to: `ws://mopidy.mydomain.com:80/MOPWS` 525 - 526 - </details> 527 - 528 - 529 - ##### URI Blacklist/Whitelist 530 - 531 - If you wish to disallow or only allow scrobbling from some sources played through Mopidy you can specify these using `uriBlacklist` or `uriWhitelist` in your config. multi-scrobbler will check the list to see if any string matches the START of the `uri` on a track. If whitelist is used then blacklist is ignored. All strings are case-insensitive. 532 - 533 - EX: 534 - 535 - ```json 536 - { 537 - "uriBlacklist": ["soundcloud"] 538 - } 539 - ``` 540 - 541 - Will prevent multi-scrobbler from scrobbling any Mopidy track that start with a `uri` like `soundcloud:song:MySong-1234` 542 - 543 - ##### Album Blacklist 544 - 545 - For certain sources (Soundcloud) Mopidy does not have all track info (Album) and will instead use "Soundcloud" as the Album name. You can prevent multi-scrobbler from using this bad Album data by adding the fake Album name to this list. Multi-scrobbler will still scrobble the track, just without the bad data. All strings are case-insensitive. 546 - 547 - EX: 548 - 549 - ```json 550 - { 551 - "albumBlacklist": ["SoundCloud", "Mixcloud"] 552 - } 553 - ``` 554 - 555 - If a track would be scrobbled like `Album: Soundcloud, Track: My Cool Track, Artist: A Cool Artist` 556 - then multi-scrobbler will instead scrobble `Track: My Cool Track, Artist: A Cool Artist` 557 - 558 - ### [JRiver](https://jriver.com/) 559 - 560 - In order for multi-scrobbler to communicate with JRiver you must have [Web Server Interface](https://wiki.jriver.com/index.php/Web_Service_Interface#Documentation_of_Functions) enabled. This can can be in the JRiver GUI: 561 - 562 - * Tools -> Options -> Media Network 563 - * Check `Use Media Network to share this library...` 564 - * If you have `Authentication` checked you will need to provide the **Username** and **Password** in the ENV/File configuration below. 565 - 566 - ##### URL 567 - 568 - If you do not provide a URL then a default is used which assumes JRiver is installed on the same server as multi-scrobbler: `http://localhost:52199/MCWS/v1/` 569 - 570 - * Make sure the port number matches what is found in `Advanced` section in the [Media Network](#jriver) options. 571 - * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 572 - 573 - The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 574 - If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 575 - 576 - Part => Default Value 577 - 578 - * Protocol => `http://` 579 - * Hostname => `localhost` 580 - * Port => `52199` 581 - * Path => `/MCWS/v1/` 582 - 583 - <details> 584 - <summary>URL Transform Examples</summary> 585 - 586 - ```json 587 - { 588 - "url": "jriver.mydomain.com" 589 - } 590 - ``` 591 - 592 - MS transforms this to: `http://jriver.mydomain.com:52199/MCWS/v1/` 593 - 594 - ```json 595 - { 596 - "url": "192.168.0.101:3456" 597 - } 598 - ``` 599 - 600 - MS transforms this to: `http://192.168.0.101:3456/MCWS/v1/` 601 - 602 - ```json 603 - { 604 - "url": "mydomain.com:80/jriverReverse/MCWS/v1/" 605 - } 606 - ``` 607 - 608 - MS transforms this to: `http://mydomain.com:80/jriverReverse/MCWS/v1/` 609 - 610 - </details> 611 - 612 - #### ENV-Based 613 - 614 - 615 - | Environmental Variable | Required | Default | Description | 616 - |------------------------|----------|---------------------------------|------------------------------------------------| 617 - | JRIVER_URL | Yes | http://localhost:52199/MCWS/v1/ | The URL of the JRiver server | 618 - | JRIVER_USERNAME | No | | If authentication is enabled, the username set | 619 - | JRIVER_PASSWORD | No | | If authenticated is enabled, the password set | 620 - 621 - 622 - #### File-Based 623 - 624 - See [`jriver.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jriver.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FJRiverSourceConfig/%23%2Fdefinitions%2FJRiverData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 625 - 626 - ### [Kodi](https://kodi.tv/) 627 - 628 - In order for multi-scrobbler to communicate with Kodi you must have the [Web Interface](https://kodi.wiki/view/Web_interface) enabled. This can can be in the Kodi GUI: 629 - 630 - * Settings -> Services -> Control 631 - * Check `Allow remote control via HTTP` 632 - * Ensure you have a **Username** and **Password** set, you will need to provide them in the ENV/File configuration below. 633 - 634 - ##### URL 635 - 636 - If you do not provide a URL then a default is used which assumes Kodi is installed on the same server as multi-scrobbler: `http://localhost:8080/jsonrpc` 637 - 638 - * Make sure the port number matches what is found in **Port** in the [Control](#kodi) section mentioned above. 639 - * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 640 - 641 - The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 642 - If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 643 - 644 - Part => Default Value 645 - 646 - * Protocol => `http://` 647 - * Hostname => `localhost` 648 - * Port => `8080` 649 - * Path => `/jsonrpc` 650 - 651 - <details> 652 - <summary>URL Transform Examples</summary> 653 - 654 - ```json 655 - { 656 - "url": "kodi.mydomain.com" 657 - } 658 - ``` 659 - 660 - MS transforms this to: `http://kodi.mydomain.com:8080/jsonrpc` 661 - 662 - ```json 663 - { 664 - "url": "192.168.0.101:3456" 665 - } 666 - ``` 667 - 668 - MS transforms this to: `http://192.168.0.101:3456/jsonprc` 669 - 670 - ```json 671 - { 672 - "url": "mydomain.com:80/kodiReverse/jsonrpc" 673 - } 674 - ``` 675 - 676 - MS transforms this to: `http://mydomain.com:80/kodiReverse/jsonrpc` 677 - 678 - </details> 679 - 680 - #### ENV-Based 681 - 682 - 683 - | Environmental Variable | Required | Default | Description | 684 - |------------------------|----------|-------------------------------|----------------------------| 685 - | KODI_URL | Yes | http://localhost:8080/jsonrpc | The URL of the Kodi server | 686 - | KODI_USERNAME | No | | The username set | 687 - | KODI_PASSWORD | No | | The password set | 688 - 689 - 690 - #### File-Based 691 - 692 - See [`kodi.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/kodi.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FKodiSourceConfig/%23%2Fdefinitions%2FKodiData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 693 - 694 - ### [WebScrobbler](https://web-scrobbler.com/) 695 - 696 - After installing the extension open the preferences/settings for it: 697 - 698 - * Under **Accounts** 699 - * **Add Webhook** 700 - * API URL: `http://localhost:9078/api/webscrobbler` 701 - * Application name: `(whatever you want)` 702 - 703 - Reload the extension after adding the webhook. 704 - 705 - * **On Firefox** - Only FQNs (domain.tld), `localhost`, and `127.0.0.1` are supported for API URL due to [firefox requiring https](https://github.com/web-scrobbler/web-scrobbler/issues/4183#issuecomment-1749222006) 706 - * **On Chromium-based Browsers** - Any domain will work for API URL 707 - * All Other browsers are untested 708 - 709 - ##### Multiple Users 710 - 711 - If you would like use multiple WebScrobbler sources they can be matched using a **slug** at the end of the **API URL.** This requires using [a file-based config.](#file-based-configuration) 712 - 713 - Example: 714 - 715 - In `webscrobbler.json` 716 - 717 - ```json 718 - [ 719 - { 720 - "name": "aUserWS", 721 - "clients": [ 722 - "client1Maloja" 723 - ], 724 - "data": { 725 - "slug": "usera" 726 - } 727 - }, 728 - { 729 - "name": "bUserWS", 730 - "clients": [ 731 - "client2Maloja" 732 - ], 733 - "data": { 734 - "slug": "userb" 735 - } 736 - } 737 - ] 738 - ``` 739 - 740 - * To use `aUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/usera` 741 - * To use `bUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/userb` 742 - 743 - :::note 744 - 745 - `http://localhost:9078/api/webscrobbler` is matched with the first source that _that does not have a slug defined._ 746 - 747 - :::: 748 - 749 - ###### Connectors Black/Whitelist 750 - 751 - MS can be configured to only scrobble, or NOT scrobble, from some WS connectors. Use the name of the website from the [supported websites](https://web-scrobbler.com/) or from the **Connectors** tab in the extension. 752 - 753 - :::note 754 - 755 - This affects **only** MS's behavior and does not affect the general connector behavior you have configured within the WebScrobbler extension. 756 - 757 - :::: 758 - 759 - #### ENV-Based 760 - 761 - | Environmental Variable | Required? | Default | Description | 762 - |------------------------|-----------|---------|--------------------------------------------------------------------------| 763 - | WS_ENABLE | No | | Set to 'true' to enable WS without needing to define other ENVs | 764 - | WS_WHITELIST | No | | Only scrobble from these WebScrobbler Connectors. Comma-delimited list | 765 - | WS_BLACKLIST | No | | Do not scrobble from these WebScrobbler Connectors. Comma-delimited list | 766 - 767 - #### File-Based 768 - 769 - See [`webscrobbler.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/webscrobbler.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FWebScrobblerSourceConfig/%23%2Fdefinitions%2FWebScrobblerData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 770 - 771 - ### [Google Cast (Chromecast)](https://www.google.com/chromecast/built-in/) 772 - 773 - If your media device can be **Cast** to using this button ![Chromecast Icon](https://upload.wikimedia.org/wikipedia/commons/2/26/Chromecast_cast_button_icon.svg) on your phone/computer then multi-scrobbler can monitor it in order to scrobble music you play. 774 - 775 - 776 - :::note 777 - 778 - Google Cast support is **experimental**. You may experience crashes and errors while using this Source. Please open an issue if you experience problems and include all information detailed in the issue template to help debug your issue. 779 - 780 - :::: 781 - 782 - :::note 783 - 784 - This source relies on common, **basic** music data provided by the cast device which will always be less exhaustive than data parsed from full source integrations. If there is an existing [Source](#source-configurations) it is recommended to configure for it and blacklist the app on Google Cast, rather than relying solely on Google Cast for scrobbling. 785 - 786 - :::: 787 - 788 - #### Connecting Devices 789 - 790 - Cast devices can be manually configured using [File-based configuration](#file-based-14) OR automatically discovered using **mDNS.** 791 - 792 - ###### mDNS Discovery 793 - 794 - The host machine running multi-scrobbler must be configured to allow [mDNS traffic on port 5353/UDP](https://book.hacktricks.xyz/network-services-pentesting/5353-udp-multicast-dns-mdns). 795 - 796 - ###### Linux 797 - 798 - **Docker** 799 - 800 - The host machine must have [avahi-daemon](https://avahi.org/) running to circumvent limitations with DNS resolution due to musl in Alpine. Most major linux distributions package avahi and many have it built-in. Once avahi is running you must pass D-Bus and the avahi daemon socket to your container like so: 801 - 802 - ``` 803 - docker run ... -v /var/run/dbus:/var/run/dbus -v /var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket ... foxxmd/multi-scrobbler 804 - ``` 805 - 806 - **Flatpak/Nodejs** 807 - 808 - No additional steps are required. 809 - 810 - ###### Windows 811 - 812 - **Docker** 813 - 814 - Unsupported at this time. 815 - 816 - **Nodejs** 817 - 818 - No additional steps are required. 819 - 820 - #### What Media Does MS Scrobble? 821 - 822 - Cast devices report what type of media the current activity is [(see `metadata` property here)](https://developers.google.com/cast/docs/media/messages#MediaInformation). The reported type is dependent on the application playing the media to correctly report it, the cast device does not magically know what the media is. If an application does not report a type it is always classified as `unknown`. 823 - 824 - **By default, MS will only track media that is reported as `MusicTrack`.** 825 - 826 - ##### Allow Unknown Media Type 827 - 828 - Media with an Unknown (`Generic`) media type can be explicitly allowed by setting `"allowUnknownMedia": true` in the [file-based configuration.](#file-based-14) This can also be configured to only allow unknown media types for specific applications by using a list of application names like: 829 - 830 - ```json5 831 - // in chromecast.json or config.json sources 832 - [ 833 - { 834 - "name": "MyCast", 835 - "type": "chromecast", 836 - "data": { 837 - // only allow unknown if app name contains any of these phrases 838 - "allowUnknownMedia": ["smarttube", "default media receiver"] 839 - }, 840 - } 841 - ] 842 - ``` 843 - 844 - ##### Forcing Media Tracking 845 - 846 - MS can be forced to track media from an application regardless of media type. This is useful if an application incorrectly reports a media type you are sure should be music. Set `"forceMediaRecognitionOn"` in the [file-based configuration.](#file-based-14) to a list of application names that should always be tracked like: 847 - 848 - ```json5 849 - // in chromecast.json or config.json sources 850 - [ 851 - { 852 - "name": "MyCast", 853 - "type": "chromecast", 854 - "data": { 855 - // media from applications that contains these phrases will always be tracked, regardless of media type reported 856 - "forceMediaRecognitionOn": ["smarttube", "default media receiver"] 857 - }, 858 - } 859 - ] 860 - ``` 861 - 862 - 863 - #### Cast Troubleshooting 864 - 865 - Please include any/all logs with raw output if there are any errors encountered as this is critical to diagnosing issues. 866 - 867 - To diagnose bad/incomplete track information or strange MS player behavior please turn on **payload logging** and include log output of the source running to help diagnose this issue: 868 - 869 - ```json5 870 - // in chromecast.json or config.json sources 871 - [ 872 - { 873 - "name": "MyCast", 874 - "type": "chromecast", 875 - "data": { 876 - //... 877 - }, 878 - "options": { 879 - "logPayload": true 880 - } 881 - } 882 - ] 883 - ``` 884 - 885 - #### ENV-Based 886 - 887 - :::note 888 - 889 - [Manually configuring cast device connections](#connecting-devices) is only available through [File-based config.](#file-based-14) 890 - 891 - :::: 892 - 893 - | Environmental Variable | Required? | Default | Description | 894 - |------------------------|-----------|---------|--------------------------------------------------------------------------------------| 895 - | CC_ENABLE | No | | Set to 'true' to enable Cast monitoring without needing to define other ENVs | 896 - | CC_WHITELIST_DEVICES | No | | Only scrobble from these Cast devices. Comma-delimited list. EX mini-home, family-tv | 897 - | CC_BLACKLIST_DEVICES | No | | Do not scrobble from these Cast devices. Comma-delimited list | 898 - | CC_WHITELIST_APPS | No | | Only scrobble from these casted Apps. Comma-delimited list. EX spotify, pandora | 899 - | CC_BLACKLIST_APPS | No | | Do not scrobble from these casted Apps. Comma-delimited list | 900 - 901 - #### File-Based 902 - 903 - See [`chromecast.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FChromecastSourceConfig/%23%2Fdefinitions%2FChromecastData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 904 - 905 - ### [Musikcube](https://musikcube.com) 906 - 907 - In order to use Musikcube configure it to accept [websocket connections](https://github.com/clangen/musikcube/wiki/remote-api-documentation) in **server setup**: 908 - 909 - * Enable the **Metadata Server** 910 - * Set a **Password** 911 - 912 - Both of these settings are found in _Musikcube -> (s)ettings -> server setup_ 913 - 914 - ![Server Setup](musikcube.jpg) 915 - 916 - The URL used by MS has the syntax: 917 - 918 - ``` 919 - [ws|wss]://HOST:[PORT] 920 - ``` 921 - 922 - The **port** is the same as shown in the server setup screenshot from above, under **metadata server enabled**. If no port is provided to MS it will default to `7905`. 923 - 924 - If no URL is provided to MS it will try to use `ws://localhost:7905` 925 - 926 - #### ENV-Based 927 - 928 - | Environmental Variable | Required? | Default | Description | 929 - |------------------------|-----------|-----------------------|--------------------------------------| 930 - | `MC_URL` | No | `ws://localhost:7905` | Use port set for **metadata server** | 931 - | `MC_PASSWORD` | Yes | | | 932 - 933 - #### File-Based 934 - 935 - See [`musikcube.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMuikcubeSourceConfig/%23%2Fdefinitions%2FMuikcubeData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 936 - 937 - ## Client Configurations 938 - 939 - ### [Maloja](https://github.com/krateng/maloja) 940 - 941 - #### ENV-Based 942 - 943 - | Environmental Variable | Required? | Default | Description | 944 - |----------------------------|-----------|---------|-------------------------------| 945 - | `MALOJA_URL` | Yes | | Base URL of your installation | 946 - | `MALOJA_API_KEY` | Yes | | Api Key | 947 - 948 - #### File-Based 949 - 950 - See [`maloja.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/maloja.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FMalojaClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 951 - 952 - ### [Last.fm](https://www.last.fm) 953 - 954 - [Register for an API account here.](https://www.last.fm/api/account/create) 955 - 956 - The Callback URL is actually specified by multi-scrobbler but to keep things consistent you should use 957 - ``` 958 - http://localhost:9078/lastfm/callback 959 - ``` 960 - or replace `localhost:9078` with your own base URL 961 - 962 - #### ENV-Based 963 - 964 - | Environmental Variable | Required? | Default | Description | 965 - |----------------------------|-----------|-----------------------------------------|-------------------------------| 966 - | `LASTFM_API_KEY` | Yes | | Api Key from your API Account | 967 - | `LASTFM_SECRET` | Yes | | Shared secret from your API Account | 968 - | `LASTFM_REDIRECT_URI` | No | `http://localhost:9078/lastfm/callback` | Url to use for authentication. Must include `lastfm/callback` somewhere in it | 969 - | `LASTFM_SESSION` | No | | Session id. Will be generated by authentication flow if not provided. | 970 - 971 - #### File-Based 972 - 973 - See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 974 - 975 - ### [Listenbrainz](https://listenbrainz.org) 976 - 977 - You will need to run your own Listenbrainz server or have an account [on the official instance](https://listenbrainz.org/login/) 978 - 979 - On your [profile page](https://listenbrainz.org/profile/) find your **User Token** to use in the configuration. 980 - 981 - #### ENV-Based 982 - 983 - 984 - | Environmental Variable | Required? | Default | Description | 985 - |------------------------|-----------|-------------------------------|---------------------------------| 986 - | LZ_TOKEN | Yes | | User token from your LZ profile | 987 - | LZ_USER | Yes | | Your LZ username | 988 - | LZ_URL | No | https://api.listenbrainz.org/ | The base URL for the LZ server | 989 - 990 - #### File-Based 991 - 992 - See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 993 - 994 - ## Monitoring 995 - 996 - multi-scrobbler supports some common webhooks and a healthcheck endpoint in order to monitor Sources and Clients for errors. 997 - 998 - ### Webhook Configurations 999 - 1000 - Webhooks will **push** a notification to your configured servers on these events: 1001 - 1002 - * Source polling started 1003 - * Source polling retry 1004 - * Source polling stopped on error 1005 - * Scrobble client scrobble failure 1006 - 1007 - Webhooks are configured in the main [config.json](#all-in-one-file-configuration) file under the `webhook` top-level property. Multiple webhooks may be configured for each webhook type. EX: 1008 - 1009 - ```json5 1010 - { 1011 - "sources": [ 1012 - //... 1013 - ], 1014 - "clients": [ 1015 - //... 1016 - ], 1017 - "webhooks": [ 1018 - { 1019 - "name": "FirstGotifyServer", 1020 - "type": "gotify", 1021 - "url": "http://192.168.0.100:8070", 1022 - "token": "abcd" 1023 - }, 1024 - { 1025 - "name": "SecondGotifyServer", 1026 - "type": "gotify", 1027 - //... 1028 - }, 1029 - { 1030 - "name": "NtfyServerOne", 1031 - "type": "ntfy", 1032 - //... 1033 - }, 1034 - //... 1035 - ] 1036 - } 1037 - ``` 1038 - 1039 - #### [Gotify](https://gotify.net/) 1040 - 1041 - Refer to the [config schema for GotifyConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FGotifyConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1042 - 1043 - multi-scrobbler optionally supports setting message notification priority via `info` `warn` and `error` mappings. 1044 - 1045 - EX 1046 - 1047 - ```json 1048 - { 1049 - "type": "gotify", 1050 - "name": "MyGotifyFriendlyNameForLogs", 1051 - "url": "http://192.168.0.100:8070", 1052 - "token": "AQZI58fA.rfSZbm", 1053 - "priorities": { 1054 - "info": 5, 1055 - "warn": 7, 1056 - "error": 10 1057 - } 1058 - } 1059 - ``` 1060 - 1061 - #### [Ntfy](https://ntfy.sh/) 1062 - 1063 - Refer to the [config schema for NtfyConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FNtfyConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1064 - 1065 - multi-scrobbler optionally supports setting message notification priority via `info` `warn` and `error` mappings. 1066 - 1067 - EX 1068 - 1069 - ```json 1070 - { 1071 - "type": "ntfy", 1072 - "name": "MyNtfyFriendlyNameForLogs", 1073 - "url": "http://192.168.0.100:9991", 1074 - "topic": "RvOwKJ1XtIVMXGLR", 1075 - "username": "Optional", 1076 - "password": "Optional", 1077 - "priorities": { 1078 - "info": 3, 1079 - "warn": 4, 1080 - "error": 5 1081 - } 1082 - } 1083 - ``` 1084 - 1085 - #### [Apprise](https://github.com/caronc/apprise-api) 1086 - 1087 - Refer to the [config schema for AppriseConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FAppriseConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1088 - 1089 - multi-scrobbler supports [stateless](https://github.com/caronc/apprise-api?tab=readme-ov-file#stateless-solution) and [persistent storage](https://github.com/caronc/apprise-api?tab=readme-ov-file#persistent-storage-solution) endpoints as well as [tags](https://github.com/caronc/apprise-api?tab=readme-ov-file#tagging)/ 1090 - 1091 - EX 1092 - 1093 - ```json5 1094 - { 1095 - "type": "apprise", 1096 - "name": "MyAppriseFriendlyNameForLogs", 1097 - "host": "http://192.168.0.100:8080", 1098 - "urls": ["gotify://192.168.0.101:8070/MyToken"], // stateless endpoints 1099 - "keys": ["e90b20526808373353afad7fb98a201198c0c3e0555bea19f182df3388af7b17"], //persistent storage endpoints 1100 - "tags": ["my","optional","tags"] 1101 - } 1102 - ``` 1103 - 1104 - ### Health Endpoint 1105 - 1106 - An endpoint for monitoring the health of sources/clients is available at GET `http://YourMultiScrobblerDomain/health` 1107 - 1108 - * Returns `200 OK` when **everything** is working or `500 Internal Server Error` if **anything** is not 1109 - * The plain url (`/health`) aggregates status of **all clients/sources** -- so any failing client/source will make status return 500 1110 - * Use query params `type` or `name` to restrict client/sources aggregated IE `/health?type=spotify` or `/health?name=MyMaloja` 1111 - * On 500 the response returns a JSON payload with `messages` array that describes any issues 1112 - * For any clients/sources that require authentication `/health` will return 500 if they are **not authenticated** 1113 - * For sources that poll (spotify, yt music, subsonic) `/health` will 500 if they are **not polling**
+1208
docsite/docs/configuration/configuration.mdx
··· 1 + --- 2 + sidebar_position: 2 3 + title: Overview 4 + toc_max_heading_level: 3 5 + --- 6 + import Tabs from '@theme/Tabs'; 7 + import TabItem from '@theme/TabItem'; 8 + import Admonition from '@theme/Admonition'; 9 + 10 + # Configuration 11 + 12 + :::tip 13 + 14 + Check the [**FAQ**](../FAQ.md) if you have any issues after configuration! 15 + 16 + ::: 17 + 18 + ## Configuration Types 19 + 20 + [**Sources** and **Clients**](/#how-does-multi-scrobbler-ms-work) are configured using: 21 + 22 + * environmental (ENV) variables 23 + * client/source specific json config files 24 + * an all-in-one json config file 25 + 26 + **MS will parse configuration from all configuration types.** You can mix and match configurations but it is generally better to stick to one or the other. 27 + 28 + <Tabs groupId="configType" queryString> 29 + <TabItem value="env" label="ENV"> 30 + This is done by passing environmental variables and so does not require any files to run MS. 31 + 32 + * Using a docker container EX `docker run -e "SPOTIFY_CLIENT_ID=yourId" -e "SPOTIFY_CLIENT_SECRET=yourSecret" ...` 33 + * Using a local installations by exporting variables before running MS EX `SPOTIFY_CLIENT_ID=yourId SPOTIFY_CLIENT_SECRET=yourSecret node index.js` 34 + 35 + Use ENV-based configuration if: 36 + 37 + * You are the only person for whom MS is scrobbling for 38 + * You have a very simple setup for MS such as one scrobble [Client](/#client) and one [Source](/#source) IE Plex -> Maloja 39 + </TabItem> 40 + <TabItem value="file" label="File"> 41 + MS will parse configuration files located in the directory specified by the `CONFIG_DIR` environmental variable. This variable defaults to: 42 + 43 + * Local installation -> `PROJECT_DIR/config` 44 + * Docker -> `/config` (in the container) -- see the [install docs](../installation/installation.md#docker) for how to configure this correctly 45 + 46 + <details> 47 + 48 + <summary>Use File-based configuration if...</summary> 49 + 50 + * You have many [Sources](/#source) 51 + * You have many of each type of **Source** you want to scrobble from IE 2x Plex accounts, 3x Spotify accounts, 1x 52 + Funkwhale... 53 + * You have more than one scrobble **Client** you want to scrobble to IE multiple Maloja servers 54 + * You want only some **Sources** to scrobble to some **Clients** IE Fred's Spotify account scrobbles to Fred's Maloja 55 + server, but not Mary's Maloja server 56 + 57 + </details> 58 + 59 + There are **example configurations** for all Source/Client types and AIO config located in the [`/config`](https://github.com/FoxxMD/multi-scrobbler/tree/master/config) directory of this project. These can be used as-is by renaming them to `.json`. 60 + For docker installations these examples are copied to your configuration directory on first-time use. There is also a [**kitchensink example**](kitchensink.md) that provides examples of using all sources/clients in a complex configuration. 61 + 62 + Each file is named by the **type** of the Client/Source found in below sections. Each file as an **array** of that type of Client/Source. 63 + 64 + Example directory structure: 65 + 66 + ``` 67 + /CONFIG_DIR 68 + plex.json 69 + spotify.json 70 + maloja.json 71 + ``` 72 + 73 + <details> 74 + <summary>Config Example</summary> 75 + 76 + ```json5 title="/CONFIG_DIR/maloja.json" 77 + [ 78 + { 79 + "name": "myFirstMalojaClient", 80 + "data": { 81 + "url": "http://myMalojaServer.example", 82 + "apiKey": "myKey" 83 + } 84 + }, 85 + { 86 + "name": "mySecondMalojaClient", 87 + "data": { 88 + "url": "http://my2ndMalojaServer.example", 89 + "apiKey": "myKey" 90 + } 91 + } 92 + ] 93 + 94 + ``` 95 + 96 + </details> 97 + </TabItem> 98 + <TabItem value="aio" label="File AIO"> 99 + MS will parse an **all-in-one** configuration file located in the directory specified by the `CONFIG_DIR` environmental variable. This variable defaults to: 100 + 101 + * Local installation -> `PROJECT_DIR/config/config.json` 102 + * Docker -> `/config/config.json` (in the container) -- see the [install docs](../installation/installation.md#docker) for how to configure this correctly 103 + 104 + <details> 105 + 106 + <summary>Use AIO-based configuration if...</summary> 107 + 108 + * You have many [Sources](/#source) 109 + * You have many of each type of **Source** you want to scrobble from IE 2x Plex accounts, 3x Spotify accounts, 1x 110 + Funkwhale... 111 + * You have more than one scrobble **Client** you want to scrobble to IE multiple Maloja servers 112 + * You want only some **Sources** to scrobble to some **Clients** IE Fred's Spotify account scrobbles to Fred's Maloja 113 + server, but not Mary's Maloja server 114 + 115 + </details> 116 + 117 + **The AIO config also enables setting default options for sources/clients as well as global options for MS itself.** 118 + 119 + An example AIO config files can be found at [/config/config.json.example](https://github.com/FoxxMD/multi-scrobbler/tree/master/config/config.json.example) in the project directory. For docker installations theis example is copied to your configuration directory on first-time use. There is also a [**kitchensink example**](kitchensink.md) that provides examples of using all sources/clients in a complex AOI configuration. 120 + 121 + [**Explore the schema for this configuration, along with an example generator and validator, here**](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 122 + 123 + <details> 124 + 125 + <summary>Config Example</summary> 126 + 127 + ```json title="/CONFIG_DIR/config.json" 128 + { 129 + "sources": [ 130 + { 131 + "name": "myConfig", 132 + "type": "spotify", 133 + "clients": [ 134 + "myMalojaClient" 135 + ], 136 + "data": { 137 + "clientId": "anExample" 138 + "clientSecret": "anExample", 139 + "redirectUri": "http://localhost:9078/callback" 140 + } 141 + } 142 + ], 143 + "clients": [ 144 + { 145 + "name": "myMalojaClient", 146 + "type": "maloja", 147 + "data": { 148 + "url": "http://myMalojaServer.example", 149 + "apiKey": "myKey" 150 + } 151 + } 152 + ] 153 + } 154 + ``` 155 + 156 + </details> 157 + </TabItem> 158 + </Tabs> 159 + 160 + ## Application Options 161 + 162 + These options affect multi-scrobbler's behavior and are not specific to any source/client. 163 + 164 + #### Base URL 165 + 166 + Defines the URL that is used to generate default redirect URLs for authentication on [spotify](#spotify), [lastfm](#lastfm), and [deezer](#deezer) -- as well as some logging hints. 167 + 168 + * Default => `http://localhost:9078` 169 + * Set with [ENV](./configuration?configType=env#configuration-types) `BASE_URL` or `baseUrl` [all-in-one configuration](./configuration?configType=aio#configuration-types) 170 + * If protocol is `http` or no protocol is specified MS will try to use port `9078` -- to override this explicitly set the port or use `https` 171 + 172 + Useful when running with [docker](../installation/installation.md#docker) so that you do not need to specify redirect URLs for each configuration. 173 + 174 + <details> 175 + 176 + <summary>Example</summary> 177 + 178 + EX Lastfm Redirect Url is `BASE_URL:PORT/lastfm/callback` (when no other redirectUri is specified for [lastfm configuration](#lastfm)) 179 + 180 + | `BASE_URL` | Redirect URL | 181 + |-------------------------------------|----------------------------------------------------------| 182 + | `192.168.0.101` | `http://192.168.0.101:9078/lastfm/callback` | 183 + | `http://my.domain.local` | `http://my.domain.local:9078/lastfm/callback` | 184 + | `http://192.168.0.101/my/subfolder` | `http://192.168.0.101:9078/my/subfolder/lastfm/callback` | 185 + 186 + | `BASE_URL` | Redirect URL | 187 + |-----------------------------------|----------------------------------------------------------| 188 + | `my.domain.local:80` | `http://192.168.0.101:9078/lastfm/callback` | 189 + | `my.domain.local:9000` | `http://my.domain.local:9078/lastfm/callback` | 190 + | `192.168.0.101:4000/my/subfolder` | `http://192.168.0.101:9078/my/subfolder/lastfm/callback` | 191 + | `https://192.168.0.101` | `https://192.168.0.101:443/lastfm/callback` | 192 + 193 + </details> 194 + 195 + #### Disable Web 196 + 197 + If you do not need the dashboard and/or ingress sources, or have security concerns about ingress and cannot control their hosting environment, the web server and API can be disabled. 198 + 199 + :::warning 200 + 201 + Any **ingress-based sources will be unusable** (Plex, Jellyfin, Tautulli, etc...) if this is disabled. 202 + 203 + ::: 204 + 205 + Disable using either: 206 + 207 + * ENV `DISABLE_WEB=true` 208 + * In [All-in-One File](./configuration?configType=aio#configuration-types) use the top-level property `"disableWeb": true` 209 + 210 + ## Source Configurations 211 + 212 + ### [Spotify](https://www.spotify.com) 213 + 214 + To access your Spotify history you must [register an application](https://developer.spotify.com/dashboard) to get a 215 + Client ID/Secret. Make sure to also whitelist your redirect URI in the application settings. 216 + 217 + :::note 218 + 219 + If your Spotify player has [Automix](https://community.spotify.com/t5/FAQs/What-is-Automix/ta-p/5257278) enabled and Spotify uses it for your playlist/queue then MS cannot accurately determine when a track will end. This is because the track is "mixed" in your queue with a shorter play time than its actual length and [Spotify does not report this modified play time in its API.](https://community.spotify.com/t5/Spotify-for-Developers/Wrong-duration-ms-of-track-with-Automix/m-p/5429147) This **does not affect MS's ability to scrobble** from Spotify but it will affect the accuracy of the duration MS reports was played. 220 + 221 + ::: 222 + 223 + #### Configuration 224 + 225 + <Tabs groupId="configType" queryString> 226 + <TabItem value="env" label="ENV"> 227 + | Environmental Variable | Required? | Default | Description | 228 + |----------------------------|-----------|----------------------------------|----------------------------------------------------| 229 + | `SPOTIFY_CLIENT_ID` | Yes | | | 230 + | `SPOTIFY_CLIENT_SECRET` | Yes | | | 231 + | `SPOTIFY_REDIRECT_URI` | No | `http://localhost:9078/callback` | URI must end in `callback` | 232 + </TabItem> 233 + <TabItem value="file" label="File"> 234 + See [`spotify.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/spotify.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSpotifySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 235 + </TabItem> 236 + <TabItem value="aio" label="AIO"> 237 + See [`spotify.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/spotify.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSpotifySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 238 + </TabItem> 239 + </Tabs> 240 + 241 + ### [Plex](https://plex.tv) 242 + 243 + Check the [instructions](plex.md) on how to setup a [webhooks](https://support.plex.tv/articles/115002267687-webhooks) to scrobble your plays. 244 + 245 + #### Configuration 246 + 247 + <Tabs groupId="configType" queryString> 248 + <TabItem value="env" label="ENV"> 249 + | Environmental Variable | Required | Default | Description | 250 + |------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------| 251 + | `PLEX_USER` | No | | The a comma-delimited list of usernames to scrobble tracks for. No usernames specified means all tracks by all users will be scrobbled. | 252 + </TabItem> 253 + <TabItem value="file" label="File"> 254 + See [`plex.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/plex.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FPlexSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 255 + </TabItem> 256 + <TabItem value="aio" label="AIO"> 257 + See [`plex.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/plex.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FPlexSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 258 + </TabItem> 259 + </Tabs> 260 + 261 + ### [Tautulli](https://tautulli.com) 262 + 263 + Check the [instructions](plex.md) on how to setup a notification agent. 264 + 265 + #### Configuration 266 + 267 + <Tabs groupId="configType" queryString> 268 + <TabItem value="env" label="ENV"> 269 + | Environmental Variable | Required | Default | Description | 270 + |------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------| 271 + | `TAUTULLI_USER` | No | | The a comma-delimited list of usernames to scrobble tracks for. No usernames specified means all tracks by all users will be scrobbled. | 272 + </TabItem> 273 + <TabItem value="file" label="File"> 274 + See [`tautulli.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/tautulli.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FTautulliSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 275 + </TabItem> 276 + <TabItem value="aio" label="AIO"> 277 + See [`tautulli.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/tautulli.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FTautulliSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 278 + </TabItem> 279 + </Tabs> 280 + 281 + ### [Subsonic](http://www.subsonic.org/) 282 + 283 + Can use this source for any application that implements the [Subsonic API](http://www.subsonic.org/pages/api.jsp) and supports the [`getNowPlaying`](http://www.subsonic.org/pages/api.jsp#getNowPlaying) endpoint (such as [Airsonic](https://airsonic.github.io/) and [Navidrome](https://www.navidrome.org/)) 284 + 285 + **Known Issues:** 286 + * "Time played at" is somewhat inaccurate since the api only reports "played X minutes ago" so... 287 + * All scrobble times are therefore "on the minute" and you may experience occasional duplicate scrobbles 288 + * "played X minutes ago" sometimes is also not reported correctly 289 + * Multiple artists are reported as one value and cannot be separated 290 + * If using [Airsonic Advanced](https://github.com/airsonic-advanced/airsonic-advanced) the password used (under **Credentials**) must be **Decodable** 291 + 292 + #### Configuration 293 + 294 + <Tabs groupId="configType" queryString> 295 + <TabItem value="env" label="ENV"> 296 + | Environmental Variable | Required? | Default | Description | 297 + |------------------------|-----------|---------|--------------------------------------| 298 + | `SUBSONIC_USER` | Yes | | | 299 + | `SUBSONIC_PASSWORD` | Yes | | | 300 + | `SUBSONIC_URL` | Yes | | Base url of your subsonic-api server | 301 + </TabItem> 302 + <TabItem value="file" label="File"> 303 + See [`subsonic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/subsonic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubSonicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 304 + </TabItem> 305 + <TabItem value="aio" label="AIO"> 306 + See [`subsonic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/subsonic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FSubSonicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 307 + </TabItem> 308 + </Tabs> 309 + 310 + ### [Jellyfin](https://jellyfin.org/) 311 + 312 + Must be using Jellyfin 10.7 or greater 313 + 314 + * In the Jellyfin desktop web UI Navigate to -> Administration -> Dashboard -> Plugins -> Catalog 315 + * Under Notifications -> **Webhook** -> Install, then restart your server 316 + * Navigate back to -> Administration -> Dashboard -> Plugins -> My Plugins -> Webhook 317 + * Click "..." -> Settings 318 + * In Webhook settings: 319 + * `Add Generic Destination` 320 + * In the new `Generic` dropdown: 321 + * Webhook Url: `http://localhost:9078/jellyfin` 322 + * Notification Type: `Playback Progress` 323 + * Item Type: `Songs` 324 + * Check `Send All Properties` 325 + * Save 326 + 327 + :::note 328 + 329 + If you see errors in the MS logs regarding `missing headers` when using Jellyfin [see this workaround.](../FAQ.md#jellyfin-has-warnings-about-missing-headers) 330 + 331 + ::: 332 + 333 + #### Configuration 334 + 335 + <Tabs groupId="configType" queryString> 336 + <TabItem value="env" label="ENV"> 337 + | Environmental Variable | Required? | Default | Description | 338 + |------------------------|-----------|---------|-------------------------------------------------------------------| 339 + | `JELLYFIN_USER` | | | Comma-separated list of usernames (from Jellyfin) to scrobble for | 340 + | `JELLYFIN_SERVER` | | | Comma-separated list of Jellyfin server names to scrobble from | 341 + </TabItem> 342 + <TabItem value="file" label="File"> 343 + See [`jellyfin.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jellyfin.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FJellySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 344 + </TabItem> 345 + <TabItem value="aio" label="AIO"> 346 + See [`jellyfin.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jellyfin.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FJellySourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 347 + </TabItem> 348 + </Tabs> 349 + 350 + ### [Last.fm (Source)](https://www.last.fm) 351 + 352 + See the [Last.fm (Client)](#lastfm) setup for registration instructions. 353 + 354 + #### Configuration 355 + 356 + <Tabs groupId="configType" queryString> 357 + <TabItem value="env" label="ENV"> 358 + No support for ENV based for Last.fm as a client (only source) 359 + </TabItem> 360 + <TabItem value="file" label="File"> 361 + See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example), change `configureAs` to `source`. Or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 362 + </TabItem> 363 + <TabItem value="aio" label="AIO"> 364 + See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example), change `configureAs` to `source`. Or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 365 + </TabItem> 366 + </Tabs> 367 + 368 + ### [Listenbrainz (Source)](https://listenbrainz.org) 369 + 370 + You will need to run your own Listenbrainz server or have an account [on the official instance](https://listenbrainz.org/login/) 371 + 372 + On your [profile page](https://listenbrainz.org/profile/) find your **User Token** to use in the configuration. 373 + 374 + 375 + #### Configuration 376 + 377 + <Tabs groupId="configType" queryString> 378 + <TabItem value="env" label="ENV"> 379 + <Admonition type="note"> 380 + You cannot use ENV variables shown in the [Listenbrainz Client config](#listenbrainz) -- multi-scrobbler assumes Listenbrainz ENVs are always used for the **client** configuration. You must use the file-based config from below to setup Listenbrainz as a Source. 381 + </Admonition> 382 + </TabItem> 383 + <TabItem value="file" label="File"> 384 + See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 385 + 386 + **Change `configureAs` to `source`** 387 + </TabItem> 388 + <TabItem value="aio" label="AIO"> 389 + See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 390 + 391 + **Change `configureAs` to `source`** 392 + </TabItem> 393 + </Tabs> 394 + 395 + ### [Deezer](https://deezer.com/) 396 + 397 + Create a new application at [Deezer Developers](https://developers.deezer.com/myapps) 398 + 399 + * Application Domain must be the same as your multi-scrobbler domain. Default is `localhost:9078` 400 + * Redirect URL must end in `deezer/callback` 401 + * Default would be `http://localhost:9078/deezer/callback` 402 + 403 + After application creation you should have credentials displayed in the "My Apps" dashboard. You will need: 404 + 405 + * **Application ID** 406 + * **Secret Key** 407 + * **Redirect URL** (if not the default) 408 + 409 + **If no access token is provided...** 410 + 411 + After starting multi-scrobbler with credentials in-place open the dashboard (`http://localhost:9078`) and find your Deezer source. Click **(Re)authenticate and (re)start polling** to start the login process. After login is complete polling will begin automatically. 412 + 413 + #### Configuration 414 + 415 + <Tabs groupId="configType" queryString> 416 + <TabItem value="env" label="ENV"> 417 + | Environmental Variable | Required? | Default | Description | 418 + |------------------------|-----------|-----------------------------------------|-----------------------------------| 419 + | `DEEZER_CLIENT_ID` | Yes | | Your **Application ID** | 420 + | `DEEZER_CLIENT_SECRET` | Yes | | Your **Secret Key** | 421 + | `DEEZER_REDIRECT_URI` | No | `http://localhost:9078/deezer/callback` | URI must end in `deezer/callback` | 422 + </TabItem> 423 + <TabItem value="file" label="File"> 424 + See [`deezer.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/deezer.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FDeezerSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 425 + </TabItem> 426 + <TabItem value="aio" label="AIO"> 427 + See [`deezer.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/deezer.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FDeezerSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 428 + </TabItem> 429 + </Tabs> 430 + 431 + ### [Youtube Music](https://music.youtube.com) 432 + 433 + :::note 434 + 435 + * YT Music authentication is "browser based" which means your credentials may expire after a (long?) period of time OR if you log out of https://music.youtube.com. In the event this happens just repeat the steps below to get new credentials. 436 + * Communication to YT Music is **unofficial** and not supported or endorsed by Google. This means that **this integration may stop working at any time** if Google decides to change how YT Music works in the browser. 437 + 438 + ::: 439 + 440 + Credentials for YT Music are obtained from a browser request to https://music.youtube.com **once you are logged in.** [Specific requirements are here and summarized below:](https://github.com/nickp10/youtube-music-ts-api/blob/master/DOCUMENTATION.md#authenticate) 441 + 442 + * Open a new tab 443 + * Open the developer tools (Ctrl-Shift-I) and select the “Network” tab 444 + * Go to https://music.youtube.com and ensure you are logged in 445 + 446 + Then... 447 + 448 + 1. Find and select an authenticated POST request. The simplest way is to filter by /browse using the search bar of the developer tools. If you don’t see the request, try scrolling down a bit or clicking on the library button in the top bar. 449 + 2. **Make sure **Headers** pane is selected and open 450 + 3. In the **Request Headers** section find and copy the **entire value** found after `Cookie:` and use this as the `cookie` value in your multi-scrobbler config 451 + 4. If present, in the **Request Headers** section find and copy the number found in `X-google-AuthUser` and use this as the value for `authUser` in your multi-scrobbler config 452 + 453 + ![Google Headers](google-header.jpg) 454 + 455 + #### Configuration 456 + 457 + <Tabs groupId="configType" queryString> 458 + <TabItem value="env" label="ENV"> 459 + No ENV support 460 + </TabItem> 461 + <TabItem value="file" label="File"> 462 + See [`ytmusic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/ytmusic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FYTMusicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 463 + </TabItem> 464 + <TabItem value="aio" label="AIO"> 465 + See [`ytmusic.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/ytmusic.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FYTMusicSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 466 + </TabItem> 467 + </Tabs> 468 + 469 + ### [MPRIS](https://specifications.freedesktop.org/mpris-spec/latest/) 470 + 471 + MPRIS is a standard interface for communicating with Music Players on **linux operating systems.** 472 + 473 + If you run Linux and have a notification tray that shows what media you are listening to, you likely have access to MPRIS. 474 + 475 + ![Notification Tray](mpris.jpg) 476 + 477 + multi-scrobbler can listen to this interface and scrobble tracks played by **any media player** that communicates to the operating system with MPRIS. 478 + 479 + :::note 480 + 481 + multi-scrobbler needs to be running as a [**Local Installation**](../installation/installation.md#nodejs) in order to use MPRIS. This cannot be used from docker. 482 + 483 + ::: 484 + 485 + #### Configuration 486 + 487 + <Tabs groupId="configType" queryString> 488 + <TabItem value="env" label="ENV"> 489 + | Environmental Variable | Required? | Default | Description | 490 + |------------------------|-----------|---------|----------------------------------------------------------------------------------| 491 + | MPRIS_ENABLE | No | | Use MPRIS as a Source (useful when you don't need any other options) | 492 + | MPRIS_BLACKLIST | No | | Comma-delimited list of player names not to scrobble from | 493 + | MPRIS_WHITELIST | No | | Comma-delimited list of players names to ONLY scrobble from. Overrides blacklist | 494 + </TabItem> 495 + <TabItem value="file" label="File"> 496 + See [`mpris.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mpris.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMPRISSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 497 + </TabItem> 498 + <TabItem value="aio" label="AIO"> 499 + See [`mpris.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mpris.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMPRISSourceConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 500 + </TabItem> 501 + </Tabs> 502 + 503 + ### [Mopidy](https://mopidy.com/) 504 + 505 + Mopidy is a headless music server that supports playing music from many [standard and non-standard sources such as Pandora, Bandcamp, and Tunein.](https://mopidy.com/ext/) 506 + 507 + multi-scrobbler can scrobble tracks played from any Mopidy backend source, regardless of where you listen to them. 508 + 509 + #### Configuration 510 + 511 + <Tabs groupId="configType" queryString> 512 + <TabItem value="env" label="ENV"> 513 + No ENV support 514 + </TabItem> 515 + <TabItem value="file" label="File"> 516 + See [`mopidy.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mopidy.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMopidySourceConfig/%23%2Fdefinitions%2FMopidyData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 517 + </TabItem> 518 + <TabItem value="aio" label="AIO"> 519 + See [`mopidy.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/mopidy.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMopidySourceConfig/%23%2Fdefinitions%2FMopidyData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 520 + </TabItem> 521 + </Tabs> 522 + 523 + #### Configuration Options 524 + 525 + ###### `url` 526 + 527 + The URL used to connect to the Mopidy server. You MUST have [Mopidy-HTTP extension](https://mopidy.com/ext/http) enabled. 528 + 529 + If no `url` is provided a default is used which assumes Mopidy is installed on the same server as multi-scrobbler: `ws://localhost:6680/mopidy/ws/` 530 + 531 + Make sure the hostname and port number match what is found in the Mopidy configuration file `mopidy.conf`: 532 + 533 + ``` 534 + ... 535 + 536 + [http] 537 + hostname = localhost 538 + port = 6680 539 + 540 + ... 541 + ``` 542 + 543 + The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 544 + If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 545 + 546 + Part => Default Value 547 + 548 + * Protocol => `ws://` 549 + * Hostname => `localhost` 550 + * Port => `6680` 551 + * Path => `/mopidy/ws/` 552 + 553 + <details> 554 + <summary>URL Transform Examples</summary> 555 + 556 + ```json 557 + { 558 + "url": "mopidy.mydomain.com" 559 + } 560 + ``` 561 + 562 + MS transforms this to: `ws://mopidy.mydomain.com:6680/mopidy/ws/` 563 + 564 + ```json 565 + { 566 + "url": "192.168.0.101:3456" 567 + } 568 + ``` 569 + 570 + MS transforms this to: `ws://192.168.0.101:3456/mopidy/ws/` 571 + 572 + ```json 573 + { 574 + "url": "mopidy.mydomain.com:80/MOPWS" 575 + } 576 + ``` 577 + 578 + MS transforms this to: `ws://mopidy.mydomain.com:80/MOPWS` 579 + 580 + </details> 581 + 582 + 583 + ##### URI Blacklist/Whitelist 584 + 585 + If you wish to disallow or only allow scrobbling from some sources played through Mopidy you can specify these using `uriBlacklist` or `uriWhitelist` in your config. multi-scrobbler will check the list to see if any string matches the START of the `uri` on a track. If whitelist is used then blacklist is ignored. All strings are case-insensitive. 586 + 587 + ```json 588 + { 589 + "uriBlacklist": ["soundcloud"] 590 + } 591 + ``` 592 + 593 + Will prevent multi-scrobbler from scrobbling any Mopidy track that start with a `uri` like `soundcloud:song:MySong-1234` 594 + 595 + ##### Album Blacklist 596 + 597 + For certain sources (Soundcloud) Mopidy does not have all track info (Album) and will instead use "Soundcloud" as the Album name. You can prevent multi-scrobbler from using this bad Album data by adding the fake Album name to this list. Multi-scrobbler will still scrobble the track, just without the bad data. All strings are case-insensitive. 598 + 599 + ```json 600 + { 601 + "albumBlacklist": ["SoundCloud", "Mixcloud"] 602 + } 603 + ``` 604 + 605 + If a track would be scrobbled like `Album: Soundcloud, Track: My Cool Track, Artist: A Cool Artist` 606 + then multi-scrobbler will instead scrobble `Track: My Cool Track, Artist: A Cool Artist` 607 + 608 + ### [JRiver](https://jriver.com/) 609 + 610 + In order for multi-scrobbler to communicate with JRiver you must have [Web Server Interface](https://wiki.jriver.com/index.php/Web_Service_Interface#Documentation_of_Functions) enabled. This can can be in the JRiver GUI: 611 + 612 + * Tools -> Options -> Media Network 613 + * Check `Use Media Network to share this library...` 614 + * If you have `Authentication` checked you will need to provide the **Username** and **Password** in the ENV/File configuration below. 615 + 616 + ##### URL 617 + 618 + If you do not provide a URL then a default is used which assumes JRiver is installed on the same server as multi-scrobbler: `http://localhost:52199/MCWS/v1/` 619 + 620 + * Make sure the port number matches what is found in `Advanced` section in the [Media Network](#jriver) options. 621 + * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 622 + 623 + The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 624 + If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 625 + 626 + Part => Default Value 627 + 628 + * Protocol => `http://` 629 + * Hostname => `localhost` 630 + * Port => `52199` 631 + * Path => `/MCWS/v1/` 632 + 633 + <details> 634 + <summary>URL Transform Examples</summary> 635 + 636 + ```json 637 + { 638 + "url": "jriver.mydomain.com" 639 + } 640 + ``` 641 + 642 + MS transforms this to: `http://jriver.mydomain.com:52199/MCWS/v1/` 643 + 644 + ```json 645 + { 646 + "url": "192.168.0.101:3456" 647 + } 648 + ``` 649 + 650 + MS transforms this to: `http://192.168.0.101:3456/MCWS/v1/` 651 + 652 + ```json 653 + { 654 + "url": "mydomain.com:80/jriverReverse/MCWS/v1/" 655 + } 656 + ``` 657 + 658 + MS transforms this to: `http://mydomain.com:80/jriverReverse/MCWS/v1/` 659 + 660 + </details> 661 + 662 + #### Configuration 663 + 664 + <Tabs groupId="configType" queryString> 665 + <TabItem value="env" label="ENV"> 666 + | Environmental Variable | Required | Default | Description | 667 + |------------------------|----------|---------------------------------|------------------------------------------------| 668 + | JRIVER_URL | Yes | http://localhost:52199/MCWS/v1/ | The URL of the JRiver server | 669 + | JRIVER_USERNAME | No | | If authentication is enabled, the username set | 670 + | JRIVER_PASSWORD | No | | If authenticated is enabled, the password set | 671 + </TabItem> 672 + <TabItem value="file" label="File"> 673 + See [`jriver.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jriver.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FJRiverSourceConfig/%23%2Fdefinitions%2FJRiverData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 674 + </TabItem> 675 + <TabItem value="aio" label="AIO"> 676 + See [`jriver.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/jriver.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FJRiverSourceConfig/%23%2Fdefinitions%2FJRiverData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 677 + </TabItem> 678 + </Tabs> 679 + 680 + ### [Kodi](https://kodi.tv/) 681 + 682 + In order for multi-scrobbler to communicate with Kodi you must have the [Web Interface](https://kodi.wiki/view/Web_interface) enabled. This can can be in the Kodi GUI: 683 + 684 + * Settings -> Services -> Control 685 + * Check `Allow remote control via HTTP` 686 + * Ensure you have a **Username** and **Password** set, you will need to provide them in the ENV/File configuration below. 687 + 688 + ##### URL 689 + 690 + If you do not provide a URL then a default is used which assumes Kodi is installed on the same server as multi-scrobbler: `http://localhost:8080/jsonrpc` 691 + 692 + * Make sure the port number matches what is found in **Port** in the [Control](#kodi) section mentioned above. 693 + * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 694 + 695 + The URL used to connect ultimately must be formed like this: `[protocol]://[hostname]:[port]/[path]` 696 + If any part of this URL is missing multi-scrobbler will use a default value, for your convenience. This also means that if any part of your URL is **not** standard you must explicitly define it. 697 + 698 + Part => Default Value 699 + 700 + * Protocol => `http://` 701 + * Hostname => `localhost` 702 + * Port => `8080` 703 + * Path => `/jsonrpc` 704 + 705 + <details> 706 + <summary>URL Transform Examples</summary> 707 + 708 + ```json 709 + { 710 + "url": "kodi.mydomain.com" 711 + } 712 + ``` 713 + 714 + MS transforms this to: `http://kodi.mydomain.com:8080/jsonrpc` 715 + 716 + ```json 717 + { 718 + "url": "192.168.0.101:3456" 719 + } 720 + ``` 721 + 722 + MS transforms this to: `http://192.168.0.101:3456/jsonprc` 723 + 724 + ```json 725 + { 726 + "url": "mydomain.com:80/kodiReverse/jsonrpc" 727 + } 728 + ``` 729 + 730 + MS transforms this to: `http://mydomain.com:80/kodiReverse/jsonrpc` 731 + 732 + </details> 733 + 734 + #### Configuration 735 + 736 + <Tabs groupId="configType" queryString> 737 + <TabItem value="env" label="ENV"> 738 + | Environmental Variable | Required | Default | Description | 739 + |------------------------|----------|-------------------------------|----------------------------| 740 + | KODI_URL | Yes | http://localhost:8080/jsonrpc | The URL of the Kodi server | 741 + | KODI_USERNAME | No | | The username set | 742 + | KODI_PASSWORD | No | | The password set | 743 + </TabItem> 744 + <TabItem value="file" label="File"> 745 + See [`kodi.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/kodi.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FKodiSourceConfig/%23%2Fdefinitions%2FKodiData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 746 + </TabItem> 747 + <TabItem value="aio" label="AIO"> 748 + See [`kodi.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/kodi.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FKodiSourceConfig/%23%2Fdefinitions%2FKodiData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 749 + </TabItem> 750 + </Tabs> 751 + 752 + ### [WebScrobbler](https://web-scrobbler.com/) 753 + 754 + After installing the extension open the preferences/settings for it: 755 + 756 + * Under **Accounts** 757 + * **Add Webhook** 758 + * API URL: `http://localhost:9078/api/webscrobbler` 759 + * Application name: `(whatever you want)` 760 + 761 + Reload the extension after adding the webhook. 762 + 763 + * **On Firefox** - Only FQNs (domain.tld), `localhost`, and `127.0.0.1` are supported for API URL due to [firefox requiring https](https://github.com/web-scrobbler/web-scrobbler/issues/4183#issuecomment-1749222006) 764 + * **On Chromium-based Browsers** - Any domain will work for API URL 765 + * All Other browsers are untested 766 + 767 + ##### Multiple Users 768 + 769 + If you would like use multiple WebScrobbler sources they can be matched using a **slug** at the end of the **API URL.** This requires using [a file-based config.](./configuration?configType=file#webscrobbler) 770 + 771 + Example: 772 + 773 + In `webscrobbler.json` 774 + 775 + ```json 776 + [ 777 + { 778 + "name": "aUserWS", 779 + "clients": [ 780 + "client1Maloja" 781 + ], 782 + "data": { 783 + "slug": "usera" 784 + } 785 + }, 786 + { 787 + "name": "bUserWS", 788 + "clients": [ 789 + "client2Maloja" 790 + ], 791 + "data": { 792 + "slug": "userb" 793 + } 794 + } 795 + ] 796 + ``` 797 + 798 + * To use `aUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/usera` 799 + * To use `bUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/userb` 800 + 801 + :::note 802 + 803 + `http://localhost:9078/api/webscrobbler` is matched with the first source that _that does not have a slug defined._ 804 + 805 + ::: 806 + 807 + ###### Connectors Black/Whitelist 808 + 809 + MS can be configured to only scrobble, or NOT scrobble, from some WS connectors. Use the name of the website from the [supported websites](https://web-scrobbler.com/) or from the **Connectors** tab in the extension. 810 + 811 + :::note 812 + 813 + This affects **only** MS's behavior and does not affect the general connector behavior you have configured within the WebScrobbler extension. 814 + 815 + ::: 816 + 817 + #### Configuration 818 + 819 + <Tabs groupId="configType" queryString> 820 + <TabItem value="env" label="ENV"> 821 + | Environmental Variable | Required? | Default | Description | 822 + |------------------------|-----------|---------|--------------------------------------------------------------------------| 823 + | WS_ENABLE | No | | Set to 'true' to enable WS without needing to define other ENVs | 824 + | WS_WHITELIST | No | | Only scrobble from these WebScrobbler Connectors. Comma-delimited list | 825 + | WS_BLACKLIST | No | | Do not scrobble from these WebScrobbler Connectors. Comma-delimited list | 826 + </TabItem> 827 + <TabItem value="file" label="File"> 828 + See [`webscrobbler.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/webscrobbler.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FWebScrobblerSourceConfig/%23%2Fdefinitions%2FWebScrobblerData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 829 + </TabItem> 830 + <TabItem value="aio" label="AIO"> 831 + See [`webscrobbler.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/webscrobbler.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FWebScrobblerSourceConfig/%23%2Fdefinitions%2FWebScrobblerData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 832 + </TabItem> 833 + </Tabs> 834 + 835 + ### [Google Cast (Chromecast)](https://www.google.com/chromecast/built-in/) 836 + 837 + If your media device can be **Cast** to using this button ![Chromecast Icon](https://upload.wikimedia.org/wikipedia/commons/2/26/Chromecast_cast_button_icon.svg) on your phone/computer then multi-scrobbler can monitor it in order to scrobble music you play. 838 + 839 + 840 + :::note 841 + 842 + Google Cast support is **experimental**. You may experience crashes and errors while using this Source. Please open an issue if you experience problems and include all information detailed in the issue template to help debug your issue. 843 + 844 + ::: 845 + 846 + :::note 847 + 848 + This source relies on common, **basic** music data provided by the cast device which will always be less exhaustive than data parsed from full source integrations. If there is an existing [Source](#source-configurations) it is recommended to configure for it and blacklist the app on Google Cast, rather than relying solely on Google Cast for scrobbling. 849 + 850 + ::: 851 + 852 + #### Connecting Devices 853 + 854 + Cast devices can be manually configured using file-based configuration OR automatically discovered using **mDNS.** 855 + 856 + ###### mDNS Discovery 857 + 858 + The host machine running multi-scrobbler must be configured to allow [mDNS traffic on port 5353/UDP](https://book.hacktricks.xyz/network-services-pentesting/5353-udp-multicast-dns-mdns). 859 + 860 + :::info[OS Specific Instructions] 861 + 862 + <Tabs> 863 + <TabItem value="linux" label="Linux"> 864 + **Docker** 865 + 866 + The host machine must have [avahi-daemon](https://avahi.org/) running to circumvent limitations with DNS resolution due to musl in Alpine. Most major linux distributions package avahi and many have it built-in. Once avahi is running you must pass D-Bus and the avahi daemon socket to your container like so: 867 + 868 + ``` 869 + docker run ... -v /var/run/dbus:/var/run/dbus -v /var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket ... foxxmd/multi-scrobbler 870 + ``` 871 + 872 + **Flatpak/Nodejs** 873 + 874 + No additional steps are required. 875 + </TabItem> 876 + <TabItem value="windows" label="Windows"> 877 + **Docker** 878 + 879 + Unsupported at this time. 880 + 881 + **Nodejs** 882 + 883 + No additional steps are required. 884 + </TabItem> 885 + </Tabs> 886 + 887 + ::: 888 + 889 + #### What Media Does MS Scrobble? 890 + 891 + Cast devices report what type of media the current activity is [(see `metadata` property here)](https://developers.google.com/cast/docs/media/messages#MediaInformation). The reported type is dependent on the application playing the media to correctly report it, the cast device does not magically know what the media is. If an application does not report a type it is always classified as `unknown`. 892 + 893 + **By default, MS will only track media that is reported as `MusicTrack`.** 894 + 895 + ##### Allow Unknown Media Type 896 + 897 + Media with an Unknown (`Generic`) media type can be explicitly allowed by setting `"allowUnknownMedia": true` in the file-based configuration. This can also be configured to only allow unknown media types for specific applications by using a list of application names like: 898 + 899 + ```json5 title="chromecast.json" 900 + [ 901 + { 902 + "name": "MyCast", 903 + "type": "chromecast", 904 + "data": { 905 + // only allow unknown if app name contains any of these phrases 906 + "allowUnknownMedia": ["smarttube", "default media receiver"] 907 + }, 908 + } 909 + ] 910 + ``` 911 + 912 + ##### Forcing Media Tracking 913 + 914 + MS can be forced to track media from an application regardless of media type. This is useful if an application incorrectly reports a media type you are sure should be music. Set `"forceMediaRecognitionOn"` in the file-based configuration. to a list of application names that should always be tracked like: 915 + 916 + ```json5 917 + // in chromecast.json or config.json sources 918 + [ 919 + { 920 + "name": "MyCast", 921 + "type": "chromecast", 922 + "data": { 923 + // media from applications that contains these phrases will always be tracked, regardless of media type reported 924 + "forceMediaRecognitionOn": ["smarttube", "default media receiver"] 925 + }, 926 + } 927 + ] 928 + ``` 929 + 930 + 931 + #### Cast Troubleshooting 932 + 933 + Please include any/all logs with raw output if there are any errors encountered as this is critical to diagnosing issues. 934 + 935 + To diagnose bad/incomplete track information or strange MS player behavior please turn on **payload logging** and include log output of the source running to help diagnose this issue: 936 + 937 + ```json5 938 + // in chromecast.json or config.json sources 939 + [ 940 + { 941 + "name": "MyCast", 942 + "type": "chromecast", 943 + "data": { 944 + //... 945 + }, 946 + "options": { 947 + "logPayload": true 948 + } 949 + } 950 + ] 951 + ``` 952 + 953 + #### Configuration 954 + 955 + <Tabs groupId="configType" queryString> 956 + <TabItem value="env" label="ENV"> 957 + <Admonition type="note"> 958 + [Manually configuring cast device connections](#connecting-devices) is only available through file-based config. 959 + </Admonition> 960 + 961 + | Environmental Variable | Required? | Default | Description | 962 + |------------------------|-----------|---------|--------------------------------------------------------------------------------------| 963 + | CC_ENABLE | No | | Set to 'true' to enable Cast monitoring without needing to define other ENVs | 964 + | CC_WHITELIST_DEVICES | No | | Only scrobble from these Cast devices. Comma-delimited list. EX mini-home, family-tv | 965 + | CC_BLACKLIST_DEVICES | No | | Do not scrobble from these Cast devices. Comma-delimited list | 966 + | CC_WHITELIST_APPS | No | | Only scrobble from these casted Apps. Comma-delimited list. EX spotify, pandora | 967 + | CC_BLACKLIST_APPS | No | | Do not scrobble from these casted Apps. Comma-delimited list | 968 + </TabItem> 969 + <TabItem value="file" label="File"> 970 + See [`chromecast.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FChromecastSourceConfig/%23%2Fdefinitions%2FChromecastData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 971 + </TabItem> 972 + <TabItem value="aio" label="AIO"> 973 + See [`chromecast.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FChromecastSourceConfig/%23%2Fdefinitions%2FChromecastData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 974 + </TabItem> 975 + </Tabs> 976 + 977 + ### [Musikcube](https://musikcube.com) 978 + 979 + In order to use Musikcube configure it to accept [websocket connections](https://github.com/clangen/musikcube/wiki/remote-api-documentation) in **server setup**: 980 + 981 + * Enable the **Metadata Server** 982 + * Set a **Password** 983 + 984 + Both of these settings are found in _Musikcube -> (s)ettings -> server setup_ 985 + 986 + ![Server Setup](musikcube.jpg) 987 + 988 + The URL used by MS has the syntax: 989 + 990 + ``` 991 + [ws|wss]://HOST:[PORT] 992 + ``` 993 + 994 + The **port** is the same as shown in the server setup screenshot from above, under **metadata server enabled**. If no port is provided to MS it will default to `7905`. 995 + 996 + If no URL is provided to MS it will try to use `ws://localhost:7905` 997 + 998 + #### Configuration 999 + 1000 + <Tabs groupId="configType" queryString> 1001 + <TabItem value="env" label="ENV"> 1002 + | Environmental Variable | Required? | Default | Description | 1003 + |------------------------|-----------|-----------------------|--------------------------------------| 1004 + | `MC_URL` | No | `ws://localhost:7905` | Use port set for **metadata server** | 1005 + | `MC_PASSWORD` | Yes | | | 1006 + </TabItem> 1007 + <TabItem value="file" label="File"> 1008 + See [`musikcube.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMuikcubeSourceConfig/%23%2Fdefinitions%2FMuikcubeData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 1009 + </TabItem> 1010 + <TabItem value="aio" label="AIO"> 1011 + See [`musikcube.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/chromecast.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FMuikcubeSourceConfig/%23%2Fdefinitions%2FMuikcubeData?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fsource.json) 1012 + </TabItem> 1013 + </Tabs> 1014 + 1015 + ## Client Configurations 1016 + 1017 + ### [Maloja](https://github.com/krateng/maloja) 1018 + 1019 + #### Configuration 1020 + 1021 + <Tabs groupId="configType" queryString> 1022 + <TabItem value="env" label="ENV"> 1023 + | Environmental Variable | Required? | Default | Description | 1024 + |------------------------|-----------|---------|-------------------------------| 1025 + | `MALOJA_URL` | Yes | | Base URL of your installation | 1026 + | `MALOJA_API_KEY` | Yes | | Api Key | 1027 + </TabItem> 1028 + <TabItem value="file" label="File"> 1029 + See [`maloja.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/maloja.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FMalojaClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1030 + </TabItem> 1031 + <TabItem value="aio" label="AIO"> 1032 + See [`maloja.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/maloja.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FMalojaClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1033 + </TabItem> 1034 + </Tabs> 1035 + 1036 + ### [Last.fm](https://www.last.fm) 1037 + 1038 + [Register for an API account here.](https://www.last.fm/api/account/create) 1039 + 1040 + The Callback URL is actually specified by multi-scrobbler but to keep things consistent you should use 1041 + ``` 1042 + http://localhost:9078/lastfm/callback 1043 + ``` 1044 + or replace `localhost:9078` with your own base URL 1045 + 1046 + #### Configuration 1047 + 1048 + <Tabs groupId="configType" queryString> 1049 + <TabItem value="env" label="ENV"> 1050 + | Environmental Variable | Required? | Default | Description | 1051 + |------------------------|-----------|-----------------------------------------|-------------------------------------------------------------------------------| 1052 + | `LASTFM_API_KEY` | Yes | | Api Key from your API Account | 1053 + | `LASTFM_SECRET` | Yes | | Shared secret from your API Account | 1054 + | `LASTFM_REDIRECT_URI` | No | `http://localhost:9078/lastfm/callback` | Url to use for authentication. Must include `lastfm/callback` somewhere in it | 1055 + | `LASTFM_SESSION` | No | | Session id. Will be generated by authentication flow if not provided. | 1056 + </TabItem> 1057 + <TabItem value="file" label="File"> 1058 + See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1059 + </TabItem> 1060 + <TabItem value="aio" label="AIO"> 1061 + See [`lastfm.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/lastfm.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23/%23%2Fdefinitions%2FLastfmClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1062 + </TabItem> 1063 + </Tabs> 1064 + 1065 + ### [Listenbrainz](https://listenbrainz.org) 1066 + 1067 + You will need to run your own Listenbrainz server or have an account [on the official instance](https://listenbrainz.org/login/) 1068 + 1069 + On your [profile page](https://listenbrainz.org/profile/) find your **User Token** to use in the configuration. 1070 + 1071 + #### Configuration 1072 + 1073 + <Tabs groupId="configType" queryString> 1074 + <TabItem value="env" label="ENV"> 1075 + | Environmental Variable | Required? | Default | Description | 1076 + |------------------------|-----------|-------------------------------|---------------------------------| 1077 + | LZ_TOKEN | Yes | | User token from your LZ profile | 1078 + | LZ_USER | Yes | | Your LZ username | 1079 + | LZ_URL | No | https://api.listenbrainz.org/ | The base URL for the LZ server | 1080 + </TabItem> 1081 + <TabItem value="file" label="File"> 1082 + See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1083 + </TabItem> 1084 + <TabItem value="aio" label="AIO"> 1085 + See [`listenbrainz.json.example`](https://github.com/FoxxMD/multi-scrobbler/blob/master/config/listenbrainz.json.example) or [explore the schema with an example and live editor/validator](https://json-schema.app/view/%23%2Fdefinitions%2FListenBrainzClientConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Fclient.json) 1086 + </TabItem> 1087 + </Tabs> 1088 + 1089 + ## Monitoring 1090 + 1091 + multi-scrobbler supports some common webhooks and a healthcheck endpoint in order to monitor Sources and Clients for errors. 1092 + 1093 + ### Webhook Configurations 1094 + 1095 + Webhooks will **push** a notification to your configured servers on these events: 1096 + 1097 + * Source polling started 1098 + * Source polling retry 1099 + * Source polling stopped on error 1100 + * Scrobble client scrobble failure 1101 + 1102 + Webhooks are configured in the AIO [config.json](#configuration-types) file under the `webhook` top-level property. Multiple webhooks may be configured for each webhook type. EX: 1103 + 1104 + ```json5 1105 + { 1106 + "sources": [ 1107 + //... 1108 + ], 1109 + "clients": [ 1110 + //... 1111 + ], 1112 + "webhooks": [ 1113 + { 1114 + "name": "FirstGotifyServer", 1115 + "type": "gotify", 1116 + "url": "http://192.168.0.100:8070", 1117 + "token": "abcd" 1118 + }, 1119 + { 1120 + "name": "SecondGotifyServer", 1121 + "type": "gotify", 1122 + //... 1123 + }, 1124 + { 1125 + "name": "NtfyServerOne", 1126 + "type": "ntfy", 1127 + //... 1128 + }, 1129 + //... 1130 + ] 1131 + } 1132 + ``` 1133 + 1134 + #### [Gotify](https://gotify.net/) 1135 + 1136 + Refer to the [config schema for GotifyConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FGotifyConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1137 + 1138 + multi-scrobbler optionally supports setting message notification priority via `info` `warn` and `error` mappings. 1139 + 1140 + EX 1141 + 1142 + ```json 1143 + { 1144 + "type": "gotify", 1145 + "name": "MyGotifyFriendlyNameForLogs", 1146 + "url": "http://192.168.0.100:8070", 1147 + "token": "AQZI58fA.rfSZbm", 1148 + "priorities": { 1149 + "info": 5, 1150 + "warn": 7, 1151 + "error": 10 1152 + } 1153 + } 1154 + ``` 1155 + 1156 + #### [Ntfy](https://ntfy.sh/) 1157 + 1158 + Refer to the [config schema for NtfyConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FNtfyConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1159 + 1160 + multi-scrobbler optionally supports setting message notification priority via `info` `warn` and `error` mappings. 1161 + 1162 + EX 1163 + 1164 + ```json 1165 + { 1166 + "type": "ntfy", 1167 + "name": "MyNtfyFriendlyNameForLogs", 1168 + "url": "http://192.168.0.100:9991", 1169 + "topic": "RvOwKJ1XtIVMXGLR", 1170 + "username": "Optional", 1171 + "password": "Optional", 1172 + "priorities": { 1173 + "info": 3, 1174 + "warn": 4, 1175 + "error": 5 1176 + } 1177 + } 1178 + ``` 1179 + 1180 + #### [Apprise](https://github.com/caronc/apprise-api) 1181 + 1182 + Refer to the [config schema for AppriseConfig](https://json-schema.app/view/%23/%23%2Fdefinitions%2FAppriseConfig?url=https%3A%2F%2Fraw.githubusercontent.com%2FFoxxMD%2Fmulti-scrobbler%2Fmaster%2Fsrc%2Fbackend%2Fcommon%2Fschema%2Faio.json) 1183 + 1184 + multi-scrobbler supports [stateless](https://github.com/caronc/apprise-api?tab=readme-ov-file#stateless-solution) and [persistent storage](https://github.com/caronc/apprise-api?tab=readme-ov-file#persistent-storage-solution) endpoints as well as [tags](https://github.com/caronc/apprise-api?tab=readme-ov-file#tagging)/ 1185 + 1186 + EX 1187 + 1188 + ```json5 1189 + { 1190 + "type": "apprise", 1191 + "name": "MyAppriseFriendlyNameForLogs", 1192 + "host": "http://192.168.0.100:8080", 1193 + "urls": ["gotify://192.168.0.101:8070/MyToken"], // stateless endpoints 1194 + "keys": ["e90b20526808373353afad7fb98a201198c0c3e0555bea19f182df3388af7b17"], //persistent storage endpoints 1195 + "tags": ["my","optional","tags"] 1196 + } 1197 + ``` 1198 + 1199 + ### Health Endpoint 1200 + 1201 + An endpoint for monitoring the health of sources/clients is available at GET `http://YourMultiScrobblerDomain/health` 1202 + 1203 + * Returns `200 OK` when **everything** is working or `500 Internal Server Error` if **anything** is not 1204 + * The plain url (`/health`) aggregates status of **all clients/sources** -- so any failing client/source will make status return 500 1205 + * Use query params `type` or `name` to restrict client/sources aggregated IE `/health?type=spotify` or `/health?name=MyMaloja` 1206 + * On 500 the response returns a JSON payload with `messages` array that describes any issues 1207 + * For any clients/sources that require authentication `/health` will return 500 if they are **not authenticated** 1208 + * For sources that poll (spotify, yt music, subsonic) `/health` will 500 if they are **not polling**
-20
docsite/docs/development/dev-common.md
··· 8 8 9 9 # Development 10 10 11 - <details> 12 - 13 - <summary>Table of Contents</summary> 14 - 15 - <!-- TOC --> 16 - * [Architecture](#architecture) 17 - * [Project Setup](#project-setup) 18 - * [Common Development](#common-development) 19 - * [Config](#config) 20 - * [Concrete Class](#concrete-class) 21 - * [Stages](#stages) 22 - * [Stage: Build Data](#stage-build-data) 23 - * [Stage: Check Connection](#stage-check-connection) 24 - * [Stage: Test Auth](#stage-test-auth) 25 - * [Play Object](#play-object) 26 - * [Creating Clients and Sources](#creating-clients-and-sources) 27 - <!-- TOC --> 28 - 29 - </details> 30 - 31 11 ## Architecture 32 12 33 13 Multi-scrobbler is written entirely in [Typescript](https://www.typescriptlang.org/). It consists of a backend and frontend. The backend handles all Source/Client logic, mounts web server endpoints that listen for Auth callbacks and Source ingress using [expressjs](https://expressjs.com/), and serves the frontend. The frontend is a standalone [Vitejs](https://vitejs.dev/) app that communicates via API to the backend in order to render the dashboard.
-28
docsite/docs/development/dev-source.md
··· 5 5 title: Source Development/Tutorial 6 6 --- 7 7 8 - <details> 9 - 10 - <summary>Table of Contents</summary> 11 - 12 - <!-- TOC --> 13 - * [Scenario](#scenario) 14 - * [Minimal Implementation](#minimal-implementation) 15 - * [Define and Implement Config](#define-and-implement-config) 16 - * [Create CoolPlayer Source](#create-coolplayer-source) 17 - * [Initialize Source from Config](#initialize-source-from-config) 18 - * [Implement Play Object Transform](#implement-play-object-transform) 19 - * [Implement Stages](#implement-stages) 20 - * [Build Data](#build-data) 21 - * [Check Connection](#check-connection) 22 - * [Test Auth](#test-auth) 23 - * [Implement Polling](#implement-polling) 24 - * [Further Implementation](#further-implementation) 25 - * [Backlog](#backlog) 26 - * [Other Source Types](#other-source-types) 27 - * [Music History Source](#music-history-source) 28 - * [Non-Polling Source](#non-polling-source) 29 - * [Basic Source](#basic-source) 30 - * [Discovery](#discovery) 31 - * [Scrobbling](#scrobbling) 32 - <!-- TOC --> 33 - 34 - </details> 35 - 36 8 This document will provide a step-by-step guide for creating a (trivial) new Source in MS alongside describing what aspects of the Source need to be implemented based on the service you use. Before using this document you should review [Common Development](dev-common.md#common-development). 37 9 38 10 ## Scenario
+8 -8
docsite/docs/installation/installation.md
··· 43 43 44 44 * The web UI and API is served on port `9078`. This can be modified using the `PORT` environmental variable. 45 45 46 - #### Using [file-based](../configuration/configuration.md#file-based-configuration) configuration 46 + #### Using [file-based](../configuration/configuration.mdx?fileType=aio#configuration-types) configuration 47 47 48 48 ```shell 49 49 npm run start 50 50 ``` 51 51 52 - #### Using [env-based](../configuration/configuration.md#env-based-configuration) configuration 52 + #### Using [env-based](../configuration/configuration.mdx?fileType=env#configuration-types) configuration 53 53 54 54 ```shell 55 55 SPOTIFY_CLIENT_ID=yourId SPOTIFY_CLIENT_SECRET=yourSecret MALOJA_URL="http://domain.tld" node src/index.js ··· 74 74 75 75 ### Usage Examples 76 76 77 - #### Using [file-based](../configuration/configuration.md#file-based-configuration) configuration 77 + #### Using [file-based](../configuration/configuration.mdx?fileType=aio#configuration-types) configuration 78 78 79 79 The config directory for multi-scrobbler as a flatpak can be found under `/home/YourUser/.var/app/io.github.foxxmd.multiscrobbler/config` 80 80 ··· 82 82 flatpak run io.github.foxxmd.multiscrobbler 83 83 ``` 84 84 85 - #### Using [env-based](../configuration/configuration.md#env-based-configuration) configuration 85 + #### Using [env-based](../configuration/configuration.mdx?fileType=env#configuration-types) configuration 86 86 87 87 There are a few [options for running flatpak applications with temporary or permanent environmental variables.](https://ardasevinc.dev/launch-flatpak-apps-with-custom-args-and-environment-variables) 88 88 ··· 128 128 129 129 Optionally, when 130 130 131 - * using a [Source or Client](../configuration/configuration.md) that has a "Redirect URI" that you have not explicitly defined 131 + * using a [Source or Client](../configuration/configuration.mdx) that has a "Redirect URI" that you have not explicitly defined 132 132 * and 133 133 * using a bridge network or 134 134 * installing MS on a different machine than the one used to view the dashboard 135 135 136 - set the [Base URL](../configuration/configuration.md#base-url) as the IP of the host machine. (This is the IP you would use to view the dashboard in a browser) 136 + set the [Base URL](../configuration/configuration.mdx#base-url) as the IP of the host machine. (This is the IP you would use to view the dashboard in a browser) 137 137 138 138 * With docker: `-e BASE_URL="http://hostMachineIP"` (first port is the port on the host to use) 139 139 * With docker-compose: [see comments in docker-compose.yml](../../../docker-compose.yml) ··· 162 162 163 163 If installing on a different machine make sure all redirect URIs are defined or that you have set a [Base URL](#base-url). 164 164 165 - ### Using [env-based](../configuration/configuration.md#env-based-configuration) configuration 165 + ### Using [env-based](../configuration/configuration.mdx?fileType=env#configuration-types) configuration 166 166 167 167 ```bash 168 168 docker run -e "SPOTIFY_CLIENT_ID=yourId" -e "SPOTIFY_CLIENT_SECRET=yourSecret" -e "MALOJA_URL=http://domain.tld" -e "MALOJA_API_KEY=1234" -e "PUID=1000" -e "PGID=1000" -p 9078:9078 -v /path/on/host/config:/config foxxmd/multi-scrobbler 169 169 ``` 170 170 171 - ### Using [file-based](../configuration/configuration.md#file-based-configuration) configuration 171 + ### Using [file-based](../configuration/configuration.mdx?fileType=aio#configuration-types) configuration 172 172 173 173 ```bash 174 174 docker run -e "PUID=1000" -e "PGID=1000" -p 9078:9078 -v /path/on/host/config:/config foxxmd/multi-scrobbler