Spotify Now Playing

and Jason Tokoph

Display currently playing Spotify song. Play/pause, skip forward, skip backward.

Image preview of Spotify Now Playing plugin.

spotify.10s.sh

Edit
Open on GitHub
#!/bin/bash

# Get current Spotify status with play/pause button
#
# by Jason Tokoph ([email protected])
#    Marcin Swieczkowski ([email protected])
#
# Shows current track information for Spotify

# metadata
# <xbar.title>Spotify Now Playing</xbar.title>
# <xbar.version>v1.2</xbar.version>
# <xbar.author>Marcin S., Jason Tokoph</xbar.author>
# <xbar.author.github>jtokoph</xbar.author.github>
# <xbar.desc>Display currently playing Spotify song. Play/pause, skip forward, skip backward.</xbar.desc>
# <xbar.image>http://i.imgur.com/y1SZwfq.png</xbar.image>

# Comment the following line to disable showing times.
SHOW_TIME=1

# By default we remove anything after " - ", as it usually is stuff like
# "Remastered", "Single Version", or other garbage that Spotify likes to
# include.
#
# Comment out this line if you want the full track names.
CLEAN_TRACK_NAMES=1
# Comment out this line if you want the full album names.
CLEAN_ALBUM_NAMES=1

# The length of a track/artist name after which to truncate.
TRUNC_LEN=18
# String used when replacing truncated text.
TRUNC_SUFFIX="..."

# Send a series of semicolon-delimited commands to Spotify
function tellspotify() {
  commands="$(echo "$1" | tr ";" "\\n")"

  osascript -e "
            tell application \"Spotify\"
                $commands
            end tell";
}

## Handle early-return cases

if [ "$1" = 'launch' ]; then
  tellspotify 'activate'
  exit
fi

first="$(echo "$1" | head -n 1 | awk '{print $1;}')"
case "$first" in
  'playpause' | 'previous' | 'next' | 'set')
    tellspotify "$1"
    exit
esac

if [ "$(osascript -e 'application "Spotify" is running')" = "false" ]; then
  echo "♫"
  echo "---"
  echo "Spotify is not running"
  echo "Launch Spotify | bash='$0' param1=launch terminal=false"
  exit
fi

## Get Spotify info

state=$(tellspotify 'player state as string');
track=$(tellspotify 'name of current track as string');
artist=$(tellspotify 'artist of current track as string');
album=$(tellspotify 'album of current track as string');

# Handle last early-return case (needed $track and $artist to look up lyrics).
if [ "$1" = 'lyrics' ]; then
  open "https://www.musixmatch.com/search/$track $artist"
  exit
fi

if [ "$state" = "playing" ]; then
  state_icon="▶"
else
  state_icon="❚❚"
fi

# Clean up track and/or album names
if [[ $CLEAN_TRACK_NAMES ]]; then
  track="$(echo -e "${track/ - /\\n}" | head -n 1)"
  track="$(echo -e "${track/ (Remastered/\\n}" | head -n 1)"
fi
if [[ $CLEAN_ALBUM_NAMES ]]; then
  album="$(echo -e "${album/ - /\\n}" | head -n 1)"
  album="$(echo -e "${album/ (Remastered/\\n}" | head -n 1)"
fi

## Truncate track and artist
trunc_track=$track
if [ ${#trunc_track} -gt $TRUNC_LEN ];then
  trunc_track=${trunc_track:0:$TRUNC_LEN-${#TRUNC_SUFFIX}}$TRUNC_SUFFIX
fi

trunc_artist=$artist
if [ ${#trunc_artist} -gt $TRUNC_LEN ];then
  trunc_artist=${trunc_artist:0:$TRUNC_LEN-${#TRUNC_SUFFIX}}$TRUNC_SUFFIX
fi

# Get position and duration of track
if [[ $SHOW_TIME ]]; then
  position=$(osascript -e \
                       "tell application \"Spotify\"
                            set pos_sec to player position
                            set time_min to (pos_sec / 60 div 1) as text
                            set raw_sec to (pos_sec mod 60 div 1) as text
                            if length of raw_sec is greater than 1 then
                                set time_sec to raw_sec
                            else
                                set time_sec to \"0\" & raw_sec
                            end if
                            return time_min as text & \":\" & time_sec as text
                        end tell");
  duration=$(osascript -e \
                       "tell application \"Spotify\"
                            set total_sec to (duration of current track / 1000) as text
                            set time_min to (total_sec / 60 div 1) as text
                            set raw_sec to (total_sec mod 60 div 1) as text
                            if length of raw_sec is greater than 1 then
                                set time_sec to raw_sec
                            else
                                set time_sec to \"0\" & raw_sec
                            end if
                            return time_min as text & \":\" & time_sec as text
                        end tell");
fi

## Print the display

echo "$state_icon $trunc_track - $trunc_artist"
echo "---"

echo -e "Track:\\t$track"
echo -e "Artist:\\t$artist"
echo -e "Album:\\t$album"
echo "---"

if [[ $SHOW_TIME ]]; then
  echo "${position} / ${duration}"
  echo '---'
fi

if [ "$state" = "playing" ]; then
  echo -e "❚❚\\tPause | bash='$0' param1=playpause terminal=false refresh=true"
  echo -e "↩\\tPrevious | bash='$0' param1='set player position to 0;previous track' terminal=false refresh=true"
  echo -e "↪\\tNext | bash='$0' param1='next track' terminal=false refresh=true"
  echo -e "↻\\tReplay | bash = '$0' param1='set player position to 0' terminal=false"
else
  echo -e "▶\\tPlay | bash='$0' param1=playpause terminal=false refresh=true"
  echo -e "↩\\tPrevious | bash='$0' param1='set player position to 0;previous track;play' terminal=false refresh=true"
  echo -e "↪\\tNext | bash='$0' param1='next track;play' terminal=false refresh=true"
  echo -e "↻\\tReplay | bash = '$0' param1='set player position to 0;play' terminal=false refresh=true"
fi

echo '---'
echo -e "♫\\tLyrics | bash='$0' param1='lyrics' terminal=false"
echo '---'

echo '---'
echo "Open Spotify | bash='$0' param1=launch terminal=false"