楽曲ファイルから amaroK のジャケット画像を探す

とある目的で表題のようなことがしたくなった。探すといってもネット上から新たに探す訳ではなくて、既に amaroK に登録してローカルに保存してある画像ファイルを楽曲ファイルから推測したいのだ。

画像自体は ~/.kde/share/apps/amarok/albumcovers/large 以下に保存されている。ただ、ファイル名は 0c81df7fb0a033460b86b0120cf0107e といったかんじでとりつくしまもない。

それなら amaroK のデータベースで曲と画像を紐付けてあるんだろうと予想して DB を覗くがどこにもそういったレコードは存在せず。

しょーがないのでソースを追っかけた。結論としては

  1. アーティスト名とアルバム名を小文字にして
  2. ローカルの文字コードエンコードして
  3. 継げて
  4. MD5 をとる

した値をファイル名にしているらしい。という訳で以下のようなスクリプトで楽曲ファイルからジャケット画像を探すことができた。

#!/usr/bin/env ruby

=begin
== Description
Find album cover image of Ogg vorbis file.
== Usage
  find.ogg.albumcover ogg_file
=end

require 'digest/md5'
require 'kconv'

COVER_BASEDIR = File.expand_path("~/.kde/share/apps/amarok/albumcovers/large")

ogg_file = File.expand_path(ARGV[0])
artist = ''
album = ''

unless File.exist?(ogg_file)
  warn("File not found: #{ogg_file}")
  exit 1
end

`vorbiscomment -R "#{ogg_file.gsub(/"/, '\"').gsub(/`/, '\`')}"`.each {|line|
  if line =~ /^artist=(.*)/i
    artist = $1
  elsif line =~ /^album=(.*)/i
    album = $1
  end
}

if 0 != $?
  exit $?
end

[artist, "Various Artists"].each {|a|
  cover_name = Digest::MD5.hexdigest((a + album).downcase.toeuc)
  cover_file = "#{COVER_BASEDIR}/#{cover_name}"
  if File.file?(cover_file)
    puts cover_file
    exit
  end
}

warn("Cover file not found.")
exit 1

Various なアルバムの場合、楽曲ファイルにはそのトラック自体のアーティスト名が入っていることが多いが、画像に変換する場合のアーティスト名は "Various Artists" が使われるのでそこだけ注意。

[追記:2006-02-20] Digest::MD5 ってのがあって Ruby でもネイティブに MD5 とれるんですね。こないだは何故か見つけきれなかった。てな訳でそっちを使うように修正。


どうでもいいけど僕はコマンドラインで md5sum を取るときに

echo "prince1999"|md5sum

とかやって「う〜ん、なぜ期待した値にならない???」と小一時間悩むことがよくあります…。