Using MusicIP with mpd

Lately I’m using mpd instead of a squeezebox as my network music player of choice.  The only thing I miss about squeezebox is its integration with MusicIP.  MusicIP is a great piece of abandon-ware.  It analyzes your digital music collection to discover acoustic “similarity” between tracks.  Given a seed song (or songs), it creates a playlist of “similar” songs — sort of like Pandora, but operating on your own music collection.  (The notion of “similar” here is based on some undisclosed metric; MusicIP is most regrettably closed-source.)  I’ve used MusicIP for years now and I’m still impressed by how well it works.  It’s an integral part of how I navigate my music collection.

I wrote a simple script to act as a middle man between MusicIP and mpd.  It gets the current song from mpd, asks MusicIP to generate a playlist with this song as the seed, and passes the result back to mpd.  You can run it from any machine on your network.  Linking this script to a desktop icon gives a nice way to generate a MusicIP mix with one click.

#!/bin/bash
# Richard Taylor 26.May.2013
# A script to generate a MusicIP playlist for mpd, using
# the current song as the seed.

# Prerequisites:
# 1) musicIP server installed in headless mode somewhere on the
#    network and answering on http://MIPHOST:MIPPORT
# 2) mpd running somewhere on the network
# 3) mpc installed on localhost (with the MPD_HOST environment
#    variable set accordingly, if your mpd isn't on localhost)
# 4) curl installed on localhost

# Set these to match your setup:
MIPHOST=localhost
MIPPORT=10002
MUSICDIR='\/tunes\/'  # music root folder (slashes must be escaped)
MIXSIZE=12

MIPURL="http://$MIPHOST:$MIPPORT/api/mix"

# Use mpc to check if mpd is currently playing:
if mpc | grep -q "playing"
  then
        echo "mpd playing; using current song as seed"
        mpc -q crop
  else
        echo "mpd not playing; using last song in playlist as seed"
fi

## Get the last song in the current playlist; mpc reports relative
## paths but MusicIP expects absolute paths, so use sed to prepend
## MUSICDIR to the path:
SEED=`mpc -f "%file%" playlist | tail -n 1 | sed -e "s/^/$MUSICDIR/"`

# Uncomment this to see the communication with the MusicIP server:
#curl -v -G -d size=$MIXSIZE --data-urlencode "song=$SEED" "$MIPURL"

# Use curl to request a playlist from the MusicIP server;
# the result is a list of full paths to music files.  Since mpc
# expects paths relative to MUSICDIR, we use sed to strip the
# leading MUSICDIR from the path before passing the playlist to mpc.
# The first song in the playlist should be the seed, so we remove
# it since it's already at the end of the current playlist. 
curl -G -d size=$MIXSIZE --data-urlencode "song=$SEED" "$MIPURL" | \
  sed -e "s/$MUSICDIR//" | tail -n +2 | mpc add

By the way, spicefly has loads of good info about MusicIP and how to set it up, including documentation of the server API.

Leave a Reply

Your email address will not be published. Required fields are marked *