seraphyの日記

日記というよりは過去を振り返るときのための単なる備忘録

iTunes for Windowsの重複トラックにマークをつける方法

約10年間の愚痴

Windows 2000の頃からWindows Media Playerのみを愛好してきて、WMA形式こそがもっとも優れたフォーマットだと勘違い(?)していた私も、Media Player 11(on Vista)のあまりのできの悪さに、ついにiTunesの軍門に下ることにした。

以下、Windows Media Player 11の愚痴。

  • プレイリストが消えるのは日常茶飯事。(もう諦めた。)
  • ライブラリに登録していたはずのトラックがいつのまにかリンク切れになっていたり、そもそも亡かったことになっていたり。(前々からそうなんだけど、そのたびにスキャンし直せばいいんなんて思っていたけれど、Vistaになってからは、これがひどい。ひどいってもんじゃない。ひどすぎる。)
  • 最近はMedia Playerを立ち上げるだけで1CPU占有するようになってしまったし。(なにがきっかけかは分からないが、たぶん壊れたカタログでも永遠に更新してるんだろう。)

最後の問題は大きいな。
ネットには、それらしい苦情の情報もないが、私の環境だけなのだろうか。
それにしても他の問題は昔からだしな。
たぶん、だれもMedia Playerなんて使ってないってことなんだろう。多分。


iTunesに乗り換えてみたけれど。


で、iTunes for Windowsを入れてみた。

MacにははじめからiTunesが入っているわけで、そうゆう意味ではすでにiTunesユーザだし、とくに抵抗はない。
昔ならQuickTimeを入れるのには抵抗があったけれど、もうどうでもいい。


で、まずはiTunesWMAをインポートするわけだが、どこかで間違えて重複してインポートしてしまった。

同じソース(*.wma)からインポートするときにiTunes側でインポート済みのものは除外してくれるのかと勘違いしていた。

なので2回同じソースを指定してインポートしてしまった。

それに気がついたのは、たぶん*1全ファイルをインポートしおわったあと。

あれ、なんか同じ曲が2つづつ並んでるな−、とか思ったら…。


iTunesのファイルメニューから「重複を表示」は可能だが、数千個のファイルを手で選別するなんて無理だし、どうやら曲名(タイトル)だけで判断しているようで、明らかにDurationの違うトラックまで表示しているし。*2


せめてタイトルと時間とサイズが一緒ならば重複とみなせるかな。

こうゆう地味な作業は自動でやらせるに限る、と思い立つ。

iTunes COM for Windows SDK

iTunesぐらい著名なソフトになれば、きっとオートメーションに対応しているはず。

で、ちょっとググると、やはりiTunes COM for Windows SDKいうものがあるらしい。

ヘルプが欲しかったのでダウンロードしようと思ったが、ところが、これが落ちてこない。

AppleのDeveloper Connectionには登録しているし、XCode3をダウンロードしたことがあるのだが、なぜかエラーページにはじかれてアクセスできない。(うわ、幸先いいなー。)

一応、ダウンロードできました。*3

仕方ないので、ネットで検索したら出てきたiTunesの便利スクリプト集をベース*4に、
ヘルプ代わりにExcelVBAからiTunes Type Libraryを参照設定してオブジェクトブラウザから、それらしい使い方を見当つけてみる。

重複トラックにコメントをつけるスクリプトを書いてみる(JScript)

var iTunesApp = WScript.CreateObject("iTunes.Application"); 

var mainLibrary = iTunesApp.LibraryPlaylist; 

var tracks = mainLibrary.Tracks; 

// 重複の判定
var dup = {};
var numTracks = tracks.Count; 
while (numTracks > 0) {
	var currTrack = tracks.Item(numTracks); 
	var key;
	// 曲名+長さ+ファイルサイズが等しいものを重複と見なす
	key = currTrack.Name + ":" + currTrack.Duration + ":" + currTrack.Size;
	var arr = dup[key];
	if (arr == undefined) {
		arr = [];
		dup[key] = arr;
	}
	arr.push(currTrack.Location);
	
	numTracks--;
} 

// 重複したロケーションをリストアップ。
var skips = {};

for (key in dup) {
	var arr = dup[key];
	var mx = arr.length;
	if (mx > 1) {
		arr.sort(function(a,b){return a.length - b.length;});
	}
	var i;
	for (i = 1; i < mx; i++) {
		skips[arr[i]] = 1;
	}
}

// iTunesライブラリのトラックにコメントをつける。
numTracks = tracks.Count; 
while (numTracks > 0) {
	var currTrack = tracks.Item(numTracks); 
	var loca = currTrack.Location;
	if (skips[loca]) {
		try {
			currTrack.Comment = "**duplicate**";
			WScript.Echo(loca);
		} catch (e) {
			WScript.Echo("**ERROR: " + loca + ", " + e.toString());
		}
	}
	
	numTracks--;
} 

結論

このやっつけスクリプトcscript.exeから実行するとコンソールに該当ファイルをリストアップしながら曲のコメントを書き換えてゆく。
このスクリプト自体は削除までは行わず、コメントに印をつけるだけだから仮にバクっていても致命的なことにはならないだろう。

スクリプトの実行が終わったら、iTunesの画面で重複ファイルのみがコメントを書き換えられていことを目視し、コメント列でソートして一括選択・一括削除を手動で行う。

とりあえず、うまくいったようだ。


効率悪いコードに見えるけれど、そんなに時間かからなかった。
数分ぐらい?。数千件ぐらいなら、ちょっと待つぐらいで終わる。
iTunesの画面でコメントがつけられてゆく様子も見れるし。

ちなみに上1/3は、ネット上にあったスクリプトをまるぱくり状態。
こんなふうにすればiTunesから管理しているトラック情報に簡単にアクセスできると分かったので、このやり方で、いろいろ応用できそう。

早くもiTunesが大好きになりそうだ。

柔軟性は大事だよね。

*1:なぜか「多分」かは、全部変換できたかはチェックしてないので。

*2:シフトキーを押しながらメニューを開くと「完全に重複する項目を表示」に切り替わり、アルバム名、アーティスト名まで判断してくれるようになるので、かなり絞り込むことはできる。しかし、依然、長さの違う曲まで重複と見なしている点はかわらない。

*3:Appleに問い合わせたら、regionをJapanにしているのに英語でメールが返されてきた。日本にはスタッフがいないのか?。翻訳ソフトを使いながら返信してもうまく伝わらずあきらめかけていたが、先日、ダメもとで再度ダウンロードを試みたら、これがなぜかうまくいった。問い合わせたのが良かったのか、それとも一時的なものだったのか。

*4:もしかすれば、もっと探せば、そのものズバリのスクリプトもあったのかもしれないけれど。