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
#!/bin/bash
# coverart.sh
DEFAULT_COVER="/path/to/defaultcover.png"
# for 'mpd' users
MUSICDIR=`cat /etc/mpd.conf | grep -v "#" | grep music_directory`
MUSICDIR=${MUSICDIR:16}
MUSICDIR=${MUSICDIR%/$}
MFILE=`mpc current -f %file%`
MFILE=${MFILE%/*}
MFILE=${MFILE%/$}
FULLDIR="$MUSICDIR/$MFILE"
## for 'moc' users under Debian, not sure if other distros use the 'mocp' name for the program:
#MFILE=`mocp --format "%file"`
#[ -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
#!/bin/bash #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:
#!/bin/bash
#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.