Friday, 31 January 2014

Migrating from Rhythmbox to Clementine

Some months back, an update rendered my main Rhythmbox installation largely unusable. Changing playlists would lock the application for about 60 seconds, and ultimately Rhythmbox would end up exhausting its stack and crashing. Not good.

To save myself from having to trawl the codebase searching for the needle in a haystack, I figured I'd switch to something shiny and fresh. After some searching, I settled on Clementine; a featureful, cross-platform player, boasting an Android remote control application, integration with countless online services, good performance with large libraries, visualisations, and the like.

Porting Metadata

In order to make the switch, I needed to migrate not only my songs, but also a few key pieces of metadata I decided I couldn't do without: rating, play count, and last played date.

Rhythmbox stores its library in an xml file, and Clementine stores its library in a sqlite database, and no migration tool existed that I could see. Hence, I hacked up a quick and nasty python script to do the dirty work and enrich Clementine's database with my additional metadata.

It relies on your having first imported your music into Clementine via the Clementine user interface.

The script searches Clementine's library, correlates songs (by path) between Clementine and Rhythmbox, and where it finds matches, it enriches Clementine's metadata.

The fact that it correlates songs by path location means that the location URIs in rhythmdb.xml must match the location URIs in Clementine's database; otherwise, the script won't be able to match them up.

If you're in the same boat I was, you may find this script useful to use as-is, or as a base to build on.


Caveat emptor: this script was tested once, using one library, on one system, with Rhythmbox 2.99.1, and Clementine 1.2.1. That is all.  Be forewarned: expect to have to delve into the Python code to get it working, or to have to restore your Clementine configuration from backup, or for your computer to spontaneously explode in disgust, or goodness knows what else.

This script was a quick hack for my one-time use, and is not something I've lovingly crafted and polished to make "production ready".


First, prepare your system:
  1. Import your music library into Clementine via the Clementine user interface.
  2. If necessary, make a copy of your rhythmdb.xml library (by default, located at ~/.local/share/rhythmbox/rhythmdb.xml)and perform search and replace with the tool of your choice, to clean the location URIs of any symlinks (e.g, file:///symlink/Bach/1.flac should be resolved to file:///absolute/path/to/Bach/1.flac). If you haven't used any symlinks in paths to your music files, then skip this step.
  3. Take a backup of your Clementine configuration directory, just in case: cp -R ~/.config/Clementine ~/.config/Clementine-backup
Then, download the script and run it in dry-run mode:

$ wget
$ chmod +x rhythmbox2clementine
$ ./rhythmbox2clementine -d

If satisfied that things look sensible, run it in commit mode:

$ ./rhythmbox2clementine

If something went wrong and you need to restore your original Clementine configuration, simply restore the backup directory you made earlier:

$ mv ~/.config/Clementine-backup ~/.config/Clementine


$ ./rhythmbox2clementine -h
usage: rhythmbox2clementine [-h] [-d] [--rhythmdb RHYTHMDB]
                               [--clemdb CLEMDB]

Enriches a Clementine library with ratings and play counts from Rhythmbox

optional arguments:
  -h, --help           show this help message and exit
  -d, --dryrun         Don't actually commit any changes to the Clementine
  --rhythmdb RHYTHMDB  Override the default Rhythmbox library location
  --clemdb CLEMDB      Override the default Clementine sqlite DB location

Sample output

$ ./rhythmbox2clementine -d
Operating in DRY RUN mode
Using Rhythmbox XML DB path: /home/[USER]/.local/share/rhythmbox/rhythmdb.xml
Using Clementine sqlite DB path: /home/[USER]/.config/Clementine/clementine.db
Rhythmbox library contains 50529 songs
Clementine sqlite 3.7.17
Clementine library contains 50782 songs
DRY RUN: Not committing any changes to your Clementine library

8552 out of 50529 songs would have been enriched