要の純然たる日記(旧館)

今は http://kanamef.sblo.jp に書いてます

iTunesライブラリの解析

iTunesライブラリの曲数が1万トラックを超えた記念に、自分のライブラリを解析できるようにしてみることにした*1
iTunesライブラリの情報はXML形式で、/Users/[user]/Music/iTunes/の"iTunes Music Library.xml"というファイルに格納されている。中身はplist (プロパティリスト = Property List) のXML表現。PlistのXML表記は美しくないから嫌いなんだけど、文句言っても仕方ない。
PlistのXML表現をRubyで扱うにはplist (http://plist.rubyforge.org) を使えば楽。plist-3.0.0まではRuby 1.9.xに対応していないので、3.1.0以降を使う。

$ sudo gem install plist

これを使ってライブラリのXMLファイルを読み込むと1つのHashに入る。iTunesライブラリのplistの最上位keyは、"Major Version", "Minor Version", "Application Version", "Features", "Show Content Ratings", "Music Folder", "Library Persistent ID", "Tracks", "Playlists"がある。このうち、曲データは"Tracks"にある。この"Tracks"の値も、曲のIDをkeyにしたHashになっている。keyは、僕のライブラリに入っている範囲だと以下があった。全てのkeyが全ての曲に入っているわけではない。

"Album", "Album Artist", "Album Rating", "Artist", "Artwork Count", "BPM", "Bit Rate", "Comments", "Compilation", "Composer", "Date Added", "Date Modified", "Disabled", "Disc Count", "Disc Number", "File Folder Count", "File Type", "Genre", "Grouping", "Kind", "Library Folder Count", "Location", "Name", "Part Of Gapless Album", "Persistent ID", "Play Count", "Play Date", "Play Date UTC", "Podcast", "Protected", "Purchased", "Rating", "Rating Computed", "Release Date", "Sample Rate", "Size", "Skip Count", "Skip Date", "Sort Album", "Sort Album Artist", "Sort Artist", "Sort Composer", "Sort Name", "Start Time", "Stop Time", "Total Time", "Track Count", "Track ID", "Track Number", "Track Type", "Unplayed", "Volume Adjustment", "Year"

これを全部入れるclassを作って解析してやれば良い。さしあたり面倒くさいので、使う奴だけ適宜入れていくことにする。サンプルに、アルバム数を数えるスクリプトを載せておこう。

#!/usr/local/bin/ruby

require "plist"

class Track
  attr_accessor :album_artist, :album, :artist
  def initialize(track)
    @album = track["Album"]
    if @album == nil then
      @album = "[none]"
    end
    @artist = track["Artist"]
    if @artist == nil then
      @artist = "[none]"
    end
    @album_artist = track["Album Artist"]
    if @album_artist == nil then
      @album_artist = @artist
    end
  end
end

if ARGV.length > 1 then
  if File.exists?(ARGV[0]) then
    file = ARGV[0]
  else
    $stderr.print "no such file: #{ARGV[0]}\n"
  end
else
  file = File.expand_path("~/Music/iTunes/iTunes Music Library.xml")
end

albums = {}
fullplist = Plist::parse_xml(file)
fullplist["Tracks"].each do |k,v|
  t = Track.new(v)
  if albums[[t.album_artist, t.album]] == nil then
    albums[[t.album_artist, t.album]] = 1
  else
    albums[[t.album_artist, t.album]] += 1
  end
end

albums.keys.sort.each do |key|
  print "#{albums[key]}\t#{key[0]}\t#{key[1]}\n"
end

$stderr.print "total #{albums.length} albums\n"

# タイトルのないアルバムと1曲しか入っていないアルバムは排除
albums.delete_if {|k,v| k[1] == "[none]" or v < 2}

$stderr.print "total #{albums.length} albums with two or more tracks\n"

で、結果、いまのところ918タイトルのアルバムが入っているらしい。まあアルバムによっては複数ディスクをまとめて1タイトルにしているものもディスクごとにタイトルを分けているものもあるので、やり方によって結果は変わるけど、とりあえずそんなもんか。500枚くらいかと思ってたけど、意外にあるもんだな。
あとは、色んな人がやっているバージョンを全部ひっくるめて一番沢山入っている曲は"The sermon"(Jimmy Smith)と、"My funny valentine"が10トラックずつで、その次は"Autumn Leaves"が9トラック、以下、Milestonesが8トラックで続く、ということが分かった。ちょっと意外。

*1:実際には英語教材なんかも入っているので、音楽だけで1万曲以上ってわけではない