I'm trying to get the current track playing in spotify into my dwm status bar. I got to the point where I get the information with this command.

enter code heredbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'Metadata'

The result is this:

method return sender=:1.0 -> dest=:1.15 reply_serial=2
variant       array [
     dict entry(
        string "mpris:artUrl"
        variant                string "http://open.spotify.com/thumb/45656b0961cba1598d127c3404ad276acb8e961b"
     dict entry(
        string "mpris:length"
        variant                uint64 308000000
     dict entry(
        string "mpris:trackid"
        variant                string "spotify:track:7oGXMMrB78C5tQhumQ2jfZ"
     dict entry(
        string "xesam:album"
        variant                string "Chopin"
     dict entry(
        string "xesam:artist"
        variant                array [
              string "Frederic Chopin"
     dict entry(
        string "xesam:autoRating"
        variant                double 0.57
     dict entry(
        string "xesam:contentCreated"
        variant                string "2009-01-01T00:00:00"
     dict entry(
        string "xesam:discNumber"
        variant                int32 0
     dict entry(
        string "xesam:title"
        variant                string "Waltz No. 1 in E flat Major, Op. 18"
     dict entry(
        string "xesam:trackNumber"
        variant                int32 8
     dict entry(
        string "xesam:url"
        variant                string "spotify:track:7oGXMMrB78C5tQhumQ2jfZ"

So my question is how I get the dict entry "xesam:artist" and "xesam:title" out of this result so I can put it in my status bar?


This would be so much simpler if it were well formatted JSON, then you could use a tool like jshon to intelligently interrogate the data.

It is possible using awk, but is dependent on conistent output:

awk 'BEGIN {RS=" entry\\("; FS="\""}; /artist/ {artist = $4}; /title/ {title = $4} END { print artist": "title}' spotify_output                      
Frederic Chopin: Waltz No. 1 in E flat Major, Op. 18

Essentially, the file is broken up by changing the record separator (RS) to the various entry blocks (entry(), and the fields within those records are delimited by changing the field separator (FS) from the default (a space) to the quote marks (") that hold the values you are seeking.

From there it is just pattern matching (eg., /artist/).


If you only need the artist and title, I would suggest using xprop to get the _NET_WM_ICON_NAME property of Spotify.

xprop -name "Spotify Free - Linux Preview" _NET_WM_ICON_NAME

gives you:

_NET_WM_ICON_NAME(UTF8_STRING) = "Spotify - Stereophonics – Indian Summer"

you can use cut to get the part inside quotes:

xprop -name "Spotify Free - Linux Preview" _NET_WM_ICON_NAME|\
cut -d "\"" -f 2

skip the starting "Spotify - " part again using cut:

xprop -name "Spotify Free - Linux Preview" _NET_WM_ICON_NAME|\
cut -d "\"" -f 2|cut -b 11-

The artist and title are separated by this dash: . Note that it is different than this: -

You can use awk to separate the two:

xprop -name "Spotify Free - Linux Preview" _NET_WM_ICON_NAME|\
cut -d "\"" -f 2|cut -b 11-|awk -F " – " '{print $1}'

gives you the artist: "Stereophonics"

xprop -name "Spotify Free - Linux Preview" _NET_WM_ICON_NAME|\
cut -d "\"" -f 2|cut -b 11-|awk -F " – " '{print $2}'

gives you the title: "Indian Summer"

  • 1
    Or just awk: awk -F'"' '{sub(/Spotify - /,""); print $2}'... xprop is a nice hack, though: upvoted. – jasonwryan Aug 10 '14 at 18:29

Here is a solution based on sp by GitHub user wandernauta :


SPOTIFY_METADATA="$(dbus-send                                                 \
 --print-reply                                  `# We need the reply.`       \
 --dest=$SP_DEST                                                             \
 $SP_PATH                                                                    \
 org.freedesktop.DBus.Properties.Get                                         \
 string:"$SP_MEMB" string:'Metadata'                                         \
 | grep -Ev "^method"                           `# Ignore the first line.`   \
 | grep -Eo '("(.*)")|(\b[0-9][a-zA-Z0-9.]*\b)' `# Filter interesting fiels.`\
 | sed -E '2~2 a|'                              `# Mark odd fields.`         \
 | tr -d '\n'                                   `# Remove all newlines.`     \
 | sed -E 's/\|/\n/g'                           `# Restore newlines.`        \
 | sed -E 's/(xesam:)|(mpris:)//'               `# Remove ns prefixes.`      \
 | sed -E 's/^"//'                              `# Strip leading...`         \
 | sed -E 's/"$//'                              `# ...and trailing quotes.`  \
 | sed -E 's/\"+/|/'                             `# Regard "" as seperator.`  \
 | sed -E 's/ +/ /g'                            `# Merge consecutive spaces.`\

TrackArtist=$(echo "$SPOTIFY_METADATA" | sed -n 's/artist|//p')
TrackTitle=$(echo "$SPOTIFY_METADATA" | sed -n 's/title|//p')

I used wmctrl in the following way:

wmctrl -lx | grep spotify | cut -c X-

where X is some number that works ;)


I installed playerctl for this task (and to manage spotify with dwm keys like META+F8 (toggle play)).

Then one can use it for example like this:

status=$(playerctl -p spotify status)
artist=$(playerctl -p spotify metadata artist)
album=$(playerctl -p spotify metadata album)
title=$(playerctl -p spotify metadata title)
length=$(playerctl -p spotify metadata mpris:length | sed 's/.\{6\}$//')
if [[ "$status" == "Playing" ]] ; then status="▶" ; else status="◼" ; fi

echo "$artist/$album/$title [$status] ${length}s"

$length is a bit more interesting though. The regular value (extracted out of metadata) is:

'mpris:length': <uint64 379093000>,

I found out that the last 6 characters (093000) are not important (?) and the remaining ones are the duration of the song in seconds, hence the sed. You can also change this in minutes:seconds by using this code here. I tested it with some sample songs (also longer ones) and it works.
Unfortunately I didn't find a proper source for my assumptions or the remaining chars ..


For those stumbling upon this 6 year-old thread, Probably the best way to do this would be with playerctl. Install it, then paste this into /etc/X11/xinit/xinitrc above exec dwm.

 while true; do
     playerctl metadata xesam:title > /tmp/SongTitle.tmp
     playerctl metadata xesam:artist > /tmp/SongArtist.tmp
     title=$(< /tmp/SongTitle.tmp)
     artist=$(< /tmp/SongArtist.tmp)

     xsetroot -name "${title}: ${artist}"
     sleep 1s
 done &

This will print title: artist in the menu bar.

  • Why use temp files?  Why not just say title=$(playerctl metadata xesam:title) and artist=$(playerctl metadata xesam:artist)? But note that Anonym’s answer (from 1½ years ago) already suggests using playerctl in a very similar way. – Scott Jan 25 at 20:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.