skuethe / MMM-Spotify

Spotify display and controller for MagicMirror
MIT License
68 stars 17 forks source link

MMM-Spotify

Spotify controller for MagicMirror. Multiples accounts supported!

Screenshot

default mini

Main Features

Restrictions

Install

0. Prevent

Do not install MagicMirror or this module as root user ! (sudo)

1. Module install

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

2. Setup Spotify

You should be a premium member of Spotify

  1. Go to https://developer.spotify.com
  2. Navigate to DASHBOARD > Create an app (fill information as your thought)
  3. Setup the app created, (EDIT SETTINGS)
    • Redirect URIs. : http://localhost:8888/callback
    • That's all you need. Just save it.
  4. 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.

3. Setup your module

Single account

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"
  }
]

Multi account

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"
  }
]

Custom callback

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:

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).

4. Get auth

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:

That's all - now all the specific json files where created.

Configuration

Simple

{
  module: "MMM-Spotify",
  position: "bottom_left",
  config: {
    debug: false,
  }
}

Detail & Default

{
  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
    }
  }
}

onStart feature

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.

Control with notifications

  this.sendNotification("SPOTIFY_SEARCH", {"type": "artist,playlist", "query": "michael+jackson", "random": false})
   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).

  this.sendNotification("SPOTIFY_PAUSE")
  this.sendNotification("SPOTIFY_TOGGLE")
  this.sendNotification("SPOTIFY_NEXT")
  this.sendNotification("SPOTIFY_PREVIOUS")
  this.sendNotification("SPOTIFY_VOLUME", 50)
  this.sendNotification("SPOTIFY_VOLUME_UP")
  this.sendNotification("SPOTIFY_VOLUME_DOWN")
  this.sendNotification("SPOTIFY_TRANSFER", "RASPOTIFY")
  this.sendNotification("SPOTIFY_SHUFFLE")
this.sendNotification("SPOTIFY_REPEAT")
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)

Notification send

It can be used with MMM-pages for example (for show or hide the module)

Credit