[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: Move Source configs to own files

FoxxMD (Oct 30, 2025, 6:35 PM UTC) 7ac3f33c 9b91f689

+1862 -2
-1
docsite/docs/configuration/configuration.mdx
··· 2378 2378 2379 2379 <Tabs groupId="configType" queryString> 2380 2380 <TabItem value="env" label="ENV"> 2381 - or <SchemaLink lower objectName="AzuracastSourceConfig"/> 2382 2381 | Environmental Variable | Required? | Default | Description | 2383 2382 | :--------------------- | :-------- | ------- | :----------------------- | 2384 2383 | `MCAST_URL` | Yes | | The Musiccast device URL |
+82
docsite/docs/configuration/sources/azuracast.mdx
··· 1 + --- 2 + title: Azuracast 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import AzuracastConfig from '!!raw-loader!@site/../config/azuracast.json.example'; 11 + import ShouldScrobble from "@site/src/components/snippets/_should-scrobble.mdx" 12 + 13 + :::tip[Scrobbling Threshold] 14 + 15 + Azuracast may not correctly report track length or position. If this is the case you should reduce the "listened to" **duration** using [Scrobble Thresholds](#scrobble-thresholds) so that multi-scrobbler scrobbles correctly. 16 + 17 + ::: 18 + 19 + The Azuracast server should have **Use High-Performance Now Playing Updates** enabled in _Administration -> System Settings_ 20 + 21 + #### URL 22 + 23 + The URL used by MS to connect to Azuracast has the syntax: 24 + 25 + ``` 26 + [ws|wss]://HOST:[PORT] 27 + ``` 28 + 29 + MS will automatically add the path required for websockets, [`/api/live/nowplaying/websocket`](https://www.azuracast.com/docs/developers/now-playing-data/#websockets), to your URL if none is provided. If you use a reverse proxy with a path-based URL or otherwise need a custom path to access the websockets path correctly then explicitly provide it. Examples: 30 + 31 + ``` 32 + URL From Config => MS Uses 33 + 34 + 'ws://192.168.0.101' => ws://192.168.0.101/api/live/nowplaying/websocket 35 + 'ws://azura.mydomain.com' => ws://azura.mydomain.com.com/api/live/nowplaying/websocket 36 + 'wss://mydomain.com/custom/azura/ws' => wss://mydomain.com/custom/azura/ws 37 + ``` 38 + 39 + #### Scrobble Behavior 40 + 41 + :::info 42 + 43 + <ShouldScrobble filename="azuracast"/> 44 + 45 + ::: 46 + 47 + Multi-scrobbler will set the default **scrobbling behavior** based on if either of these settings is configured: 48 + 49 + * live status (`AZURA_LIVE` or `monitorWhenLive`) or 50 + * listener count (`AZURA_LISTENERS_NUM` or `monitorWhenListeners`) 51 + 52 + If either is configured then MS will automatically scrobble based on when these conditions are met. 53 + 54 + If neither is configured automatic scrobble defaults to **off** and you should either manually initiate it or explicitly set the default behavior. 55 + 56 + ## Configuration 57 + 58 + <Tabs groupId="configType" queryString> 59 + <TabItem value="env" label="ENV"> 60 + | Environmental Variable | Required? | Default | Description | 61 + | :--------------------- | :-------- | :------ | ---------------------------------------------------------------------------------------------- | 62 + | `AZ_URL` | Yes | | Azuracast URL *without station name* | 63 + | `AZ_STATION` | Yes | | The station name shown on the public page | 64 + | `AZURA_LIVE` | No | Yes | Only scrobble when station status is ONLINE | 65 + | `AZURA_LISTENERS_NUM` | No | `true` | Only scrobble if station has any listeners (`true`) or listeners are equal-to/greater-than `X` | 66 + </TabItem> 67 + <TabItem value="file" label="File"> 68 + 69 + <CodeBlock title="CONFIG_DIR/azuracast.json" language="json5">{AzuracastConfig}</CodeBlock> 70 + 71 + 72 + or <SchemaLink lower objectName="AzuracastSourceConfig"/> 73 + </TabItem> 74 + <TabItem value="aio" label="AIO"> 75 + 76 + <AIOExample data={AzuracastConfig} name="azuracast"/> 77 + 78 + 79 + or <SchemaLink lower objectName="AzuracastSourceConfig"/> 80 + </TabItem> 81 + </Tabs> 82 +
+153
docsite/docs/configuration/sources/deezer.mdx
··· 1 + --- 2 + title: Deezer 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import DeezerConfig from '!!raw-loader!@site/../config/deezer.json.example'; 11 + import DeezerDeprecatedConfig from '!!raw-loader!@site/../config/deezer-deprecated.json.example'; 12 + 13 + <Tabs groupId="deezerSource" queryString> 14 + <TabItem value="arl" label="Unofficial ARL"> 15 + :::warning 16 + 17 + This Source uses unofficial methods to access Deezer data that are likely in violation of Deezer's TOS. Deezer may change or remove these methods at any time, breaking functionality. Use this Source at your own risk. 18 + 19 + ::: 20 + 21 + :::info 22 + 23 + This Source will work only if you have a **Premium** Deezer account. 24 + 25 + ::: 26 + 27 + ### Retrieve ARL 28 + 29 + The `arl` is a browser cookie that Deezer uses to store your login information. Multi-scrobbler uses the `arl` value to make authorized requests to Deezer's API where it can retrieve listening history. 30 + 31 + **After logging into Deezer**, use one of the methods below to retrieve the `arl` cookie value: 32 + 33 + <Tabs groupId="arlRetrival"> 34 + <TabItem value="chrome" label="Chrome"> 35 + 1. On deezer.com, press F12 to open the Developer Tools window. 36 + 2. Go to the Applications tab. Press the '>>' More tabs icon if it's hidden. 37 + 3. Under the Cookies Filter, click deezer.com, then the text bar name `arl`. 38 + 4. Copy all the contents shown in the **Cookie Value** pane. 39 + </TabItem> 40 + <TabItem value="firefox" label="Firefox"> 41 + 1. On deezer.com, hit Ctrl+Shift+I to open Developer Tools 42 + 2. Go to the Storage Tab, then expand Cookies in the sidebar and select deezer.com 43 + 3. Find the row with `arl` as the name, then double click the Value column and right click -> copy the value 44 + </TabItem> 45 + </Tabs> 46 + 47 + ## Configuration 48 + 49 + <Tabs groupId="configType" queryString> 50 + <TabItem value="env" label="ENV"> 51 + | Environmental Variable | Required? | Default | Description | 52 + | :--------------------- | --------- | ------- | ------------------------------------------------ | 53 + | `DEEZER_ARL` | Yes | | The ARL cookie value retrieved from your browser | 54 + </TabItem> 55 + <TabItem value="file" label="File"> 56 + 57 + <CodeBlock title="CONFIG_DIR/deezer.json" language="json5">{DeezerConfig}</CodeBlock> 58 + 59 + or <SchemaLink lower objectName="DeezerSourceConfig"/> 60 + </TabItem> 61 + <TabItem value="aio" label="AIO"> 62 + 63 + <AIOExample data={DeezerConfig} name="deezer"/> 64 + 65 + or <SchemaLink lower objectName="DeezerSourceConfig"/> 66 + </TabItem> 67 + </Tabs> 68 + 69 + ### Duplicate detection 70 + 71 + Third party integrations with Deezer (Sonos) may cause Deezer to [report the same track many times in listening history.](https://github.com/FoxxMD/multi-scrobbler/pull/296#issuecomment-2922374738) If you experience this issue modify your Deezer Source config (file-based only) to include the option `"fuzzyDiscoveryIgnore": "aggressive"` 72 + 73 + <details> 74 + 75 + <summary>deezer.json example</summary> 76 + 77 + ```json title="deezer.json" 78 + [ 79 + { 80 + "name": "MyDeezer", 81 + "data": { 82 + "arl": "UOsRPjT3U5Dhaaup3x...", 83 + }, 84 + "options": { 85 + "fuzzyDiscoveryIgnore": "aggressive" 86 + } 87 + } 88 + ] 89 + ``` 90 + </details> 91 + 92 + This option comes with some trade-offs: MS will aggressively detect repeated tracks within a window of time that should eliminate all duplicates. However, this will also prevent *intentionally* repeated tracks from being scrobbled. See [this thread](https://github.com/FoxxMD/multi-scrobbler/pull/296#issuecomment-2970417070) for more information on how this works. 93 + 94 + </TabItem> 95 + <TabItem value="official" label="Official API"> 96 + 97 + :::warning 98 + 99 + **This Source is DEPRECATED because Deezer has dropped official API support.** This Source will **not** be removed but no further support or fixes will be given. [See this issue for more discussion.](https://github.com/FoxxMD/multi-scrobbler/issues/175#issuecomment-2296776625) 100 + 101 + Users cannot create new applications on Deezer Developers and there is no guarantee existing applications will continue to work. 102 + 103 + As a workaround consider: 104 + 105 + * Using the alternative [Deezer Source that uses unofficial, internal API via ARL](./?deezerSource=arl#deezer) 106 + * Connect Deezer with Last.fm and then use [Last.fm as a Source](#lastfm-source) 107 + 108 + ::: 109 + 110 + Create a new application at [Deezer Developers](https://developers.deezer.com/myapps) 111 + 112 + * Application Domain must be the same as your multi-scrobbler domain. Default is `localhost:9078` 113 + * Redirect URL must end in `deezer/callback` 114 + * Default would be `http://localhost:9078/deezer/callback` 115 + 116 + After application creation you should have credentials displayed in the "My Apps" dashboard. You will need: 117 + 118 + * **Application ID** 119 + * **Secret Key** 120 + * **Redirect URL** (if not the default) 121 + 122 + **If no access token is provided...** 123 + 124 + 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. 125 + 126 + ###### Configuration 127 + 128 + <Tabs groupId="configType" queryString> 129 + <TabItem value="env" label="ENV"> 130 + | Environmental Variable | Required? | Default | Description | 131 + |------------------------|-----------|-----------------------------------------|-----------------------------------| 132 + | `DEEZER_CLIENT_ID` | Yes | | Your **Application ID** | 133 + | `DEEZER_CLIENT_SECRET` | Yes | | Your **Secret Key** | 134 + | `DEEZER_REDIRECT_URI` | No | `http://localhost:9078/deezer/callback` | URI must end in `deezer/callback` | 135 + </TabItem> 136 + <TabItem value="file" label="File"> 137 + 138 + <CodeBlock title="CONFIG_DIR/deezer.json" language="json5">{DeezerDeprecatedConfig}</CodeBlock> 139 + 140 + 141 + or <SchemaLink lower objectName="DeezerSourceConfig"/> 142 + </TabItem> 143 + <TabItem value="aio" label="AIO"> 144 + 145 + <AIOExample data={DeezerDeprecatedConfig} name="deezer"/> 146 + 147 + 148 + or <SchemaLink lower objectName="DeezerSourceConfig"/> 149 + </TabItem> 150 + </Tabs> 151 + 152 + </TabItem> 153 + </Tabs>
+184
docsite/docs/configuration/sources/google-cast.mdx
··· 1 + --- 2 + title: Google Cast (Chromecast) 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import ChromecastConfig from '!!raw-loader!@site/../config/chromecast.json.example'; 11 + 12 + 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. 13 + 14 + 15 + :::note 16 + 17 + 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. 18 + 19 + ::: 20 + 21 + :::note 22 + 23 + 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. 24 + 25 + ::: 26 + 27 + #### Connecting Devices 28 + 29 + Cast devices can be manually configured using file-based configuration OR automatically discovered using **mDNS.** 30 + 31 + ###### mDNS Discovery 32 + 33 + 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). 34 + 35 + <details> 36 + 37 + <summary>OS Specific Instructions</summary> 38 + 39 + <Tabs> 40 + <TabItem value="linux" label="Linux"> 41 + **Docker** 42 + 43 + 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: 44 + 45 + ``` 46 + docker run ... -v /var/run/dbus:/var/run/dbus -v /var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket ... foxxmd/multi-scrobbler 47 + ``` 48 + 49 + **Flatpak/Nodejs** 50 + 51 + No additional steps are required. 52 + </TabItem> 53 + <TabItem value="windows" label="Windows"> 54 + **Docker** 55 + 56 + Unsupported at this time. 57 + 58 + **Nodejs** 59 + 60 + No additional steps are required. 61 + </TabItem> 62 + </Tabs> 63 + 64 + </details> 65 + 66 + #### What Media Does MS Scrobble? 67 + 68 + 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`. 69 + 70 + **By default, MS will only track media that is reported as `MusicTrack`.** 71 + 72 + ##### Allow Unknown Media Type 73 + 74 + 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. 75 + 76 + <details> 77 + 78 + <summary>Example</summary> 79 + 80 + ```json5 title="chromecast.json" 81 + [ 82 + { 83 + "name": "MyCast", 84 + "type": "chromecast", 85 + "data": { 86 + // only allow unknown if app name contains any of these phrases 87 + "allowUnknownMedia": ["smarttube", "default media receiver"] 88 + }, 89 + } 90 + ] 91 + ``` 92 + 93 + </details> 94 + 95 + ##### Forcing Media Tracking 96 + 97 + 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. 98 + 99 + <details> 100 + 101 + <summary>Example</summary> 102 + 103 + ```json5 title="chromecast.json" 104 + [ 105 + { 106 + "name": "MyCast", 107 + "type": "chromecast", 108 + "data": { 109 + // media from applications that contains these phrases will always be tracked, regardless of media type reported 110 + "forceMediaRecognitionOn": ["smarttube", "default media receiver"] 111 + }, 112 + } 113 + ] 114 + ``` 115 + 116 + </details> 117 + 118 + #### Cast Troubleshooting 119 + 120 + Please include any/all logs with raw output if there are any errors encountered as this is critical to diagnosing issues. 121 + 122 + 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. Either enable in config using the below example OR enable [Debug Mode.](#debug-mode) 123 + 124 + <details> 125 + 126 + <summary>Example</summary> 127 + 128 + ```json5 title="chromecast.json" 129 + [ 130 + { 131 + "name": "MyCast", 132 + "type": "chromecast", 133 + "data": { 134 + //... 135 + }, 136 + "options": { 137 + "logPayload": true 138 + } 139 + } 140 + ] 141 + ``` 142 + 143 + </details> 144 + 145 + ## Configuration 146 + 147 + <Tabs groupId="configType" queryString> 148 + <TabItem value="env" label="ENV"> 149 + :::note 150 + [Manually configuring cast device connections](#connecting-devices) is only available through file-based config. 151 + ::: 152 + 153 + | Environmental Variable | Required? | Default | Description | 154 + |------------------------|-----------|---------|--------------------------------------------------------------------------------------| 155 + | CC_ENABLE | No | | Set to 'true' to enable Cast monitoring without needing to define other ENVs | 156 + | CC_WHITELIST_DEVICES | No | | Only scrobble from these Cast devices. Comma-delimited list. EX mini-home, family-tv | 157 + | CC_BLACKLIST_DEVICES | No | | Do not scrobble from these Cast devices. Comma-delimited list | 158 + | CC_WHITELIST_APPS | No | | Only scrobble from these casted Apps. Comma-delimited list. EX spotify, pandora | 159 + | CC_BLACKLIST_APPS | No | | Do not scrobble from these casted Apps. Comma-delimited list | 160 + </TabItem> 161 + <TabItem value="file" label="File"> 162 + 163 + <details> 164 + 165 + <summary>Example</summary> 166 + 167 + <CodeBlock title="CONFIG_DIR/chromecast.json" language="json5">{ChromecastConfig}</CodeBlock> 168 + 169 + </details> 170 + 171 + or <SchemaLink lower objectName="ChromecastSourceConfig"/> 172 + </TabItem> 173 + <TabItem value="aio" label="AIO"> 174 + <details> 175 + 176 + <summary>Example</summary> 177 + 178 + <AIOExample data={ChromecastConfig} name="chromecast"/> 179 + 180 + </details> 181 + 182 + or <SchemaLink lower objectName="ChromecastSourceConfig"/> 183 + </TabItem> 184 + </Tabs>
+97
docsite/docs/configuration/sources/icecast.mdx
··· 1 + --- 2 + title: Icecast 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import IcecastConfig from '!!raw-loader!@site/../config/icecast.json.example'; 11 + import ShouldScrobble from "@site/src/components/snippets/_should-scrobble.mdx" 12 + 13 + Parse metadata from any Icecast Station (streams) to use for scrobbling. 14 + 15 + :::note 16 + 17 + There is no standard format for presenting track information in an Icecast stream and the majority of streams that do include metadata only use a single string (`StreamTitle`) from which metadata can be parsed. 18 + 19 + Multi-scrobbler will do its best to parse Artist/Album/Track information from this data but the quality and consistency for this is solely based on how the Icecast broadcaster chooses to format their tracks. 20 + 21 + ::: 22 + 23 + :::note[Scrobbling Behavior] 24 + 25 + Multi-scrobbler cannot automatically determine if you are listening to a Station. Therefore, **automatic scrobbling for Icecast Sources is off by default.** 26 + 27 + Use [Should Scrobble Behavior](/configuration/sources/overview#should-scrobble-behavior) to initiate scrobbling or configure automatic scrobble. 28 + 29 + ::: 30 + 31 + :::tip[Scrobbling Threshold] 32 + 33 + Icecast does not report track lengths so multi-scrobbler cannot determine if it should scrobble based on percent played. You should instead set a shorter "listened to" **duration** using [Scrobble Thresholds.](/configuration/sources/overview#scrobble-thresholds) 34 + 35 + ::: 36 + 37 + 38 + #### URL and Sources 39 + 40 + The URL should be the URL you would use to stream audio. 41 + 42 + Additional sources are supported based on those found in [`icecast-metadata-stats`](https://github.com/eshaz/icecast-metadata-js/tree/main/src/icecast-metadata-stats#supported-status-apis). To use these with automatic parsing [based on the regular URL](https://github.com/eshaz/icecast-metadata-js/tree/main/src/icecast-metadata-stats#options) include a `sources` array in your config the same way as shown in `icecast-metadata-stats`: 43 + 44 + <details> 45 + 46 + <summary>Example</summary> 47 + 48 + ```json5 title="config.json" 49 + [ 50 + { 51 + "name": "myIcy", 52 + "enable": true, 53 + "data": { 54 + "url": "http://myIcecast.com/radio", 55 + "sources": ["icy", "ogg", "sevenhtml"] 56 + } 57 + } 58 + ] 59 + 60 + ``` 61 + </details> 62 + 63 + To manually set these sources include the same [`*Endpoint` options](https://github.com/eshaz/icecast-metadata-js/tree/main/src/icecast-metadata-stats#options) found in `icecast-metadata-stats`. 64 + 65 + If no `sources` are configured for multi-scrobbler it will automatically try to use `icy` and `ogg`. 66 + 67 + ## Configuration 68 + 69 + <Tabs groupId="configType" queryString> 70 + <TabItem value="env" label="ENV"> 71 + | Environmental Variable | Required? | Default | Description | 72 + | :--------------------- | :-------- | :------ | ----------- | 73 + | `ICECAST_URL` | Yes | | Icecast URL | 74 + </TabItem> 75 + <TabItem value="file" label="File"> 76 + <details> 77 + 78 + <summary>Example</summary> 79 + 80 + <CodeBlock title="CONFIG_DIR/icecast.json" language="json5">{IcecastConfig}</CodeBlock> 81 + 82 + </details> 83 + 84 + or <SchemaLink lower objectName="IcecastSourceConfig"/> 85 + </TabItem> 86 + <TabItem value="aio" label="AIO"> 87 + <details> 88 + 89 + <summary>Example</summary> 90 + 91 + <AIOExample data={IcecastConfig} name="icecast"/> 92 + 93 + </details> 94 + 95 + or <SchemaLink lower objectName="IcecastSourceConfig"/> 96 + </TabItem> 97 + </Tabs>
+67
docsite/docs/configuration/sources/jellyfin.mdx
··· 1 + --- 2 + title: Jellyfin 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JellyfinConfig from '!!raw-loader!@site/../config/jellyfin.json.example'; 11 + 12 + Must be using Jellyfin 10.7 or greater 13 + 14 + * Create an **API Key** for multi-scrobbler 15 + * In the Jellyfin desktop web UI Navigate to -> Administration -> Dashboard -> API Keys (`http://YOUR_JELLYIN_URL/web/index.html#!/apikeys.html`) 16 + * Click `+` button and create a new key with **App name** `multi-scrobbler` 17 + * Copy the created API Key value for use in configuration below 18 + 19 + 20 + It is **recommended** to use API Key + username but if you are not an admin for your Jellyfin instance you can also authenticate with your Jellyfin username and **password.** 21 + 22 + :::tip[Important Defaults] 23 + 24 + By default... 25 + 26 + * multi-scrobbler will **only** scrobble for the user authenticated with the API. 27 + * Allowed Users (`usersAllow` or `JELLYFIN_USERS_ALLOW`) are only necessary if you want to scrobble for additional users. 28 + * multi-scrobbler will **only** scrobble media found in Jellyfin libraries that were labelled as **Music.** 29 + * `librariesAllow` or `JELLYFIN_LIBRARIES_ALLOW` will override this 30 + * OR use `additionalAllowedLibraryTypes` to allow more types (like `mixed` or `book` for audiobooks) 31 + * multi-scrobbler will **only** scrobble media Jellyfin detects as **Audio.** 32 + * To force multi-scrobbler to scrobble when media is detected as **Unknown** use `"allowUnknown": true` in file/aio configuration. 33 + 34 + ::: 35 + 36 + #### Configuration 37 + 38 + <Tabs groupId="configType" queryString> 39 + <TabItem value="env" label="ENV"> 40 + | Environmental Variable | Required? | Default | Description | 41 + | -------------------------- | --------- | ------- | ------------------------------------------------------------------------------------------ | 42 + | `JELLYFIN_URL` | **Yes** | | The URL of the Jellyfin server IE `http://localhost:8096` | 43 + | `JELLYFIN_USER` | **Yes** | | The user to authenticate with the API | 44 + | `JELLYFIN_APIKEY` | No | | The API Key to use for authentication **(Must provide either apikey or password)** | 45 + | `JELLYFIN_PASSWORD` | No | | The password of the user to authenticate for. **(Must provide either apikey or password)** | 46 + | `JELLYFIN_USERS_ALLOW` | No | | Comma-separated list of usernames (from Jellyfin) to scrobble for | 47 + | `JELLYFIN_USERS_BLOCK` | No | | Comma-separated list of usernames (from Jellyfin) to disallow scrobble for | 48 + | `JELLYFIN_DEVICES_ALLOW` | No | | Comma-separated list of devices to scrobble from | 49 + | `JELLYFIN_DEVICES_BLOCK` | No | | Comma-separated list of devices to disallow scrobbles from | 50 + | `JELLYFIN_LIBRARIES_ALLOW` | No | | Comma-separated list of libraries to allow scrobbles from | 51 + | `JELLYFIN_LIBRARIES_BLOCK` | No | | Comma-separated list of libraries to disallow scrobbles from | 52 + </TabItem> 53 + <TabItem value="file" label="File"> 54 + 55 + <CodeBlock title="CONFIG_DIR/jellyfin.json" language="json5">{JellyfinConfig}</CodeBlock> 56 + 57 + or <SchemaLink lower objectName="JellyApiSourceConfig"/> 58 + 59 + </TabItem> 60 + <TabItem value="aio" label="AIO"> 61 + 62 + <AIOExample data={JellyfinConfig} name="jellyfin"/> 63 + 64 + 65 + or <SchemaLink lower objectName="JellyApiSourceConfig"/> 66 + </TabItem> 67 + </Tabs>
+76
docsite/docs/configuration/sources/jriver.mdx
··· 1 + --- 2 + title: JRiver 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JriverConfig from '!!raw-loader!@site/../config/jriver.json.example'; 11 + 12 + 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: 13 + 14 + * Tools -> Options -> Media Network 15 + * Check `Use Media Network to share this library...` 16 + * If you have `Authentication` checked you will need to provide the **Username** and **Password** in the ENV/File configuration below. 17 + 18 + ### URL 19 + 20 + The URL used to connect to JRiver, set in your [file config as `url`.](#jriver-config) The URL used to connect ultimately must be formed like this: 21 + 22 + ``` 23 + Syntax => [protocol]://[hostname]:[port]/[path] 24 + Default => http://localhost:52199/MCWS/v1/ 25 + ``` 26 + 27 + If any part of this URL is missing multi-scrobbler will use a default value. This also means that if any part of your URL is **not** standard you must explicitly define it. 28 + 29 + :::tip[Jriver Settings] 30 + 31 + * Make sure the port number matches what is found in `Advanced` section in the [Media Network](#jriver) options. 32 + * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 33 + 34 + ::: 35 + 36 + <details> 37 + <summary>URL Transform Examples</summary> 38 + 39 + Examples of a given `url` in your file config and the final URL multi-scrobbler will use to connect to JRiver: 40 + 41 + | `url` | Transformed URL | 42 + |------------------------------------------|---------------------------------------------| 43 + | (none set) | `http://localhost:52199/MCWS/v1/` | 44 + | `jriver.mydomain.com` | `http://jriver.mydomain.com:52199/MCWS/v1/` | 45 + | `192.168.0.101:3456` | `http://192.168.0.101:3456/MCWS/v1/` | 46 + | `mydomain.com:80/jriverReverse/MCWS/v1/` | `mydomain.com:80/jriverReverse/MCWS/v1/` | 47 + 48 + </details> 49 + 50 + ## Configuration 51 + 52 + <Tabs groupId="configType" queryString> 53 + <TabItem value="env" label="ENV"> 54 + <EnvType> 55 + | Environmental Variable | Required | Default | Description | 56 + |------------------------|----------|---------------------------------|------------------------------------------------| 57 + | JRIVER_URL | Yes | http://localhost:52199/MCWS/v1/ | The URL of the JRiver server | 58 + | JRIVER_USERNAME | No | | If authentication is enabled, the username set | 59 + | JRIVER_PASSWORD | No | | If authenticated is enabled, the password set | 60 + </EnvType> 61 + </TabItem> 62 + <TabItem value="file" label="File"> 63 + <FileType> 64 + <CodeBlock title="CONFIG_DIR/jriver.json" language="json5">{JriverConfig}</CodeBlock> 65 + 66 + or <SchemaLink lower objectName="JRiverSourceConfig"/> 67 + </FileType> 68 + </TabItem> 69 + <TabItem value="aio" label="AIO"> 70 + <AIOType> 71 + <AIOExample data={JriverConfig} name="jriver"/> 72 + 73 + or <SchemaLink lower objectName="JRiverSourceConfig"/> 74 + </AIOType> 75 + </TabItem> 76 + </Tabs>
+59
docsite/docs/configuration/sources/kodi.mdx
··· 1 + --- 2 + title: Kodi 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import KodiConfig from '!!raw-loader!@site/../config/kodi.json.example'; 11 + import Config from '@site/src/components/GenericConfiguration.mdx'; 12 + 13 + In order for multi-scrobbler to communicate with Kodi you must have the [Web Interface](https://kodi.wiki/view/Web_interface) enabled. This can be done in the Kodi GUI: 14 + 15 + * Settings -> Services -> Control 16 + * Check `Allow remote control via HTTP` 17 + * Ensure you have a **Username** and **Password** set, you will need to provide them in the ENV/File configuration below. 18 + 19 + ### URL 20 + 21 + The URL used to connect to Kodi, set in your [file config as `url`.](#kodi-config) The URL used to connect ultimately must be formed like this: 22 + 23 + ``` 24 + Syntax => [protocol]://[hostname]:[port]/[path] 25 + Default => http://localhost:8080/jsonrpc 26 + ``` 27 + 28 + If any part of this URL is missing multi-scrobbler will use a default value. This also means that if any part of your URL is **not** standard you must explicitly define it. 29 + 30 + :::tip[Kodi Settings] 31 + 32 + * Make sure the port number matches what is found in **Port** in the [Control](#kodi) section mentioned above. 33 + * If your installation is on the same machine but you cannot connect using `localhost` try `0.0.0.0` instead. 34 + 35 + ::: 36 + 37 + <details> 38 + <summary>URL Transform Examples</summary> 39 + 40 + Examples of a given `url` in your file config and the final URL multi-scrobbler will use to connect to Kodi: 41 + 42 + | `url` | Transformed URL | 43 + |---------------------------------------|----------------------------------------------| 44 + | (none set) | `http://localhost:8080/jsonrpc` | 45 + | `kodi.mydomain.com` | `http://kodi.mydomain.com:8080/jsonrpc` | 46 + | `192.168.0.101:3456` | `http://192.168.0.101:3456/jsonprc` | 47 + | `mydomain.com:80/kodiReverse/jsonrpc` | `http://mydomain.com:80/kodiReverse/jsonrpc` | 48 + 49 + </details> 50 + 51 + ## Configuration 52 + 53 + <Config config="KodiSourceConfig" fileContent={KodiConfig} name="kodi"> 54 + | Environmental Variable | Required | Default | Description | 55 + |------------------------|----------|-------------------------------|----------------------------| 56 + | KODI_URL | Yes | http://localhost:8080/jsonrpc | The URL of the Kodi server | 57 + | KODI_USERNAME | No | | The username set | 58 + | KODI_PASSWORD | No | | The password set | 59 + </Config>
+31
docsite/docs/configuration/sources/koito-source.mdx
··· 1 + --- 2 + title: Koito 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import KoitoConfig from '!!raw-loader!@site/../config/koito.json.example'; 11 + 12 + This Source monitors a Koito account's scrobble history and then re-scrobbles discovered tracks to configured [Clients.](/configuration/clients/overview) 13 + 14 + :::tip[Other Uses] 15 + 16 + To _scrobble to_ a Koito server, create a [Koito (Client)](/configuration/clients/koito) 17 + 18 + ::: 19 + 20 + See the [Koito (Client)](/configuration/clients/koito) configuration for general setup. The only difference for **Source** configuration: 21 + 22 + * Cannot be setup with ENV config 23 + * [File/AIO config](/configuration?configType=file#configuration-types) must include `"configureAs": "source"` 24 + 25 + #### Configuration 26 + 27 + <Config config="KoitoSourceConfig" fileContent={KoitoConfig} name="koito"> 28 + :::note 29 + You cannot use ENV variables shown in the [Koito Client config](/configuration/clients/koito) -- multi-scrobbler assumes Koito ENVs are always used for the **client** configuration. You must use the [File or AIO](/configuration?configType=file#configuration-types) config to setup Koito as a Source. 30 + ::: 31 + </Config>
+46
docsite/docs/configuration/sources/lastfm-endpoint.mdx
··· 1 + --- 2 + title: Lastfm (Endpoint) 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import LastfmEndpointConfig from '!!raw-loader!@site/../config/endpointlfm.json.example'; 11 + 12 + This Source enables multi-scrobbler to accept scrobbles from outside applications as if it was a Last.fm server. 13 + 14 + :::tip[Other Uses] 15 + 16 + * To **scrobble to** Last.fm, create a [Last.fm (Client)](/configuration/clients/lastfm) 17 + * To monitor and re-scrobble activity from your Last.fm account, create a [Last.fm (Source)](/configuration/sources/lastfm-source) 18 + 19 + ::: 20 + 21 + ### URL 22 + 23 + If a **slug** is **not** provided in configuration then multi-scrobbler will accept Last.fm scrobbles at 24 + 25 + ``` 26 + http://localhost:9078/2.0/ 27 + ``` 28 + 29 + which is the "standard" Last.fm server path for scrobbling 30 + 31 + Use a slug only if you need to setup multiple Last.fm Endpoint sources and cannot use different tokens. 32 + 33 + If a slug is used then the URL will be: 34 + 35 + ``` 36 + http://localhost:9078/api/lastfm/mySlug 37 + ``` 38 + 39 + ## Configuration 40 + 41 + <Config config="LastFMEndpointSourceConfig" fileContent={LastfmEndpointConfig} name="endpointlfm"> 42 + | Environmental Variable | Required? | Default | Description | 43 + | :--------------------- | :-------- | ------- | ------------------------------------------------------------------------------------------------------------------ | 44 + | `LFMENDPOINT_ENABLE` | No | | Use LFM Endpoint as a Source without any other configuration. Only required if slug/token are not provided as ENVs | 45 + | `LFM_SLUG` | No | | (Optional) The URL suffix to use for accepting LFM scrobbles | 46 + </Config>
+29
docsite/docs/configuration/sources/lastfm-source.mdx
··· 1 + --- 2 + title: Lastfm 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import LastfmConfig from '!!raw-loader!@site/../config/lastfm.json.example'; 11 + 12 + This Source **monitors your Last.fm scrobble history** and re-scrobbles new activity to configured [Clients.](/configuration/clients/overview) 13 + 14 + :::tip[Other Uses] 15 + 16 + * To **scrobble to** Last.fm, create a [Last.fm (Client)](/configuration/clients/lastfm) 17 + * To accept scrobbles from outside applications as if multi-scrobbler was Last.fm, create a [Last.fm (Endpoint)](/configuration/sources/lastfm-endpoint) 18 + 19 + ::: 20 + 21 + To configure this Source use the same registration instructions and configuration data shown in [Last.fm (Client)](/configuration/clients/lastfm) with the difference being `"configureAs": "source"` defined in the File/AIO configuration below. 22 + 23 + ## Configuration 24 + 25 + <Config config="LastfmSourceConfig" fileContent={LastfmConfig} name="lastfm"> 26 + :::note 27 + You cannot use ENV variables shown in the [Last.fm Client config](/configuration/clients/lastfm) -- multi-scrobbler assumes Last.fm ENVs are always used for the **client** configuration. You must use the [File or AIO](/configuration?configType=file#configuration-types) config to setup Last.fm as a Source. 28 + ::: 29 + </Config>
+56
docsite/docs/configuration/sources/listenbrainz-endpoint.mdx
··· 1 + --- 2 + title: Listenbrainz (Endpoint) 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import ListenbrainzEndpointConfig from '!!raw-loader!@site/../config/endpointlz.json.example'; 11 + 12 + This Source enables multi-scrobbler to accept scrobbles from outside applications as if it was a Listenbrainz server. 13 + 14 + :::tip[Other Uses] 15 + 16 + * To **scrobble to** Listenbrainz, create a [Listenbrainz (Client)](/configuration/clients/listenbrainz) 17 + * To monitor and re-scrobble activity from your Listenbrainz account, create a [Listenbrainz (Source)](/configuration/sources/listenbrainz-source) 18 + 19 + ::: 20 + 21 + ##### URL 22 + 23 + If a **slug** is **not** provided in configuration then multi-scrobbler will accept Listenbrainz scrobbles at 24 + 25 + ``` 26 + http://localhost:9078/1/submit-listens 27 + ``` 28 + 29 + which is the "standard" Listenbrainz server path for scrobbling. 30 + 31 + Use a slug only if you need to setup multiple Listenbrainz Endpoint sources and cannot use different tokens. 32 + 33 + If a slug is used then the URL will be: 34 + 35 + ``` 36 + http://localhost:9078/api/listenbrainz/mySlug 37 + ``` 38 + 39 + :::note 40 + Some Listenbrainz applications may require custom Listenbrainz URLs to be a real domain (`example.com`) and/or use SSL (`https://`). In this case you should setup multi-scrobbler behind a reverse proxy to support this functionality. It is out of the scope of this project to do this solely within multi-scrobbler. 41 + ::: 42 + 43 + ##### Token 44 + 45 + Most Listenbrainz clients require a token (Authentication Token) to be provided during setup. This value can be anything you want, just make sure to use the same value for `token` in your multi-scrobbler configuration for the endpoint. 46 + 47 + 48 + ## Configuration 49 + 50 + <Config config="ListenbrainzEndpointSourceConfig" fileContent={ListenbrainzEndpointConfig} name="endpointlz"> 51 + | Environmental Variable | Required? | Default | Description | 52 + | :--------------------- | :-------- | ------- | ----------------------------------------------------------------------------------------------------------------- | 53 + | `LZENDPOINT_ENABLE` | No | | Use LZ Endpoint as a Source without any other configuration. Only required if slug/token are not provided as ENVs | 54 + | `LZE_TOKEN` | No | | LZ "Authentication Token" you provided to the scrobbling application | 55 + | `LZE_SLUG` | No | | (Optional) The URL suffix to use for accepting LZ scrobbles | 56 + </Config>
+31
docsite/docs/configuration/sources/listenbrainz-source.mdx
··· 1 + --- 2 + title: Listenbrainz 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import ListenbrainzConfig from '!!raw-loader!@site/../config/listenbrainz.json.example'; 11 + 12 + This Source monitors a Listenbrainz account's scrobble history and then re-scrobbles discovered tracks to configured clients. 13 + 14 + :::tip[Other Uses] 15 + 16 + * To **scrobble to** a Listenbrainz server, create a [Listenbrainz (Client)](/configuration/clients/listenbrainz) 17 + * To accept scrobbles from outside applications as if multi-scrobbler was a Listenbrainz server, create a [Listenbrainz (Endpoint)](/configuration/sources/listenbrainz-endpoint) 18 + 19 + ::: 20 + 21 + You will need to run your own Listenbrainz server or have an account [on the official instance](https://listenbrainz.org/login/). 22 + 23 + On your [profile page](https://listenbrainz.org/profile/) find your **User Token** to use in the configuration. 24 + 25 + ## Configuration 26 + 27 + <Config config="ListenBrainzSourceConfig" fileContent={ListenbrainzConfig} name="listenbrainz"> 28 + :::note 29 + You cannot use ENV variables shown in the [Listenbrainz Client config](/configuration/clients/listenbrainz) -- multi-scrobbler assumes Listenbrainz ENVs are always used for the **client** configuration. You must use the [File or AIO](/configuration?configType=file#configuration-types) config to setup Listenbrainz as a Source. 30 + ::: 31 + </Config>
+29
docsite/docs/configuration/sources/maloja.mdx
··· 1 + --- 2 + title: Maloja 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import MalojaConfig from '!!raw-loader!@site/../config/maloja.json.example'; 11 + 12 + :::tip[Other Uses] 13 + 14 + To _scrobble to_ a Maloja server, create a [Maloja (Client)](/configuration/clients/maloja) 15 + 16 + ::: 17 + 18 + See the [Maloja (Client)](/configuration/clients/maloja) configuration for general setup. The only difference for **Source** configuration: 19 + 20 + * Cannot be setup with ENV config 21 + * [File/AIO config](/configuration?configType=file#configuration-types) must include `"configureAs": "source"` 22 + 23 + ## Configuration 24 + 25 + <Config config="MalojaSourceConfig" fileContent={MalojaConfig} name="maloja"> 26 + :::note 27 + You cannot use ENV variables shown in the [Maloja Client config](/configuration/clients/maloja) -- multi-scrobbler assumes Maloja ENVs are always used for the **client** configuration. You must use the [[File or AIO](/configuration?configType=file#configuration-types) config to setup Maloja as a Source. 28 + ::: 29 + </Config>
+102
docsite/docs/configuration/sources/mopidy.mdx
··· 1 + --- 2 + title: Mopidy 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import MopidyConfig from '!!raw-loader!@site/../config/mopidy.json.example'; 11 + 12 + 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/) 13 + 14 + multi-scrobbler can scrobble tracks played from any Mopidy backend source, regardless of where you listen to them. 15 + 16 + :::note 17 + 18 + You must have [Mopidy-HTTP extension](https://mopidy.com/ext/http) enabled for this integration to work. 19 + 20 + ::: 21 + 22 + #### URL 23 + 24 + The URL used to connect to the Mopidy server, set in your [file config as `url`.](#mopidy-config) The URL used to connect ultimately must be formed like this: 25 + 26 + ``` 27 + Syntax => [protocol]://[hostname]:[port]/[path] 28 + Default => ws://localhost:6680/mopidy/ws 29 + ``` 30 + 31 + If any part of this URL is missing multi-scrobbler will use a default value. This also means that if any part of your URL is **not** standard you must explicitly define it. 32 + 33 + :::tip[Mopidy Configuration] 34 + 35 + Make sure the hostname and port number match what is found in the Mopidy configuration file `mopidy.conf`: 36 + 37 + ```ini 38 + [http] 39 + hostname = localhost 40 + port = 6680 41 + ``` 42 + 43 + ::: 44 + 45 + <details> 46 + <summary>URL Transform Examples</summary> 47 + 48 + Examples of a given `url` in your file config and the final URL multi-scrobbler will use to connect to Mopidy: 49 + 50 + | `url` | Transformed URL | 51 + |--------------------------------|--------------------------------------------| 52 + | (none set) | `ws://localhost:6680/mopidy/ws` | 53 + | `mopidy.mydomain.com` | `ws://mopidy.mydomain.com:6680/mopidy/ws/` | 54 + | `192.168.0.101:3456` | `ws://192.168.0.101:3456/mopidy/ws/` | 55 + | `mopidy.mydomain.com:80/MOPWS` | `ws://mopidy.mydomain.com:80/MOPWS` | 56 + 57 + </details> 58 + 59 + 60 + ### URI Blacklist/Whitelist 61 + 62 + 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. 63 + 64 + <details> 65 + <summary>Example</summary> 66 + ```json 67 + { 68 + "uriBlacklist": ["soundcloud"] 69 + } 70 + ``` 71 + 72 + Will prevent multi-scrobbler from scrobbling any Mopidy track that start with a `uri` like `soundcloud:song:MySong-1234` 73 + </details> 74 + 75 + 76 + ### Album Blacklist 77 + 78 + 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. 79 + 80 + <details> 81 + <summary>Example</summary> 82 + ```json 83 + { 84 + "albumBlacklist": ["SoundCloud", "Mixcloud"] 85 + } 86 + ``` 87 + 88 + If a track would be scrobbled like 89 + ``` 90 + Album: Soundcloud, Track: My Cool Track, Artist: A Cool Artist 91 + ``` 92 + then multi-scrobbler will instead scrobble 93 + ``` 94 + Track: My Cool Track, Artist: A Cool Artist 95 + ``` 96 + </details> 97 + 98 + ## Configuration 99 + 100 + <Config config="MopidySourceConfig" fileContent={MopidyConfig} name="mopidy"> 101 + No ENV support 102 + </Config>
+28
docsite/docs/configuration/sources/mpd.mdx
··· 1 + --- 2 + title: MPD (Music Player Daemon) 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import MPDConfig from '!!raw-loader!@site/../config/mpd.json.example'; 11 + 12 + MS communicates with MPD using the [TCP client connection.](https://mpd.readthedocs.io/en/stable/user.html#client-connections) 13 + 14 + You should uncomment/create the following settings in your mpd config: 15 + 16 + ``` 17 + bind_to_address "any" # or a specific ipv4/v6 address 18 + port "6600" 19 + ``` 20 + 21 + ## Configuration 22 + 23 + <Config config="MPDSourceConfig" fileContent={MPDConfig} name="mpd"> 24 + | Environmental Variable | Required? | Default | Description | 25 + |------------------------|-----------|------------------|-------------| 26 + | `MPD_URL` | No | `localhost:6600` | | 27 + | `MPD_PASSWORD` | No | | | 28 + </Config>
+79
docsite/docs/configuration/sources/mpris.mdx
··· 1 + --- 2 + title: MPRIS 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import MPRISConfig from '!!raw-loader!@site/../config/mpris.json.example'; 11 + 12 + [MPRIS](https://specifications.freedesktop.org/mpris-spec/latest) is a standard interface for communicating with Music Players on **linux operating systems.** 13 + 14 + If you run Linux and have a notification tray that shows what media you are listening to, you likely have access to MPRIS. 15 + 16 + ![Notification Tray](../mpris.jpg) 17 + 18 + multi-scrobbler can listen to this interface and scrobble tracks played by **any media player** that communicates to the operating system with MPRIS. 19 + 20 + ##### Host Setup 21 + 22 + MPRIS communication requires multi-scrobbler to have access to the host's dbus-daemon. 23 + 24 + <Tabs groupId="dbus" queryString> 25 + <TabItem value="local" label="Local"> 26 + If multi-scrobbler is running as a [**Local Installation**](../../installation/installation.mdx#nodejs), directly with node/npm, on the same host as MPRIS then no setup is required. 27 + 28 + Remote setup is also possible, see the **Remote Unix Socket** section in the Docker tab. 29 + </TabItem> 30 + <TabItem value="docker" label="Docker"> 31 + If multi-scrobbler is running as a [**Docker Container**](../../installation/installation.mdx#docker) some modifications are required... 32 + 33 + ##### Local Unix Socket 34 + 35 + The most secure way is to **run a multi-scrobbler container on the same host as MPRIS.** In this scenario you can simply mount the **user session** dbus unix socket into the container. Make sure [`PUID` and `PGID` ENVs are configured](../installation/#linux-host) so the container has permissions to access the socket. Then, modify your compose stack with these additional values: 36 + 37 + ```yaml title="docker-compose.yaml" 38 + 39 + environment: 40 + - DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/UID/bus 41 + 42 + volumes: 43 + - /run/user/UID/bus:/run/user/UID/bus:ro 44 + ``` 45 + 46 + ##### Remote Unix Socket 47 + 48 + :::warning 49 + 50 + This method is **insecure.** You should not expose dbus over a network unless access to the port is restricted and the network is trusted. 51 + 52 + ::: 53 + 54 + Use [`socat`](https://linux.die.net/man/1/socat) to bidirectionally relay communication from the host's dbus socket to a listening TCP port. 55 + 56 + To make dbus for user with uid `1000` available on port `6644`: 57 + 58 + ```shell 59 + socat TCP-LISTEN:6644,reuseaddr,fork UNIX-CONNECT:/run/user/1000/bus 60 + ``` 61 + 62 + Then, add the following value to multi-scrobbler's ENVs: 63 + 64 + ``` 65 + DBUS_SESSION_BUS_ADDRESS=tcp:host=yourHostIP,port=6644 66 + ``` 67 + 68 + </TabItem> 69 + </Tabs> 70 + 71 + ## Configuration 72 + 73 + <Config config="MPRISSourceConfig" fileContent={MPRISConfig} name="mpris"> 74 + | Environmental Variable | Required? | Default | Description | 75 + |------------------------|-----------|---------|----------------------------------------------------------------------------------| 76 + | MPRIS_ENABLE | No | | Use MPRIS as a Source (useful when you don't need any other options) | 77 + | MPRIS_BLACKLIST | No | | Comma-delimited list of player names not to scrobble from | 78 + | MPRIS_WHITELIST | No | | Comma-delimited list of players names to ONLY scrobble from. Overrides blacklist | 79 + </Config>
+38
docsite/docs/configuration/sources/musikcube.mdx
··· 1 + --- 2 + title: Musikcube 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import MusikcubeConfig from '!!raw-loader!@site/../config/musikcube.json.example'; 11 + 12 + In order to use [Musikcube](https://musikcube.com) configure it to accept [websocket connections](https://github.com/clangen/musikcube/wiki/remote-api-documentation) in **server setup**: 13 + 14 + * Enable the **Metadata Server** 15 + * Set a **Password** 16 + 17 + Both of these settings are found in _Musikcube -> (s)ettings -> server setup_ 18 + 19 + ![Server Setup](../musikcube.jpg) 20 + 21 + The URL used by MS has the syntax: 22 + 23 + ``` 24 + [ws|wss]://HOST:[PORT] 25 + ``` 26 + 27 + 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`. 28 + 29 + If no URL is provided to MS it will try to use `ws://localhost:7905` 30 + 31 + ## Configuration 32 + 33 + <Config config="MusikcubeSourceConfig" fileContent={MusikcubeConfig} name="musikcube"> 34 + | Environmental Variable | Required? | Default | Description | 35 + |------------------------|-----------|-----------------------|--------------------------------------| 36 + | `MC_URL` | No | `ws://localhost:7905` | Use port set for **metadata server** | 37 + | `MC_PASSWORD` | Yes | | | 38 + </Config>
+79
docsite/docs/configuration/sources/plex.mdx
··· 1 + --- 2 + title: Plex 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import AzuracastConfig from '!!raw-loader!@site/../config/azuracast.json.example'; 11 + import PlexConfig from '!!raw-loader!@site/../config/plex.json.example'; 12 + 13 + Find your [**Plex Token**](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/) and make note of the **URL** and **Port** used to connect to your Plex instance. 14 + 15 + <details> 16 + 17 + <summary>Allowed Users and Defaults</summary> 18 + 19 + **Multi-scrobbler will automatically scrobble for these users by default:** 20 + 21 + * The User authenticated with the Plex Token 22 + * and the **Local User** 23 + 24 + The Local User (`PLEX_LOCAL_USER`) is how Plex identifies anyone directly accessing the Plex UI from a local IP (who does not need to login). 25 + 26 + To allow MS to scrobble for other users use `usersAllow` or `PLEX_USERS_ALLOW` (env) from the below configuration docs. However, because you are overriding the default settings you must also explicitly list the authenticated user and the Local User if you want them to also be able to scrobble. 27 + 28 + <details> 29 + 30 + <summary>Examples</summary> 31 + 32 + ###### Defaults 33 + 34 + If `usersallow` and `PLEX_USERS_ALLOW` are not defined then the Plex Token authenticated User and Local User will be scrobbled for. 35 + 36 + 37 + ###### Only A Specific User 38 + 39 + * `"usersallow": ["SomeUser"]` or 40 + * `PLEX_USERS_ALLOW: SomeUser` 41 + 42 + Only the Plex user `SomeUser` will be scrobbled for. The Plex Token authenticated user and the Local User will not be scrobbled for. 43 + 44 + ###### A Specific User + Defaults 45 + 46 + (Assuming the plex authenticated user is `FoxxMD`) 47 + 48 + * `"usersallow": ["FoxxMD", "PLEX_LOCAL_USER", "SomeUser"]` or 49 + * `PLEX_USERS_ALLOW: FoxxMD,PLEX_LOCAL_USER,SomeUser` 50 + 51 + The Plex user SomeUser, the Plex Token authenticated user (FoxxMD) and the Local User will be scrobbled for. 52 + 53 + </details> 54 + 55 + </details> 56 + 57 + <details> 58 + 59 + <summary>Allowed Libraries and Defaults</summary> 60 + 61 + By default multi-scrobbler will only scrobble media found in Plex libraries that are labelled as **Music.** 62 + * `librariesAllow` or `PLEX_LIBRARIES_ALLOW` will override this 63 + 64 + </details> 65 + 66 + #### Configuration 67 + 68 + <Config config="PlexApiSourceConfig" fileContent={PlexConfig} name="plex"> 69 + | Environmental Variable | Required? | Default | Description | 70 + | ---------------------- | --------- | ------- | ---------------------------------------------------------------------- | 71 + | `PLEX_URL` | **Yes** | | The URL of the Plex server IE `http://localhost:32400` | 72 + | `PLEX_TOKEN` | **Yes** | | The **Plex Token** to use with the API | 73 + | `PLEX_USERS_ALLOW` | No | | Comma-separated list of usernames (from Plex) to scrobble for | 74 + | `PLEX_USERS_BLOCK` | No | | Comma-separated list of usernames (from Plex) to disallow scrobble for | 75 + | `PLEX_DEVICES_ALLOW` | No | | Comma-separated list of devices to scrobble from | 76 + | `PLEX_DEVICES_BLOCK` | No | | Comma-separated list of devices to disallow scrobbles from | 77 + | `PLEX_LIBRARIES_ALLOW` | No | | Comma-separated list of libraries to allow scrobbles from | 78 + | `PLEX_LIBRARIES_BLOCK` | No | | Comma-separated list of libraries to disallow scrobbles from | 79 + </Config>
+105
docsite/docs/configuration/sources/spotify.mdx
··· 1 + --- 2 + title: Spotify 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import SpotifyConfig from '!!raw-loader!@site/../config/spotify.json.example'; 11 + 12 + <details> 13 + 14 + <summary>Spotify and Automix</summary> 15 + 16 + 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. 17 + 18 + </details> 19 + 20 + #### Authenticate Spotify with Multi-Scrobbler 21 + 22 + To access your Spotify history you must [create a Spotify App](https://developer.spotify.com/dashboard) to get a 23 + Client ID/Secret. 24 + 25 + 1. **Login to https://developer.spotify.com** with your existing Spotify account and accept Developer Terms 26 + 27 + 2. Navigate to your Spotify Developer [Dashboard](https://developer.spotify.com/dashboard) and start the **Create App** process 28 + 29 + 3. Determine the correct **Redirect URI** to use and set it in your App settings 30 + 31 + <details> 32 + 33 + <summary>Redirect URI Instructions</summary> 34 + 35 + A Redirect URI is the URL that Spotify will navigate your **browser** to after you complete authorization. The URL will contain the code necessary for multi-scrobbler to get a Spotify access token. 36 + 37 + Spotify [**no longer allows insecure URIs**](https://developer.spotify.com/documentation/web-api/tutorials/migration-insecure-redirect-uri) (start with `http://`) unless the address is `127.0.0.1` -- so `localhost` and internal IPs (`192.168.0.xxx`) no longer work. 38 + 39 + Use **one** of the following methods to specify a valid Redirect URI and complete Spotify authentication with multi-scrobbler: 40 + 41 + <Tabs groupId="spotifyRedirect" queryString> 42 + <TabItem value="https" label="HTTPS"> 43 + **Use a domain you control, with SSL certificates/HTTPS enabled, to create a valid redirect URI.** 44 + 45 + For example, if you are already running multi-scrobbler behind a reverse proxy (nginx/traefik/caddy) at `https://scrobbler.mydomain.com` then set the Spotify Redirect URI for your Spotify App, and multi-scrobbler `SPOTIFY_REDIRECT_URI` ENV, to `https://scrobbler.mydomain.com/callback` 46 + 47 + Alternatively, if multi-scrobbler is not accessible behind your domain, then use the [**Echo**](./?spotifyRedirect=echo#spotify) method with your own domain instead of 127.0.0.1. 48 + </TabItem> 49 + <TabItem value="local" label="Run MS Locally"> 50 + **Run multi-scrobbler, configured for a Spotify Source, from the same machine as your browser in order to get credentials.** 51 + 52 + In this scenario you can use `http://127.0.0.1:9078/callback` as the Spotify Redirect URI and multi-scrobbler `SPOTIFY_REDIRECT_URI` ENV. 53 + 54 + After completing authentication, copy the contents of local multi-scrobbler's [configuration folder](../installation/installation.mdx#storage) to the final location of where multi-scrobbler will be run. 55 + </TabItem> 56 + <TabItem value="echo" label="Echo"> 57 + **Use a docker container on the same machine your browser is on to "intercept" the callback URL from Spotify authentication, then manually finish the process by changing the domain to your multi-scrobbler instance.** 58 + 59 + 60 + 1. Create a container on the same machine as your browser using the [`mendhak/http-https-echo:36`](https://github.com/mendhak/docker-http-https-echo) image. This container runs a simple HTTP server that echos back any request it recieves. 61 + 62 + ```shell 63 + docker run --rm -p 127.0.0.1:5079:8080 mendhak/http-https-echo:36 64 + ``` 65 + 66 + 2. Set the Spotify Redirect URI and multi-scrobbler `SPOTIFY_REDIRECT_URI` ENV as `http://127.0.0.1:5079/callback` 67 + 68 + 3. In [Authenticate Spotify with Multi-Scrobbler](#authenticate-spotify-with-multi-scrobbler) (outside these Redirect Instructions) go to **Step 4** and continue the instructions 69 + 70 + Eventually, Spotify will redirect you to a web page with a URL like `http://127.0.0.1:5079/callback?code=xxxxxx...` 71 + 72 + ![echo](../echo.png) 73 + 74 + 4. In the URL, replace `127.0.0.1:5079` with the address/IP for your multi-scrobbler instance so the URL is similar to `http://192.168.0.101:9078/callback?code=xxxxxx...`. Then navigate to this URL to complete authentication. 75 + 76 + </TabItem> 77 + 78 + <TabItem value="msEcho" label="Echo from echo.multi-scrobbler.app"> 79 + For your convenience, I run the [`mendhak/http-https-echo:36`](https://github.com/mendhak/docker-http-https-echo) container from the [**Echo**](./?spotifyRedirect=echo#spotify) approach on a domain I, the multi-scrobbler developer [FoxxMD](https://github.com/FoxxMD), control and self-host. Please be aware: 80 + 81 + * I **do not collect personal data** or any querystrings/data sent in requests to this site 82 + * It's **not possible** for me to use the code sent by Spotify to this URL without also having your Client ID/Secret 83 + * However, there is **always** risk involved with trusting a service you do not control. Evaluate the risk of using this site for yourself. 84 + 85 + Use the [**Echo**](./?spotifyRedirect=echo#spotify) approach, starting from **Step 2**, with **https://echo.multi-scrobbler.app/callback** as Spotify Redirect URI and multi-scrobbler `SPOTIFY_REDIRECT_URI` ENV. 86 + </TabItem> 87 + </Tabs> 88 + 89 + </details> 90 + 91 + 4. Save your new App, then copy the Client ID/Secret from the App's Basic Information page. 92 + 93 + 5. Add the Client ID, Secret, and Redirect URI to the respective field/ENV in the [configuration section below](#spotify-config) 94 + 95 + 6. Start multi-scrobbler, then visit the Web Dashboard and click **(Re)authenticate** on the Spotify card to start the auth process 96 + 97 + ## Configuration 98 + 99 + <Config config="SpotifySourceConfig" fileContent={SpotifyConfig} name="spotify"> 100 + | Environmental Variable | Required? | Default | Description | 101 + |----------------------------|-----------|----------------------------------|----------------------------------------------------| 102 + | `SPOTIFY_CLIENT_ID` | Yes | | | 103 + | `SPOTIFY_CLIENT_SECRET` | Yes | | | 104 + | `SPOTIFY_REDIRECT_URI` | No | `http://localhost:9078/callback` | URI must end in `callback` | 105 + </Config>
+31
docsite/docs/configuration/sources/subsonic.mdx
··· 1 + --- 2 + title: Subsonic 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import SubsonicConfig from '!!raw-loader!@site/../config/subsonic.json.example'; 11 + 12 + This Source can be used 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/)) 13 + 14 + :::warning[Known Issues] 15 + 16 + * Multiple artists are reported as one value and cannot be separated 17 + * If using [Airsonic Advanced](https://github.com/airsonic-advanced/airsonic-advanced) the password used (under **Credentials**) must be **Decodable** 18 + 19 + ::: 20 + 21 + Use the optional `usersAllow` property with **File** or **AIO** configuration to restrict scrobbling to a list of defined users. 22 + 23 + ## Configuration 24 + 25 + <Config config="SubsonicSourceConfig" fileContent={SubsonicConfig} name="subsonic"> 26 + | Environmental Variable | Required? | Default | Description | 27 + |------------------------|-----------|---------|--------------------------------------| 28 + | `SUBSONIC_USER` | Yes | | | 29 + | `SUBSONIC_PASSWORD` | Yes | | | 30 + | `SUBSONIC_URL` | Yes | | Base url of your subsonic-api server | 31 + </Config>
+94
docsite/docs/configuration/sources/vlc.mdx
··· 1 + --- 2 + title: VLC 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JsonConfig from '!!raw-loader!@site/../config/vlc.json.example'; 11 + 12 + MS communicates with [VLC](https://www.videolan.org/vlc/) using the [Web (`http`) interface module](https://wiki.videolan.org/VLC_HTTP_requests/) 13 + 14 + #### Enable HTTP Interface 15 + 16 + Open VLC: 17 + 18 + * **Tools** Menu -> Preferences 19 + * In the bottom left change **Show Settings** from `Simple` to `All` 20 + * In the updated window select `Interface -> Main interfaces` 21 + * In the **Extra interface modules** section enable **Web** and verify that `http` is shown in the textbox 22 + * Select `Interface -> Main interfaces -> Lua` 23 + * In Lua HTTP -> Password -> set a password in this box 24 + * Click **Save** at the bottom to persist your changes 25 + * Restart VLC 26 + * Verify the HTTP interface is accessible by navigating to `http://localhost:8080` in your browser 27 + 28 + If the interface is accessible, after typing in your password, VLC is now ready to be used by MS. 29 + 30 + ##### Setting VLC Interface and Port 31 + 32 + These can be set by starting VLC from command line with specific options: 33 + 34 + * `vlc --http-host yourHostIp:yourPort` or 35 + * `vlc --http-port yourPort` or 36 + * modify the configuration file for VLC by editing keys with the same values as from the command line (`http-host` and `http-port`) 37 + 38 + 39 + #### Filename Parsing 40 + 41 + If the file being played in VLC does not have ID3 tags/metadata information multi-scrobbler can attempt to extract artist, title, and album information from the raw filename using regular expressions. Mutli-scrobbler will only do this if there is **no other information** reported by VLC about these fields. 42 + 43 + To extract this information use [named capture groups](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group) in your expression matching the field that should be extracted: `artist` `title` and/or `album`. MS accepts multiple expressions, the first one that matches a filename will be used. 44 + 45 + Example usage in [a file-based config:](./?configType=file#webscrobbler-config) 46 + 47 + ```json5 title="config/vlc.json" {10-15} 48 + [ 49 + { 50 + "name": "MyVlc", 51 + "enable": true, 52 + "data": { 53 + // ... 54 + }, 55 + "options": { 56 + "filenamePatterns": [ 57 + // Extracts artist and title from filenames that look like: 58 + // My Artist - My Cool title.mp4 59 + "/^\\s*(?<artist>.+?) - (?<title>.+?)\\.\\w+$/i" 60 + ], 61 + // logs to DEBUG when MS tries to extract data from a filename 62 + "logFilenamePatterns": true, 63 + } 64 + } 65 + ] 66 + ``` 67 + 68 + #### Vlc Information Reporting 69 + 70 + If you find that VLC is incorrectly reporting track information (in its interface) but multi-scrobbler is not parsing it correctly it may be due to the _name_ of the fields VLC is reporting. mutli-scrobbler uses the most common field name but does not cover all use cases. Before reporting an issue please turn on metadata logging and include output from your logs while it is turned on: 71 + 72 + ```json5 title="config/vlc.json" {9-9} 73 + [ 74 + { 75 + "name": "MyVlc", 76 + "enable": true, 77 + "data": { 78 + // ... 79 + }, 80 + "options": { 81 + "dumpVlcMetadata": true 82 + } 83 + } 84 + ] 85 + ``` 86 + 87 + ## Configuration 88 + 89 + <Config config="VLCSourceConfig" fileContent={JsonConfig} name="vlc"> 90 + | Environmental Variable | Required? | Default | Description | 91 + |------------------------|------------|------------------|-------------| 92 + | `VLC_URL` | No | `localhost:8080` | | 93 + | `VLC_PASSWORD` | Yes | | | 94 + </Config>
+95
docsite/docs/configuration/sources/webscrobbler.mdx
··· 1 + --- 2 + title: Webscrobbler 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JsonConfig from '!!raw-loader!@site/../config/webscrobbler.json.example'; 11 + 12 + After installing the [Webscrobbler extension](https://web-scrobbler.com/) open the preferences/settings for it: 13 + 14 + * Under **Accounts** 15 + * **Add Webhook** 16 + * API URL: `[YourMultiScrobblerInstance]/api/webscrobbler` EX `http://localhost:9078/api/webscrobbler` 17 + * Application name: `(whatever you want)` 18 + 19 + Reload the extension after adding the webhook. 20 + 21 + :::note 22 + 23 + * **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) 24 + * **On Chromium-based Browsers** - Any domain will work for API URL 25 + * All other browsers are untested 26 + 27 + ::: 28 + 29 + :::warning 30 + 31 + Multi-scrobbler is **not** designed to be publicly accessible from the internet. To use Webscrobbler outside your local network you should be accessing MS through a VPN or through a reverse proxy with some kind of authentication (though this is still not recommended). 32 + 33 + ::: 34 + 35 + ### Multiple Users 36 + 37 + 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#configuration-types) 38 + 39 + <details> 40 + 41 + <summary>Example</summary> 42 + 43 + ```json title="webscrobbler.json" 44 + [ 45 + { 46 + "name": "aUserWS", 47 + "clients": [ 48 + "client1Maloja" 49 + ], 50 + "data": { 51 + "slug": "usera" 52 + } 53 + }, 54 + { 55 + "name": "bUserWS", 56 + "clients": [ 57 + "client2Maloja" 58 + ], 59 + "data": { 60 + "slug": "userb" 61 + } 62 + } 63 + ] 64 + ``` 65 + 66 + * To use `aUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/usera` 67 + * To use `bUserWS` source set **API URL** to `http://localhost:9078/api/webscrobbler/userb` 68 + 69 + :::tip 70 + 71 + `http://localhost:9078/api/webscrobbler` is matched with the first source that _that does not have a slug defined._ 72 + 73 + ::: 74 + 75 + </details> 76 + 77 + ### Connectors Black/Whitelist 78 + 79 + 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. 80 + 81 + :::note 82 + 83 + This affects **only** MS's behavior and does not affect the general connector behavior you have configured within the WebScrobbler extension. 84 + 85 + ::: 86 + 87 + ## Configuration 88 + 89 + <Config config="WebscrobblerSourceConfig" fileContent={JsonConfig} name="webscrobbler"> 90 + | Environmental Variable | Required? | Default | Description | 91 + |------------------------|-----------|---------|--------------------------------------------------------------------------| 92 + | WS_ENABLE | No | | Set to 'true' to enable WS without needing to define other ENVs | 93 + | WS_WHITELIST | No | | Only scrobble from these WebScrobbler Connectors. Comma-delimited list | 94 + | WS_BLACKLIST | No | | Do not scrobble from these WebScrobbler Connectors. Comma-delimited list | 95 + </Config>
+37
docsite/docs/configuration/sources/yamaha-musiccast.mdx
··· 1 + --- 2 + title: Yamaha MusicCast 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JsonConfig from '!!raw-loader!@site/../config/musiccast.json.example'; 11 + 12 + Monitor [MusicCast](https://usa.yamaha.com/products/contents/audio_visual/musiccast/index.html) device/receivers for music played on Network/USB/CD inputs. 13 + 14 + :::tip[Scrobbling Threshold] 15 + 16 + Musiccast may not correctly report track length. If this is the case you should reduce the "listened to" **duration** using [Scrobble Thresholds](#scrobble-thresholds) so that multi-scrobbler scrobbles correctly. 17 + 18 + ::: 19 + 20 + ##### URL 21 + 22 + If only a domain/IP:PORT is provided to multi-scrobbler it will automatically append the default Musiccast API path. If your Musiccast device is located behind a custom URL (or reverse proxy) you should explicitly provide the base path to use. 23 + 24 + EX 25 + 26 + | `url` | Transformed URL | 27 + | --------------------------------------- | :---------------------------------------------- | 28 + | `http://192.168.0.101` | `http://192.168.0.101/YamahaExtendedControl/v1` | 29 + | `http://mydomain.com/reverseProxy/cast` | `http://mydomain.com/reverseProxy/cast` | 30 + 31 + ## Configuration 32 + 33 + <Config config="MusicCastSourceConfig" fileContent={JsonConfig} name="musiccast"> 34 + | Environmental Variable | Required? | Default | Description | 35 + | :--------------------- | :-------- | ------- | :----------------------- | 36 + | `MCAST_URL` | Yes | | The Musiccast device URL | 37 + </Config>
+189
docsite/docs/configuration/sources/youtube-music.mdx
··· 1 + --- 2 + title: Youtube Music 3 + toc_min_heading_level: 2 4 + toc_max_heading_level: 5 5 + --- 6 + 7 + import Tabs from '@theme/Tabs'; 8 + import TabItem from '@theme/TabItem'; 9 + import CodeBlock from '@theme/CodeBlock'; 10 + import JsonConfig from '!!raw-loader!@site/../config/ytmusic.json.example'; 11 + 12 + :::warning 13 + 14 + Communication with 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. 15 + 16 + ::: 17 + 18 + :::tip[Scrobble Troubleshooting] 19 + 20 + Due to monitoring being unofficial, listening history from YTM can be inconsistent and can cause missed scrobbles. 21 + 22 + [**See the FAQ**](../FAQ.md#youtube-music-misses-or-duplicates-scrobbles) for a detailed explanation, how to see more details about MS's detection of tracks, and how to properly report an issue. 23 + 24 + ::: 25 + 26 + #### Authentication {#ytm-auth} 27 + 28 + Only one of these methods needs to be used. 29 + 30 + <Tabs groupId="ytmAuth" queryString> 31 + <TabItem value="cookie" label="Cookies"> 32 + 33 + Use instructions from 34 + 35 + * https://github.com/patrickkfkan/Volumio-YouTube.js/wiki/How-to-obtain-Cookie or 36 + * https://ytmusicapi.readthedocs.io/en/stable/setup/browser.html#copy-authentication-headers 37 + 38 + to get the **Cookie** value from a browser. 39 + 40 + It is highly recommended to [get the cookie from an Incognito/Private Session](https://github.com/LuanRT/YouTube.js/issues/803#issuecomment-2504032666) to limit the chance the session is invalidated from normal browsing. 41 + 42 + Add the cookie to your `ytmusic.json` config in `data` or as an ENV: 43 + 44 + ```json 45 + { 46 + "type": "ytmusic", 47 + "enable": true, 48 + "name": "MyYTM", 49 + "data": { 50 + "cookie": "__Secure-1PSIDTS=sidts-CjEB3EgAEvCd-......" 51 + }, 52 + "options": { 53 + "logAuthUpdateChanges": true, 54 + "logDiff": true 55 + } 56 + } 57 + ``` 58 + 59 + If MS gives you authentication errors (session invalidated) at some point in the future follow the same instructions to get new cookies. 60 + 61 + </TabItem> 62 + <TabItem value="oauth" label="OAuth Client"> 63 + :::warning 64 + 65 + As of Sept 25' OAuth clients no longer seem to have permission to access the YTM service, as reported by the upstream YTM library developer and [several other users.](https://github.com/FoxxMD/multi-scrobbler/issues/345#issuecomment-3258518769) 66 + 67 + If you have existing, working OAuth credentials keep using them but there is no gaurantee they will continue to work. 68 + 69 + If you are setting up the YTM Source for the first time you should first try to use [Cookies](./?ytmAuth=cookie#ytm-auth). 70 + 71 + ::: 72 + 73 + [Based on the instructions from here...](https://github.com/LuanRT/YouTube.js/issues/803#issuecomment-2479689924) 74 + 75 + * Login to [Google Cloud console](https://console.cloud.google.com/) (create an account, if necessary) 76 + * [Create a new project](https://console.cloud.google.com/projectcreate) 77 + * Go to APIs and services. 78 + * Configure the OAuth consent screen 79 + * Use the old experience if possible 80 + * If new is unavoidable then do not fill out any branding and under Authorized Domains you can delete the empty one (in order to save) 81 + * Add yourself as an authorized user 82 + * Navigate to Credentials 83 + * Create Credentials -> choose "OAuth client ID" 84 + * Application Type is **Web Application** 85 + * **Name** is whatever you want, leave Authorization Javascript origins blank 86 + * Authorized redirect URIs 87 + * This must be **exactly** the same as what is displayed in MS! For now leave it blank so we can generate it from MS first 88 + * Create 89 + * In the newly created client popup save the **Client ID** and **Client Secret**, then copy them into `ytmusic.json` or appropriate ENVs: 90 + 91 + ```json 92 + { 93 + "type": "ytmusic", 94 + "enable": true, 95 + "name": "MyYTM", 96 + "data": { 97 + "clientId": "8910....6jqupl.apps.googleusercontent.com", 98 + "clientSecret": "GOCSPX-WGXL6BSuQ343..." 99 + }, 100 + "options": { 101 + "logAuthUpdateChanges": true, 102 + "logDiff": true 103 + } 104 + } 105 + ``` 106 + 107 + Now, start MS and during the YTMusic startup it will log something like this: 108 + 109 + ``` 110 + Will use custom OAuth Client: 111 + Client ID: ... 112 + Client Secret: ... 113 + Redirect URI: http://localhost:9078/api/ytmusic/callback?name=MyYTM 114 + ``` 115 + 116 + If the beginning of the Redirect URI (before `api`) is EXACTLY how you would reach the MS dashboard from your browser (EX `http://localhost:9078`) then edit your google oauth client section for `Authorized redirect URIs` and add the URL MS has displayed. 117 + 118 + If it is NOT EXACTLY the same you either need to set MS's [base url](https://foxxmd.github.io/multi-scrobbler/docs/configuration/#base-url) or you can provide your own (Custom) Redirect URI for MS to use by setting it in `ytmusic.json` or ENV. 119 + 120 + <details> 121 + 122 + <summary>Using a Custom Redirect URI</summary> 123 + 124 + The three parts of the URL that must be the same: 125 + 126 + * it must start with `api` (after domain or subdirectory IE `my.domain.tld/api...` or `whatever.tld/subDir/api...` 127 + * it must end in `ytmusic/callback` 128 + * It must include `name=[NameOfSource]` in the query string 129 + 130 + Remember to add your custom URL to the `Authorized redirect URIs` section in the google oauth client! 131 + 132 + ```json 133 + { 134 + "type": "ytmusic", 135 + "enable": true, 136 + "name": "MyYTM", 137 + "data": { 138 + "clientId": "8910....6jqupl.apps.googleusercontent.com", 139 + "clientSecret": "GOCSPX-WGXL6BSuQ343...", 140 + "redirectUri": "http://my.custom.domain/api/ytmusic/callback?name=MyYTM" 141 + }, 142 + "options": { 143 + "logAuthUpdateChanges": true, 144 + "logDiff": true 145 + } 146 + } 147 + ``` 148 + 149 + </details> 150 + 151 + AFTER changing the Authorized redirect URIs on Google Cloud console you may need to wait a few minutes for it to take affect. Then restart MS. From the dashboard click `(Re)authenticate` on the YTmusic source card and follow the auth flow: 152 + 153 + * On the screen about "testing" make sure you hit **Continue** (not Back To Safety) 154 + * Make sure to select ALL scopes/permissions/grants it asks you about 155 + * `Select what [YourAppName] can access` -> Select all 156 + 157 + Once the flow is finished MS will get the credentials and start polling automatically. You should not need to re-authenticate again after restarting MS as it saves the credentials to the `/config` folder. 158 + 159 + </TabItem> 160 + <TabItem value="ytt" label="YoutubeTV"> 161 + 162 + :::warning 163 + 164 + Using the built-in YoutubeTV authentication is unlikely to work due to [Google restricting what permissions TV clients can have](https://github.com/yt-dlp/yt-dlp/issues/11462#issuecomment-2471703090). This authentication method should not be used. 165 + 166 + ::: 167 + 168 + To authenticate start multi-scrobbler with an empty YT Music configuration. An authentication URL/code will be logged in additon to being available from the dashboard. 169 + 170 + ``` 171 + ERROR: Sign in with the code 'CLV-KFA-BVKY' using the authentication link on the dashboard or https://www.google.com/device 172 + ``` 173 + 174 + Visit the authentication URL and enter the code that was provided (also available on the dashboard). After completing the setup flow MS will log `Auth success` and the YT Music dashboard card will display as **Idle** after refreshing. Click the **Start** link to begin monitoring. 175 + 176 + </TabItem> 177 + </Tabs> 178 + 179 + ## Configuration 180 + 181 + <Config config="YTMusicSourceConfig" fileContent={JsonConfig} name="ytmusic"> 182 + | Environmental Variable | Required? | Default | Description | 183 + |------------------------|-----------|---------|-----------------------------------------------| 184 + | YTM_COOKIE | No | | Value for Cookie Authentication | 185 + | YTM_CLIENT_ID | No | | Client ID for OAuth Athentication | 186 + | YTM_CLIENT_SECRET | No | | Client Secret for OAuth Athentication | 187 + | YTM_REDIRECT_URI | No | | A custom redirect URI for OAuth Athentication | 188 + | YTM_LOG_DIFF | No | false | Log YTM history changes | 189 + </Config>
+28
docsite/src/components/GenericConfiguration.mdx
··· 1 + import Tabs from '@theme/Tabs'; 2 + import TabItem from '@theme/TabItem'; 3 + import CodeBlock from '@theme/CodeBlock'; 4 + 5 + <Tabs groupId="configType" queryString> 6 + <TabItem value="env" label="ENV"> 7 + <EnvType> 8 + {props.children} 9 + </EnvType> 10 + </TabItem> 11 + <TabItem value="file" label="File"> 12 + <FileType> 13 + 14 + <FileExample title={`CONFIG/${props.name}.json`} client={props.client ?? false} data={props.fileContent}/> 15 + 16 + or <SchemaLink lower objectName={props.config}/> 17 + </FileType> 18 + </TabItem> 19 + <TabItem value="aio" label="AIO"> 20 + <AIOType> 21 + 22 + <AIOExample data={props.fileContent} client={props.client ?? false} name={props.name}/> 23 + 24 + 25 + or <SchemaLink lower objectName={props.config}/> 26 + </AIOType> 27 + </TabItem> 28 + </Tabs>
+2
docsite/src/components/snippets/_aio-config.mdx
··· 1 + [**AIO** Config Type](/configuration?configType=aio#configuration-types) 2 + {props.children}
+3
docsite/src/components/snippets/_env-config.mdx
··· 1 + [**ENV** Config Type](/configuration?configType=env#configuration-types) 2 + 3 + {props.children}
+3
docsite/src/components/snippets/_file-config.mdx
··· 1 + [**File** Config Type](/configuration?configType=file#configuration-types) 2 + 3 + {props.children}
+9 -1
docsite/src/theme/MDXComponents.js
··· 4 4 import SchemaLink from "@site/src/components/SchemaLink"; 5 5 import AIOExample from "@site/src/components/AIOExample"; 6 6 import FileExample from "@site/src/components/FileExample"; 7 + import EnvType from "@site/src/components/snippets/_env-config.mdx"; 8 + import FileType from "@site/src/components/snippets/_file-config.mdx"; 9 + import AIOType from "@site/src/components/snippets/_aio-config.mdx"; 10 + import Config from "@site/src/components/GenericConfiguration.mdx"; 7 11 8 12 export default { 9 13 // Re-use the default mapping 10 14 ...MDXComponents, 11 15 SchemaLink, 12 16 AIOExample, 13 - FileExample 17 + FileExample, 18 + EnvType, 19 + FileType, 20 + AIOType, 21 + Config 14 22 };