iTunes はアートワークを設定しておくと、プレイヤーの左下にアートワークが表示できます。が、1個ずつ設定するのはめんどくさすぎ。なので、Amazon Web Services からとってきて、iTunes COM つかって設定してしまいましょう、と。
以下のソースを fetch-artwork-aws.pl で保存して実行。ActivePerl と、それぞれモジュール、それに AWS のデベロッパトークンが必要です。さすがにこれを Pure WSH で書くのはしんどい。
なんだか日本盤がうまくいかないなあ。日本語は Shift_JIS => UTF-8 変換をいれてみたがだめか。→ %Cache が US と JP で同じものもってたので修正。
use strict;
use Cache::FileCache;
use Cwd;
use Encode;
use File::Basename;
use File::Spec;
use Image::Size;
use LWP::Simple;
use Net::Amazon;
use Net::Amazon::Request::Keyword;
use Win32::OLE;
our $ImageDir = File::Spec->catfile(cwd, "itunes-images");
our $DeveloperToken = "XXXXXXXXXXXX";
mkdir $ImageDir, 0777 unless -e $ImageDir;
my $itunes = Win32::OLE->new("iTunes.Application");
my $playlist = $itunes->LibraryPlaylist;
my $tracks = $playlist->Tracks;
my $count = $tracks->Count;
for (my $i = 1; $i < $count; $i++) { # start from 1
my $track = $tracks->Item($i);
next if $track->Artwork->Count;
my $artist = $track->Compilation ? "" : $track->Artist;
my $item = retrieve_item($artist, $track->Album, "", "music");
$item ||= retrieve_item($artist, $track->Album, "jp", "music-jp");
if ($item) {
my $url = $item->ImageUrlMedium;
my $file = File::Spec->catfile($ImageDir, basename($url));
unless (-e $file) {
warn "fetching $url\n";
LWP::Simple::getstore($url => $file);
}
my($width, $height) = imgsize($file);
unless ($width == 1 && $height == 1) {
$track->AddArtworkFromFile($file);
}
}
}
my %Cache;
sub retrieve_item {
my($artist, $title, $locale, $mode) = @_;
my $cache_key = join "|", $artist, $title, $locale;
if (exists $Cache{$cache_key}) {
return $Cache{$cache_key};
}
warn "Searching AWS for $artist - $title\n";
my $cache = Cache::FileCache->new({
cache_root => File::Spec->catfile($ENV{TMP}, "itunes-cache"),
default_expires_in => "60 min",
});
my $attr = {
token => $DeveloperToken,
cache => $cache,
};
$attr->{locale} = $locale if $locale;
my $ua = Net::Amazon->new(%$attr);
my $keyword = "$artist $title";
Encode::from_to($keyword, "Shift_JIS" => "UTF-8");
my $req = Net::Amazon::Request::Keyword->new(
keyword => $keyword,
mode => $mode
);
my $response = $ua->request($req);
my $item = ($response->properties())[0];
$Cache{$cache_key} = $item;
return $item;
}