Coverart display

Displaying Cover Art for mpd tracks with the help of naughty.

Cover Art should be in the same directory with song file.

= Used scripts =

I created two shellscripts for this task:

1) coverart.sh - Detects current song file directory and finds coverart within it


 * 1) !/bin/bash
 * 2) coverart.sh

DEFAULT_COVER="/path/to/defaultcover.png"

MUSICDIR=`cat /etc/mpd.conf | grep -v "#" | grep music_directory` MUSICDIR=${MUSICDIR:16} MUSICDIR=${MUSICDIR%/$}
 * 1) for 'mpd' users

MFILE=`mpc current -f %file%` MFILE=${MFILE%/*} MFILE=${MFILE%/$}

FULLDIR="$MUSICDIR/$MFILE"


 * 1) for 'moc' users under Debian, not sure if other distros use the 'mocp' name for the program:
 * 2) MFILE=`mocp --format "%file"`
 * 3) [ -n "$MFILE" ] && FULLDIR=`dirname "$MFILE"`

[ -n "$FULLDIR" ] && COVERS=`ls "$FULLDIR" | grep "\.jpg\|\.png\|\.gif"`

if [ -z "$COVERS" ]; then COVERS="$DEFAULT_COVER" else TRYCOVERS=`echo "$COVERS" | grep -i "cover\|front\|folder\|albumart" | head -n 1`

if [ -z "$TRYCOVERS" ]; then TRYCOVERS=`echo "$COVERS" | head -n 1` if [ -z "$TRYCOVERS" ]; then TRYCOVERS="$DEFAULT_COVER" else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi

COVERS="$TRYCOVERS" fi

echo -n "$COVERS"

2) musicinfo.sh - Prints any info you want to see in tooltip


 * 1) !/bin/bash
 * 2) musicinfo.sh

echo "Artist: `mpc current -f %artist%`" echo "Album: `mpc current -f %album%`" echo -n "Year: `mpc current -f %date%`"

for those who use moc under Debian. Other distros might not use the mocp name for the program:


 * 1) !/bin/bash
 * 2) musicinfo.sh

date +"%F%n%a %b %d, %-l:%M%P"

if mocp --info 2>/dev/null | grep -q PLAY; then mocp -Q " Artist:	%artist Album:	%album Song:	%song Time:	%ct/%tt" else echo "Nothing playing..." fi

= Changes in rc.lua = 1) You need to add function to show/hide tooltip

local coverart_nf function coverart_show -- destroy old popup, needed when bound to a key coverart_hide local img = awful.util.pread("/path/to/coverart.sh") local ico = image(img) local txt = awful.util.pread("/path/to/musicinfo.sh") -- set desired position of popup during creation coverart_nf = naughty.notify({icon = ico, icon_size = 100, text = txt, position = "bottom_left"}) end

function coverart_hide if coverart_nf ~= nil then naughty.destroy(coverart_nf) end end

2) You need to add mouse event handlers to a widget, or a key binding. The position of the popup is set in the coverart_show function above.

Note: mpdw is my widget displaying mpd info. mytextclock would work just as well if you haven't got a mpdw widget running.

mpdw:add_signal("mouse::enter", function	coverart_show end)

mpdw:add_signal("mouse::leave", function	coverart_hide end)

A sample key binding that you would add to your globalkeys table:

awful.key({ modkey,          }, "slash", function  coverart_show end),

= Add some dynamics =

If you'd like to display coverart on song change, or if you'd like to display coverart as a widget on your root window and change all fields dynamically, it is a very simple task with the help of Bashets.

1. To display coverart on a song change, you need to register a simple callback function:

ctitle = "" function mpd_callback(data) if data[1] ~= ctitle then                    --here "1" may be "3" or "2", or any other number of your variable ctitle = data[1] coverart_show end end bashets.register("mpd.sh", {update_time = 1, separator = "|", callback = mpd_callback})

Here mpd.sh is your shellscript which returns separator-separated values. For example, here is a simplified version of my mpd.sh:

TITLE=`mpc | head -n 1` MTIME=`mpc | head -n 2 | tail -n 1 | awk '{print $3}'` CURR=`mpc current` if [ -z "$CURR" ]; then TITLE="mpd `mpd --version | head -n 1 | awk '{print $6}'`" MTIME="stopped" fi echo -n "$TITLE|$MTIME"

which returns something like

Artist - Song|00:00/99:99

Here "Artist - Song" corresponds to the first variable - $1 in format string or data[1] in data table, and "00:00/99:99" corresponds to the second variable. The separator is "|", as mentioned above in register call.

2. To display a coverart widget on your root window, you are able to define it yourself (see naughty sources for example how to arrange elements within a wibox, then add your wibox to current screen with a geometry you prefer) and to register all it's textbox widgets in bashets:

bashets.register("mpd.sh", {widget = mpdw, format = '$1 | $2', update_time = 1, separator = '|'}) bashets.register("mpd.sh", {widget = mpdw, format = '$3', update_time = 1, separator = '|'})

Also you can combine callback call with widget updates, e.g.: bashets.register("mpd.sh", {widget = mpdw, format = '$1 | $2', update_time = 1, separator = '|', callback = mpd_callback})

Note: callbacks are available since bashets 0.4.

= Using dbus for coverart =

In the script using the mapping of the cover and title of the song there is some drawback, for it is necessary to create a separate widget (which for me turned out to be uncomfortable). Found in the network scripts notifications work through  notify-send , whose Debian's default is not, and it is not advisable, because if you switch one song after another (for example, in search of music in the mood), you will see a lot of pop-ups, that is not very nice. So I suggest you slightly revised version of the above scripts but working via D-Bus, and automatically replaces/closing the old notice, plus a cover of the track displays. Additionally, both scripts combined into one. Script reworked to moc/mocp.

Unfortunately mocp not support dbus, but it can cause an external command when changing the track (and not only for details to the documentation).

Add in mocp config: OnSongChange = "/home/user/script/changesong.sh %f %a %t %d %r %n" Here we are passing all the required parameters: the path to the file, artist, title, time, album, in order then to not pull mocp again to get the data, as indicated in the original versions of these scripts.

Then, create a script (changesong.sh) for the cover and the formation of the text:
 * 1) !/bin/bash
 * 2) changesong.sh

DEFAULT_COVER="/home/user/Images/no-cover.jpg"

if mocp --info 2>/dev/null | grep -q PLAY; then [ -n "$1" ] && FULLDIR=`dirname "$1"`

[ -n "$FULLDIR" ] && COVERS=`ls "$FULLDIR" | grep "\.jpg\|\.png\|\.gif"`

if [ -z "$COVERS" ]; then COVERS="$DEFAULT_COVER" else TRYCOVERS=`echo "$COVERS" | grep -i "cover\|front\|folder\|albumart" | head -n 1`

if [ -z "$TRYCOVERS" ]; then TRYCOVERS=`echo "$COVERS" | head -n 1` if [ -z "$TRYCOVERS" ]; then TRYCOVERS="$DEFAULT_COVER" else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi COVERS="$TRYCOVERS" fi

#echo -n "$COVERS"

MTITLE="

Artist: $2 Title: $3 Album:	$5 Track: 	$6 Time: 	$4"	if [ -z $1 ]; then		MTITLE=`mocp -Q "

Artist:	%artist Title:	%song Album: 	%album Time: 	%tt" ` 	fi else	MTITLE="

Nothing playing..."	COVERS="$DEFAULT_COVER" fi

dbus-send --session --dest=org.naquadah.awesome.awful /ru/console/mocp ru.console.mocp.songChanged \ string:"$MTITLE" \ string:"$COVERS" Give the right to the script execution: chmod +x changesong.sh Adds handlers to the Awesome: function notifyHide(mynotification)   --функция удаляет уведомление по переданному идентификатору if mynotification ~= nil then naughty.destroy(mynotification) return nil else return true end end

dbus.request_name("session", "ru.console.mocp" dbus.add_match("session", "interface='ru.console.mocp', member='songChanged' ") dbus.add_signal("ru.console.mocp", function(...) local data = {...} --убираем старую информацию notifyHide(coverart_nf) coverart_nf = naughty.notify({icon = data[3], icon_size = 100, text = data[2], position = "bottom_left"}) end )