Skip to content

Highly customizable MagicMirror² module that displays what you are listening to using the Spotify Connect API. Compatible with MMM-LiveLyrics and DynamicTheming.

License

Notifications You must be signed in to change notification settings

Fabrizz/MMM-OnSpotify

Repository files navigation

MMM-OnSpotify banner

MMM-OnSpotify for MagicMirror² is a highly configurable module that displays Spotify activity on your MagicMirror display (including podcasts, and when available, audiobooks). https://onsp.fabriz.co/

The module provides a static web service that walks you through setting up and configuring both the Spotify app and the module itself. MMM-OnSpotify relies solely on the official Spotify Web API and does not use any third-party services.

onSpotifyCtr.mp4
Canvas-Support.mp4

This module displays Spotify activity. If you want to use Spotify in your mirror you should look at Raspotify

Installation

Step 1: Clone the module and install dependencies

cd ~/MagicMirror/modules
git clone https://github.com/Fabrizz/MMM-OnSpotify.git
cd MMM-OnSpotify
npm install

Step 2: Create a Spotify App and authorize the app

The module includes a static web service that guides you in the creation of the Spotify App needed to use this module, you can view the source code inside /web.

The online tool saves the credentials ONLY in your browser and its a static page. If you do not want to use the online tool, you can host it by running the Vite proyect inside /web.

Access it by going to https://onsp.fabriz.co/ Auth banner

Updating

git pull
npm install

Module Configuration

Extended full configuration object: Copy only the parts you want to change to your configuration file. The defaults are shown below:

{
    module: "MMM-OnSpotify",
    position: "bottom_right",
    config: {
        // Spotify Auth
        clientID: "key",
        clientSecret: "key",
        accessToken: "key",
        refreshToken: "key",

        // General Options [SEE BELOW]
        advertisePlayerTheme: true,
        displayWhenEmpty: "both",
        userAffinityUseTracks: false,
        prefersLargeImageSize: false,
        hideTrackLengthAndAnimateProgress: false,
        showDebugPalette: false,
        userDataMaxAge: 14400,
        userAffinityMaxAge: 36000,
        deviceFilter: [],
        deviceFilterExclude: false,
        filterNoticeSubtitle: true,
        // language: config.language, // [SEE BELOW]

        // Update Intervals [SEE BELOW]
        isPlaying: 1,
        isEmpty: 2,
        isPlayingHidden: 2,
        isEmptyHidden: 4,
        onReconnecting: 4,
        onError: 8,

        // Animations [SEE BELOW]
        mediaAnimations: false,
        fadeAnimations: false,
        scrollAnimations: false,
        textAnimations: true,
        transitionAnimations: true,
        spotifyVectorAnimations: false,

        // Spotify Code [SEE BELOW]
        spotifyCodeExperimentalShow: true,
        spotifyCodeExperimentalUseColor: true,
        spotifyCodeExperimentalSeparateItem: true,

        // Theming General [SEE BELOW]
        roundMediaCorners: true,
        roundProgressBar: true,
        showVerticalPipe: true, 
        useColorInProgressBar: true,
        useColorInTitle: true,
        useColorInUserData: true,
        showBlurBackground: true,
        blurCorrectionInFrameSide: false,
        blurCorrectionInAllSides: false,
        alwaysUseDefaultDeviceIcon: false,
        experimentalCSSOverridesForMM2: false, // [SEE BELOW]
        experimentalColorSignaling: false,
    },
},

Theming 3rd Party Modules:

MMM-OnSpotify 3rd Party theming

/* Keys */
text background palette_vibrant palette_vibrantlight palette_vibrantdark palette_muted palette_mutedlight palette_muteddark brand_spotify
/* Example */
experimentalCSSOverridesForMM2: [
	["--color-text-dimmed", "palette_vibrantlight"],
	["--ONSP-OVERRIDES-ICONS-COLOR", "palette_vibrantlight"], /* View css/theming.css */
],

Tip

You can use other variables that are not from OnSpotify, just replace palette_vibrantlight with whatever variable you like, it gets wrapped on a var(x) function automatically.

General options:

Key Description
advertisePlayerTheme
true
If the module should send notifications when the theme status changes.
displayWhenEmpty
"both"
What to display when the player is empty. Options are:
- user: Displays user card
- affinity: Shows user top albums/songs
- both: Combines the user card and affinity data
- logo: Displays the Spotify logo
- none: Display only when playing

Display when empty
userAffinityUseTracks
false
If you have selected to show your affinity data on idle, you can choose between showing tracks or albums.
prefersLargeImageSize
false
If you prefer to use higher resolution images. Not recommended for normal use.
hideTrackLengthAndAnimateProgress
false
Depending on your internet conection or your selected polling rate, you may want to hide the actual seconds and animate the progress bar.
showDebugPalette
false
Shows the Vibrant output as a palette in the web console.

Debug palette
userDataMaxAge
14400
(Seconds) The time in seconds of user data TTL. If set to 0, its updated everytime that the player goes to idle, as user data rarely changes, this allows a middle ground between updating always and only on boot
userAffinityMaxAge
36000
(Seconds) The time in seconds of affinity data TTL. If set to 0, its updated everytime that the player goes to idle, as user data rarely changes, this allows a middle ground between updating always and only on boot
deviceFilter
list[]
List of device names to filter from the module, by default, its an inclusion list, you can change this using deviceFilterExclude (making it an exclusion list). When a filtered device plays displayWhenEmpty shows. Example: ["Sonos Bedroom", "DESKTOP-ABCD123"]
deviceFilterExclude
false
Inverts the deviceFilter list, making it exclude devices
filterNoticeSubtitle
true
Changes the subtitle of displayWhenEmpty, to not show a false status if the deviceFilter is set
language
config.language
The language used in the API query. When it is not set, it depends on config.language. Example: en-US (Or false if you prefer the default api response)

Polling Intervals:

Key Description
isPlaying
1
Default interval when something is playing in Spotify.
isEmpty
2
Interval when the player is idle.
isPlayingHidden
2
Interval when the module is hidden from another module and there is something playing in Spotify.
isEmptyHidden
3
Interval when the module is hidden and the player is idle.
onReconnecting
4
Interval when there is an error fetching from the Spotify API.
onError
8
After trying to reconnect for a long time, the module enters an error state where the polling is rate is longer than "onReconnecting".

Theming:

See also: Disabling all color based theming

Important

  • If you are using a RPI5 Not tested, any insight is helpful!
  • If you are using a RPI4 I recommend to keep the default theming settings. (enabling some animations should not be a problem)
  • If you are using a RPI3 or below, I recommend turning off the animations and the blurred background, as its GPU intensive.
  • If you using a higher power device (RPI5), you can turn on all the animations, the fade, text and transition animations look really good!

Animations

Key Description
mediaAnimations
false
Control the cover crossfade, this animation type waits for the image to be dowmloaded to do the fade between new/old media. (See the warning for RPIs above)
fadeAnimations
false
Controls the fade effects between module status changes. Not too GPU intensive. (See the warning for RPIs above)
scrollAnimations
false
Controls text scrolling for long music/podcast names/artist/show. (See the warning for RPIs above)
textAnimations
true
Control the animation of text on music/podcast change, also affects the "current device" text. (See the warning for RPIs above)
transitionAnimations
true
Controls the transition between color changes, GPU intensive, but looks really good. (See the warning for RPIs above) (It also affects other modules if you are using experimentalCSSOverridesForMM2 default CSS config.)
spotifyVectorAnimations
false
Control the animation of the Spotify code, It look really good, as it transitions seamless. (See the warning for RPIs above)

Spotify Code

Key Description
spotifyCodeExperimentalShow
true
Shows the Spotify Code (SpotifyScannable) for the current Song/Podcast/Audiobook. This is an experimental feature, as the API is not documented. SVG elements from the Spotify CDN are sanitized and parsed to allow animations (spotifyVectorAnimations).

Spotify code
spotifyCodeExperimentalUseColor
true
As shown on the image above, color the Spotify Code bar using cover art colors.
spotifyCodeExperimentalSeparateItem
true
Separates or joins the Spotify Code Bar to the cover art. Also respects roundMediaCorners and spotifyCodeExperimentalUseColor.

Spotify code bar separation

Canvas

Important

Removed direct support for canvases

Relevant disscussion about Spotify changes and it affecting lots of OSS projects: misiektoja/spotify_monitor#2 (comment) librespot-org/librespot#1475 (comment)

TL;DR: It now uses another request and TOTP auth and it seems that they are currently changing some stuff on their end.

You can check the last version with canvas support here dev-canvas-support branch. Im open to having PRs that add the OTP or new auth but I will not directly support/fix the feature.

Thanks to https://github.com/dientuki & https://github.com/bartleyg/my-spotify-canvas for the implementation!

General Theming options

Key Description
roundMediaCorners
true
If cover art (and Spotify Code) should have rounded corners.
roundProgressBar
true
If you want a rounded progress bar.
showVerticalPipe
true
Shows or hides the vertical bar (or pipe) in the module header.
useColorInProgressBar
true
Use color in the progress bar. If showBlurBackground is enabled, the background behaviour differs to balance it.
useColorInTitle
true
Use color in the title, artist and bar.
useColorInUserData
true
Only when displayWhenEmpty: "user" is selected.
showBlurBackground
true
Renders the background for the module (Heavy GPU use).
blurCorrectionInFrameSide
false
Fixes the color blur in the frame side of the module, making it look like there is no gap between the actual border and the display. View ilustration below.

Blur separation
blurCorrectionInAllSides
false
Same as blurCorrectionInFrameSide, but applies the correction on all of the borders for a more subtle effect.
alwaysUseDefaultDeviceIcon
false
The device icon changes depending on the player type. If you don’t like this behaviour you can disable it.
experimentalCSSOverridesForMM2
false
An array containing CSS overrides, OnSpotify manages the status depending on what is displayed on the screen and lets you customize other modules. See above
experimentalColorSignaling
false
Sends a notification with the color data for modules that are not DOM based and need the color when its already processed.

See also: Disabling all color based theming

MMM-LiveLyrics

View more on the MMM-LiveLyrics repository.

MMM-Livelyrics

This module uses web scrapping to get the Lyrics from Genius, could stop working at any time but now its +3 years solid!

More modules!

  • MMM-Matter Adds native Matter to MagicMirror and provides an API to control other modules from ANY smarthome provider (Homekit, Google Home, Amazon Alexa, Home Assistant, etc).

Old modules:

Notification API

key Description
THEME_PREFERENCE ↑ Sent to signal other modules that color data is available.
INSTANT_COLOR ↑ Sent to signal other modules that color data has been updated instantly, also sends the raw vibrant data, only when experimentalColorSignaling is turned on.
NOW_PLAYING ↑ When the player state changes, the module sends a notification so other modules can, for example, show lyrics.
DEVICE_CHANGE ↑ Everytime the Spotify Connect target changes, this notification is fired.
ONSPOTIFY_NOTICE ↑ This notification signals other modules that OnSpotify is available.
ONSPOTIFY_GET ↓ Returns a ONSPOTIFY_NOTICE
GET_PLAYING ↓ Return a NOW_PLAYING notification, regardles of the state of the player. (Used by MMM-LiveLyrics)

Migrating from MMM-NowPlayingOnSpotify

You cannot migrate from NowPlayingInSpotify, as the scopes included in the NPOS auth do not enable searching for user data or viewing user generated data.

Enabling every animation and the included CSS override:

{
    module: "MMM-OnSpotify",
    position: "bottom_right",
    config: {
        clientID: "key",
        clientSecret: "key",
        accessToken: "key",
        refreshToken: "key",
	
	mediaAnimations: true,
	fadeAnimations: true,
	textAnimations: true,
	transitionAnimations: true,
	spotifyVectorAnimations: true,
    scrollAnimations: true,
        experimentalCSSOverridesForMM2: [
			["--color-text-dimmed", "palette_vibrantlight"],
			["--ONSP-OVERRIDES-ICONS-COLOR", "palette_vibrantlight"],
		],
    },
},

Other:

Caution

Using Dynamic Theming notifications is deprecated, use CSS variables and overrides.

  • You can disable all the color related theming and use the module as is. You need to disable all the color related fields:
    advertisePlayerTheme, useColorInProgressBar, useColorInTitle, useColorInTitleBorder, showBlurBackground, useColorInUserData, spotifyCodeExperimentalUseColor, experimentalCSSOverridesForMM2. Of course you can still use the Spotify Code (White/Gray). Disabling all theming options also stop the module from loading the Vibrant lib.

  • The API for Spotify Codes is not public, as its part of the Spotify CDN (scannables.scdn.co). The API could change without notice. Many libraries rely on it and using it does not go againts the ToS.

  • Contributions wanted! Add features or your language using translations/yourLanguage.json. Currently we have translations for: Spanish, English, German

  • You can custom CSS and functions in the "Issues" tab. For example #65 for changing the size and hiding other modules using ONSP state.

With <3 by Fabrizio | fabriz.co | Star this repository! Fabrizz logo

About

Highly customizable MagicMirror² module that displays what you are listening to using the Spotify Connect API. Compatible with MMM-LiveLyrics and DynamicTheming.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project