Saturday, January 26, 2008

CD cover art in Amarok

I have long since RIPed all my CDs and they're now stored in the basement. I listen to my music on my MP3 player or on various computers that have a copy of the collection (including the living room MythTV media center of course). I use Amarok as player on most of the computers. It has a nice cover manager which can retrive cover art from various Amazon sites or give the URL to a cover image stored elsewhere. IMHO the covers adds to the experience of playing MP3s and I like the feature very much.

But, Amarok keeps the cover art in a cache directory with md5 sum file names. When I copy my collection to a new computer I have to re-find all the covers... This sucks. Amarok has a second way of storing the cover images. If I save a graphics file in a album directory this will be viewed as the album cover by Amarok. So all I have to do is get the covers from the cover manager into the MP3 directory hierarchy. Right!

It turns out that Amarok can be remote controlled by DCOP, "Desktop Communications Protocol", which is sort of like DBUS ("desktop bus" I suspect, it's part of the open desktop initiative which, it appears, will eventually make all the different desktops somehow interoperable by using common protocols).

If I type "dcop amarok" at a shell promot I get a list of all functions available:

qt
KBookmarkManager-/home/janl/.kde/share/apps/amarok/fileBrowserBookmarks.xml
KBookmarkNotifier
KDebug
KDirNotify-1
KIO::Observer
KIO::Scheduler
MainApplication-Interface
collection
contextbrowser
devices
html-widget1
html-widget2
html-widget3
html-widget4
html-widget5
ksycoca
mediabrowser
player (default)
playlist
playlistbrowser
script
Turns out I can do quite a lot with this, like starting and stopping playback. Changing the volume or skipping to the next track.

After some trial and error I found "dcop amarok player coverImage" which will return the path of the cover image of the currently played track: "/home/janl/.kde/share/apps/amarok/albumcovers/cache/130@7ab00582116d9a9034221828a4df648e" and similarly "dcop amarok player path" which returns the path of the currently playing track. So I know what directory the currently playing album is stored in. Just a short script away from what I want then:

#!/bin/bash

# Script to dump cover art into album directories.

# BEFORE YOU RUN THIS:
# - Use the cover manager to find and install covers for everything
# - Load your entire collection in the playlist
# - Set the volume to "0".
# - Run this script - and wait... Note that the script cannot tell when it
# has completed O:-)

# This scrip will for each played track ask for
# - The directory it is stored in
# - The cover image
# - If there is no cover image in the directory given copy the cover image
# there with the filename albumcover.png

# This all takes a good while if you have some thousands of tracks,
# perhaps as long as one second pr. track, so easily hours. But it is
# automatic

OSD=$(dcop amarok player osdEnabled)
dcop amarok player enableOSD false
dcop amarok player play

while :; do
ALBUM="$(dcop amarok player album)"
NOW="$(dcop amarok player nowPlaying)"

echo "** $NOW / $ALBUM"
TRACKPATH=$(dcop amarok player path)
COVER=$(dcop amarok player coverImage)
dcop amarok player next

case $COVER in
*nocover.png) continue;;
esac

DIR=$(dirname "$TRACKPATH")
[ -f "$DIR/albumcover.png" ] || cp -v "$COVER" "$DIR/albumcover.png"
done

dcop amarok player enableOSD $OSD
Now I can use rsync or unison to bounce my collection around - including the covers. ... But wait, it's not quite perfect yet, I'd like my MP3 player to show covers as well! There were several rockbox cover scripts in the Amarok wiki, but none suited me perfectly. Fortunately it's only a question of generating a 100x100 .bmp file called "cover.bmp" in each directory. The "convert" command from Image Magick does this without fuzz. Thus this script:

#!/bin/bash

COVER_SIZE="100x100"
RBNAME=cover.bmp

find . -name 'albumcover.png' -print | while read cover; do
DIR="$(dirname "$cover")"
NEW="$DIR/$RBNAME"
if [ -f "$NEW" ] ; then
continue
fi
echo Converting cover in "$DIR"
convert "$cover" -geometry $COVER_SIZE "$NEW" || exit 1
done

To use it simply cd to a MP3 directory hierarchy and it will find all albumcover.png files and make cover.bmp from them. Then sync to your rockbox MP3 player.