Spotify controller for MagicMirror. Multiples accounts supported!
- Screenshot
- Main Features
- Restrictions
- Install
- Configuration
- Control with notifications
- Notification send
- Credit
- Showing Current playback on any devices
- Playing Controllable by Notification & touch (Play, pause, next, previous, volume)
- Spotify Controllable by Notification & touch (change device, change account, search and play)
- Multiple accounts supported
- This is NOT a full blown Spotify client with integrated player! If you want to use your Pi also as playback device via soundcard, have a look at Raspotify
- Starting specific songs, playlists etc. is limited! This can only be done by the notifications described below but NOT via the UI / Buttons
- Some of Spotify's API calls we are using are limited to premium accounts only! If you are using a free account, you will probably run into problems at some point
- The Spotify API is rate-limited and only a limited number of clients can make requests to the API. It is recommended to use a separate Spotify app for each client to avoid rate limitations
Do not install MagicMirror or this module as root user ! (sudo
)
cd ~/MagicMirror/modules
git clone https://github.com/skuethe/MMM-Spotify
cd MMM-Spotify
npm install
You should be a premium member of Spotify
- Go to https://developer.spotify.com
- Navigate to DASHBOARD > Create an app (fill information as your thought)
- Setup the app created, (EDIT SETTINGS)
- Redirect URIs. :
http://localhost:8888/callback
- That's all you need. Just save it.
- Redirect URIs. :
- Now copy your Client ID and Client Secret to any memo
Hint:
If you are running MM²
inside an environment without a UI (Docker f.e.), you need to configure a custom callback URL.
This custom callback URL needs to be adapted when editing the app in the Spotify developer dashboard.
cd ~/MagicMirror/modules/MMM-Spotify
cp spotify.config.json.example-single spotify.config.json
vim spotify.config.json
Edit the spotify.config.json
with the editor of your choice. Modify the entries as hinted below, hen save it.
[
{
"USERNAME": "A_NAME_TO_IDENTIFY_YOUR_ACCOUNT",
"CLIENT_ID": "PUT_YOUR_SPOTIFY_APP_CLIENT_ID",
"CLIENT_SECRET": "PUT_YOUR_SPOTIFY_APP_CLIENT_SECRET",
"TOKEN": "./USERNAME_token.json"
}
]
cd ~/MagicMirror/modules/MMM-Spotify
cp spotify.config.json.example-multi spotify.config.json
vim spotify.config.json
Open the spotify.config.json
then modify it as described. You can create a configuration object for each account you want to use. Save the file.
Make sure that TOKEN
is referencing different file names, as these files will be created.
[
{
"USERNAME": "A_NAME_TO_IDENTIFY_THE_FIRST_ACCOUNT",
"CLIENT_ID": "PUT_SPOTIFY_APP_CLIENT_ID_OF_FIRST_ACCOUNT",
"CLIENT_SECRET": "PUT_SPOTIFY_APP_CLIENT_SECRET_OF_FIRST_ACCOUNT",
"TOKEN": "./FIRSTUSERNAME_token.json"
},
{
"USERNAME": "ANOTHER_NAME_TO_IDENTIFY_THE_SECOND_ACCOUNT",
"CLIENT_ID": "PUT_SPOTIFY_APP_CLIENT_ID_OF_SECOND_ACCOUNT",
"CLIENT_SECRET": "PUT_SPOTIFY_APP_CLIENT_SECRET_OF_SECOND_ACCOUNT",
"TOKEN": "./SECONDUSERNAME_token.json"
}
]
If you are running MagicMirror in an environment without UI (Docker f.e.), you need to provide a custom callback URL in your account file, which points to your devices IP address.
This can be configured inside the spotify.config.json
file.
An example:
- you have
MM²
running inside a docker container, which is running on your Raspberry Pi - your Pi's local network IP is:
192.168.0.100
- some other application / container is already using port
8888
on your Pi, so you need to use something other than the default (which is8888
). For example:8889
cd ~/magicmirror/mounts/modules/MMM-Spotify
cp spotify.config.json.example-callback spotify.config.json
vim spotify.config.json
[
{
"USERNAME": "A_NAME_TO_IDENTIFY_YOUR_ACCOUNT",
"CLIENT_ID": "PUT_YOUR_SPOTIFY_APP_CLIENT_ID",
"CLIENT_SECRET": "PUT_YOUR_SPOTIFY_APP_CLIENT_SECRET",
"TOKEN": "./token.json",
"AUTH_DOMAIN": "http://192.168.0.100",
"AUTH_PORT": "8889"
}
]
Docker specific: make sure you pass the port specified by AUTH_PORT
directly to the container running MM²
.
In our case, a possible docker-compose.yml
file could look like this:
version: '3'
services:
magicmirror:
container_name: mm
image: karsten13/magicmirror:latest
ports:
- "8080:8080"
- "8889:8889"
volumes:
- ../mounts/config:/opt/magic_mirror/config
- ../mounts/modules:/opt/magic_mirror/modules
- ../mounts/css:/opt/magic_mirror/css
restart: unless-stopped
command:
- npm
- run
- server
This change needs to also be made if you run MM²
in docker but keep the default AUTH_PORT
of 8888
:
[...]
ports:
- "8080:8080"
- "8888:8888"
[...]
Also make sure you configured the custom callback URL inside the Spotify App (see: Setup Spotify).
In RPI Desktop, log in in a Terminal (you can use VNC).
If you are running inside Docker (or any other environment without UI), be sure to configure a Custom callback fist.
The first_auth.js
script will then not open your default browser, but output an URL, which you need to open in your workstation on the same network.
cd ~/MagicMirror/modules/MMM-Spotify
node first_auth.js
Then the allowance dialog popup will be opened:
- You MUST login in the SAME ORDER you put your users in the configuration file (when using multiple accounts)
- It helps to not save your login in the browser session (when using multiple accounts)
- Allow the application to access your Spotify API
- Close the browser
- Another browser session will start when using multiple accounts -> repeat steps
That's all - now all the specific json files where created.
{
module: "MMM-Spotify",
position: "bottom_left",
config: {
debug: false,
}
}
{
module: "MMM-Spotify",
position: "bottom_left", // "bottom_bar" or "top_bar" for miniBar
config: {
debug: false, // debug mode
style: "default", // "default" or "mini" available (inactive for miniBar)
moduleWidth: 360, // width of the module in px
control: "default", // "default" or "hidden"
showAlbumLabel: true, // if you want to show the label for the current song album
showVolumeLabel: true, // if you want to show the label for the current volume
showAccountName: false, // also show the current account name in the device label; usefull for multi account setup
showAccountButton: true, // if you want to show the "switch account" control button
showDeviceButton: true, // if you want to show the "switch device" control button
useExternalModal: false, // if you want to use MMM-Modal for account and device popup selection instead of the build-in one (which is restricted to the album image size)
updateInterval: 1000, // update interval when playing
idleInterval: 30000, // update interval on idle
defaultAccount: 0, // default account number, attention : 0 is the first account
defaultDevice: null, // optional - if you want the "SPOTIFY_PLAY" notification to also work from "idle" status, you have to define your default device here (by name)
allowDevices: [], //If you want to limit devices to display info, use this. f.e. allowDevices: ["RASPOTIFY", "My Home speaker"],
onStart: null, // disable onStart feature with `null`
// if you want to send custom notifications when suspending the module, f.e. switch MMM-Touch to a different "mode"
notificationsOnSuspend: [
{
notification: "TOUCH_SET_MODE",
payload: "myNormalMode",
},
{
notification: "WHATEVERYOUWANT",
payload: "sendMe",
}
],
// if you want to send custom notifications when resuming the module, f.e. switch MMM-Touch to a different "mode"
notificationsOnResume: [
{
notification: "TOUCH_SET_MODE",
payload: "mySpotifyControlMode",
},
],
deviceDisplay: "Listening on", // text to display in the device block (default style only)
volumeSteps: 5, // in percent, the steps you want to increase or decrese volume when reacting on the "SPOTIFY_VOLUME_{UP,DOWN}" notifications
// miniBar is no longer supported, use at your own "risk". Will be removed in a future version
miniBarConfig: {
album: true, // display Album name in miniBar style
scroll: true, // scroll title / artist / album in miniBar style
logo: true, // display Spotify logo in miniBar style
}
}
}
You can control Spotify on start of MagicMirror (By example; Autoplay specific playlist when MM starts)
onStart: {
deviceName: "RASPOTIFY", //if null, current(last) activated device will be.
spotifyUri: "spotify:track:3ENXjRhFPkH8YSH3qBXTfQ",
//when search is set, sportifyUri will be ignored.
search: {
type: "playlist", // `artist`, track`, `album`, `playlist` and its combination(`artist,playlist,album`) be available
keyword: "death metal",
random:true,
}
}
When search
field exists, spotifyUri
will be ignored.
SPOTIFY_SEARCH
: search items with query and play it.type
,query
,random
be payloads
this.sendNotification("SPOTIFY_SEARCH", {"type": "artist,playlist", "query": "michael+jackson", "random": false})
SPOTIFY_PLAY
: playing specific SpotifyUri. There could be two types of uri -context_uri
anduris
.context_uri:String
: Spotify URI of the context to play. Valid contexts are albums, artists, playlists.uris:[]
: A JSON array of the Spotify track URIs to play
this.sendNotification("SPOTIFY_PLAY", {"context_uri": "spotify:album:1Je1IMUlBXcx1Fz0WE7oPT"})
//OR
this.sendNotification("SPOTIFY_PLAY", {
"uris": ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh", "spotify:track:1301WleyT98MSxVHPZCA6M"]
})
The SPOTIFY_PLAY notification can also be used as resume
feature of stopped/paused player, when used without payloads.
In addition, if you have defaultDevice
configured, you can start playback from Spotify's "disconnected" mode (where Spotify does not have an active device in your account).
SPOTIFY_PAUSE
: pausing current playback.
this.sendNotification("SPOTIFY_PAUSE")
SPOTIFY_TOGGLE
: toggling for playing/pausing
this.sendNotification("SPOTIFY_TOGGLE")
SPOTIFY_NEXT
: next track of current playback.
this.sendNotification("SPOTIFY_NEXT")
SPOTIFY_PREVIOUS
: previous track of current playback.
this.sendNotification("SPOTIFY_PREVIOUS")
SPOTIFY_VOLUME
: setting volume of current playback. payload will be volume (0 - 100)
this.sendNotification("SPOTIFY_VOLUME", 50)
SPOTIFY_VOLUME_UP
: increasing volume in this.config.volumeSteps steps. Maximum 100. Useful in combination with touch
this.sendNotification("SPOTIFY_VOLUME_UP")
SPOTIFY_VOLUME_DOWN
: decreasing volume in this.config.volumeSteps steps. Minimum 0. Useful in combination with touch
this.sendNotification("SPOTIFY_VOLUME_DOWN")
SPOTIFY_TRANSFER
: change device of playing with device name (e.g: RASPOTIFY)
this.sendNotification("SPOTIFY_TRANSFER", "RASPOTIFY")
SPOTIFY_SHUFFLE
: toggle shuffle mode.
this.sendNotification("SPOTIFY_SHUFFLE")
SPOTIFY_REPEAT
: change repeat mode. (off
->track
->context
)
this.sendNotification("SPOTIFY_REPEAT")
SPOTIFY_ACCOUNT
: change account. payload is theUSERNAME
defined in your account inspotify.config.json
file
this.sendNotification("SPOTIFY_ACCOUNT", "premium")
payload could be the number of the account. attention: for first account, number is 0
this.sendNotification("SPOTIFY_ACCOUNT", 0)
SPOTIFY_CONNECTED
: Spotify is connected to a deviceSPOTIFY_DISCONNECTED
: Spotify is disconnected
It can be used with MMM-pages for example (for show or hide the module)
- Biggest thanks to @eouia for all his work and inspiration
- Special thanks to @ejay-ibm so much for taking the time to cowork to make this module.
- Thanks to @KamisamaPT for helping design