DLNA 対応の有無を問わず大抵のオーディオ・プレイヤー・ソフトや機器は、任意のフォルダー内に置いた特定のファイル名の画像ファイル (folder.jpg/cover.jpg/<アルバム名>.jpg) だったり、個々の MP3 ファイル等に直接埋め込まれた画像をアルバム・ジャケットとして表示する機能を持っているが、複数の方式に対応していることが多い。
アルバム画像を外部ファイルとしてフォルダー中に置くか、個々の MP3 に埋め込むかは意見の分かれるところだと思うが、僕は断然外部ファイル派 (folder.jpg) だ。これは Web ページが参照するスタイル・シートを CSS ファイルとして独立させるか、個々のページに直接書くか、と言った話と同種の問題で、特殊な事情がある場合を除いて、作業効率とデータ量の点で議論するまでもないと考えている。我が家のオーディオ・データ用アルバム画像 (標準サイズは 500x500px) は、主にインターネットで検索したり、自らスキャンした画像データを加工して作成していて、より高精細なデータを見つけたり、品質に問題がある画像を修正する等して差し替えが頻繁に発生するため、アルバム画像は別ファイルとして独立していた方が、断然効率がいい。
ところが先日、妻用に購入したあるデジタル・オーディオ・プレイヤーが原因で、アルバム画像として同一フォルダー中の folder.jpg を参照する大量の MP3 ファイルに、従来の方針を 180° 転換して画像を埋め込まざるを得ない事態が発生した (理由は後述)。アルバム画像を含む ID3 タグ情報を編集できるソフトはいろいろあるが、これを全て手作業で修正していては、たまったものではない。そこで Linux 上でコマンドによる ID3 タグ操作が可能なツールを探し、eyeD3 を使うことにした。
eyeD3 公式サイトによると、本エントリー執筆時の最新版 0.6.17 では動作条件として Python が 2.5 以上とされているが、我が家の主力 Linux である CentOS 5.6 の Python は 2.4 系。アップグレードは面倒だなと思っていると、同サイトの旧バージョン配布ページに 0.6.10 の RPM を発見し、ありがたく使わせていただくことにした。インストールは rpm コマンド一発で終了。
ちなみにソースコードに同梱の readme を見る限り、Python が 2.5 以上になったのは 0.6.17 から。0.6.16 までは Python 2.3 以上とされているので、eyeD3 を CentOS 5.x にソースからインストールする場合は、0.6.16 以前のバージョンをどうぞ。
インストールが終われば、eyeD3 コマンドが使えるようになる。オプション --help や、man で詳細な使い方が表示されるが、今回僕が必要なのは、アルバム画像の操作に関連したオプションのみ。ざっと目を通しつつ必要なオプションをピックアップすると、以下のようになった。
・メディア・ファイルの情報を表示 $ eyeD3 <メディア・ファイル> (-v オプションで詳細表示) ・画像を埋め込む $ eyeD3 --add-image=<画像ファイル>:FRONT_COVER <メディア・ファイル> ・埋め込まれている画像を削除 $ eyeD3 --add-image=:FRONT_COVER <メディア・ファイル> ※ メディア・ファイルの指定ではワイルド・カードを使用可能。
--add-image オプション (":FRONT_COVER" の前) に空文字を指定することで、削除の指示になる。当初は埋め込みだけで十分だと考えていたが、既に画像を持っているメディア・ファイルに対して --add-image を実行すると、画像が上書きではなく複数個埋め込まれてしまうことが判明 (2個以上の画像を持てるとは知らなかった!)。意図して複数の画像を埋め込むのでなければ、対象のメディア・ファイルが既に画像を持っている場合は、事前に削除しておいた方がいいと思う。
eyeD3 には、ID3 タグのバージョンを変換するオプションが用意されている。僕が普段 ID3 タグ情報の編集に使っている SuperTagEditor 改 Plugin Version で ID3 タグのデフォルト・バージョンを v2.4 に設定してあり、一度でも同ツールで編集した MP3 ファイルなら v2.4 になっている (はず) だが、その洗礼を受けていないファイルがあった場合に備え、画像埋め込み時に v2.4 に変換するオプション --to-v2.4 を併用した。
・画像を埋め込む (同時に ID3v2.4 に変換) $ eyeD3 --to-v2.4 --add-image=<画像ファイル>:FRONT_COVER <メディア・ファイル>
画像の埋め込み/削除が意図通りに動作することを確認したら、任意のディレクトリ以下のアルバム用ディレクトリを探して、直下にある folder.jpg を同じ場所の MP3 ファイルに埋め込むスクリプトを書く。我が家の環境に依存する部分があって汎用性に欠けるので公開はしないが、僕は次のような方針とした。
- オーディオ・データのディレクトリ構造は、「ジャンル」→「アーティスト」→「アルバム」。 (既存)
- アルバム画像は、各「アルバム」ディレクトリ中の folder.jpg。(既存)
- 前回チェック時からファイル・システム上の変化がなければ、何もせずに終了。
- 「アルバム」ディレクトリ中には、原則的に folder.jpg 以外の画像ファイルを置かない。
- 画像埋め込みと同時に、ID3 タグを v2.4 に変換する。
- 画像以外の ID3 タグ情報は編集しない (v2.4 変換は除く)。
- 1つの MP3 ファイルに複数の画像を埋め込まない。
- MP3 ファイルに画像を埋め込みつつ、folder.jpg も併用する。
- 「アルバム」ディレクトリ中で folder.jpg よりタイム・スタンプが新しい JPEG ファイルを発見した場合は、既存の folder.jpg を削除して新しい画像を folder.jpg にリネームし、各 MP3 ファイルについて古い埋め込み画像を削除してから、新しい folder.jpg を埋め込み直す。
- 画像埋め込み強制実行フラグが ON の場合は、各 MP3 ファイルについて埋め込み画像があれば削除し、既存の folder.jpg を新画像として再度埋め込む。
- 原則的に全オーディオ・データについて実行するが、ジャンル単位で実行範囲を限定できる。
"9." は、任意のアルバムのディレクトリ内に新しい画像を放り込んでおけば、(cron に登録して) 一定の間隔で走るスクリプトが、全自動でアルバム画像を差し替えてくれると言う機能。アルバム画像を MP3 ファイルに埋め込むことで跳ね上がるデータの管理コストを低減させるためには、欠かせない。ただし画像差し替えの判断基準は画像のタイム・スタンプを機械的に比較しているだけなので、「アルバム」ディレクトリに入れた画像が違うアルバムの物でも、更新されてしまう (画像ファイル名と ID3 タグ中のアルバム名を対応させる等の対策はあるが、面倒だったので今回はパス)。
"10." は普段使うことはないが、初回埋め込み時 (まだどの MP3 ファイルにも画像が埋め込まれていない状態) のみに必要だったので実装した、「問答無用で画像埋め込み」モード。
尚、画像の埋め込み前に既存の画像を削除する処理では、何らかの理由で埋め込み画像が 2個以上あった場合を想定し、埋め込み画像の数が 0 になるまで削除を繰り返す、と言う方法を採っている。eyeD3 コマンドで表示される情報の中に
FRONT_COVER Image: [Size: 71480 bytes] [Type: image/jpeg]
と言う行が埋め込み画像の数だけ出力されるので、grep "FRONT_COVER Image" | wc -l で、画像の数を判断できる。またスクリプトとは関係ないが、Windows 上で埋め込み画像の数を確認する場合は、Mp3tag で "Cover" カラムを表示するとわかりやすい。
過去に作成して運用中だった「アルバム画像がない (=folder.jpg が存在しない)」「アルバム画像のサイズが標準値と異なる (=ImageMagick に含まれる identify コマンドでチェック)」「ファイル名が命名規則に則っていない」等のチェックも、ついでに今回のスクリプトに統合した。これらチェックの結果は随時任意のファイルに「アルバム」ディレクトリ単位で出力するようにしてあるので、いずれ処理しなければいけない「宿題リスト」は、常に最新の状態に保たれている。
さて今回、MP3 ファイルに画像を埋め込む羽目になった原因を作ったのは、SONY の WALKMAN NW-S756 と言う製品。長くなったので、その理由については別エントリーで (別に勿体ぶるような内容ではないけれど)。