mp3 ファイルの文字化けを修正
iTunes に登録されていたファイルを mpd サーバーにコピーしてみたところ、mp3 ファイルで日本語の曲名やアルバム名などで文字化けが発生することに気づきました。どうやら mp3 のタグの文字コードが Shift-JIS になっているようで、iTunes では問題なく表示されるものの mpd では NG のようです。iTunes でも mpd でも文字化け無く表示できるよう、文字コードを変換することにしました。 Python 用の eyeD3 という mp3 のタグを読み書きできるモジュールがあるようなので、
の記事を参考に変換スクリプトを作ってみることにしました。以前作成した Mac OSX 10.9, Python 2.7, virtualenv 環境で開発します。
eyeD3 モジュールのインストール
$ pip install eyeD3
でインストールできるかと思ったら、
Downloading/unpacking eyeD3 Could not find any downloads that satisfy the requirement eyeD3 Some externally hosted files were ignored (use --allow-external eyeD3 to allow). Cleaning up... No distributions at all found for eyeD3 Storing debug log for failure in /Users/iwamoto/.pip/pip.log
と、エラーが出てしまいました。なぜエラーが出るかはよくわかりませんが
$ pip install --allow-external eyed3 --allow-unverified eyed3 eyed3
とすることで、うまくいきました。
chardet モジュールのインストール
文字コードの自動判定機能を使いたいので chardet モジュールをインストールします。
$ pip install chardet
こちらはすんなりインストール出来ました。
プログラム仕様
- 指定フォルダー以下の拡張子 .mp3 を処理対象とする。それ以外のファイルに対しては何もしない。
- 保存する際、ID3タグのバージョンは ID3v2.3 にする。保存の際にエラーが出たら(ID3v2.3に無いタグを使っている可能性があるので)ID3v2.4 で保存する。文字コードは UTF-16 とする。
- 文字列が格納されているタグはすべて文字コード変換対象とする。変換ルールは以下の通り。
- eyeD3 モジュールで取り出した文字列は Unicode 型になっている。この文字列は以下の4つに分類できる。
- の場合は何もしない
- その他の場合は、Unicode 型文字列を latin-1 エンコーディングで encode する。これを rawstr とする。
- この encode の時に例外が発生した場合は 4. であると考えられるので何もしない。
- chardet モジュールを使って rawstr の文字コードを自動判定する。信頼度(confidence)が99%以上の場合は、その文字コードを使って rawstr を unicode に変換する。
- 信頼度が99%未満の場合は cp932 エンコーディングで rawstr を Unicode 変換する(※)。この時例外が発生したら latin-1 エンコーディングで Unicode 変換する。
- 文字コード変換済みのタグをファイルに保存する。
※ の部分では正しく変換できるかどうかわからないので、あらかじめファイル名とエンコーディングの対応関係を指定してあった場合は、cp932 ではなく指定されたエンコーディングを使うこともできるようにする。
プログラム
bitbucket に公開しておきました。
注意: このプログラムを -x オプション付きで実行すると MP3 ファイルに埋め込んであるジャケット画像が消えてしまいます。消えて良い場合だけ実行してください。
まず、
$ python modid3.py -v .
とすると、カレントディレクトリ以下の全ての MP3 ファイルを検索し、対象となるファイルと変換後の文字列を画面に表示します。文字化けがないか(目視で!)確認します。文字化けがなければ
$ python modid3.py -v -x .
と -x オプション付きで実行すると実際に文字コードが修正されます。なお、-i オプション付きで実行すると eyeD3 モジュールが出す警告メッセージを表示しないようにします。もし、最初の
$ python modid3.py -v .
の実行で文字化けがあった場合は、文字化けが発生したファイルのパス名(の一部)と正しいエンコーディングとの対応関係を PREFERRED_ENCODINGS リストに追加するとそのエンコーディングを使って文字コードを変換します。