DLNA 経由でアクセスする音楽のメタデータ文字化け問題を調べる
目次
はじめに
Bubble UPnP で DLNA サーバーの音楽を再生 にて最後に以下のように述べました。
次回の技術ネタは、前回「気になりますが」と述べ、今回も「これについては別途」とした文字化けを何とかしたいですね。メディアファイルに埋め込まれたメタデータの文字コードの問題であることはわかっているのですが…解決できるかな?
Bubble UPnP で DLNA サーバーの音楽を再生
で、すみません!残念ながらまだ解決には至っていません。ただ何が起きているのかは大体わかったので、ひとまずその状況について書いておきます。
なお、これまでの流れもあってタイトルを「DLNA でアクセスする…」としましたが、実は DLNA は無関係で、ID3v2 メタデータの文字コードの誤った運用とそれに対するプレーヤーの対応の違いが問題の本質でした。
現状のおさらい
ラズパイにインストールした openmediavault (以下 OMV) と、そのプラグインとしてインストールした MiniDLNA でメディアサーバーを構築し、Android スマホの Bubble UPnP で音楽再生できるようにした、というのがこれまでやってきたことでした。そして Bubble UPnP でメディアをブラウズすると一部のアルバムや楽曲のタイトルが文字化けしていました。ここまでが前回。
調査のための環境
さて、これが実際どうなっているのかをさらに調べます。調査には Windows 10 の WSL2 にインストールした Ubuntu 18.04 を使います。手元の環境は MiniDLNA でメディアファイルを提供しているドライブは samba/cifs でもアクセスできるようにしてあるので、これを Ubuntu 上にマウントします。サーバーは Windows からは \\rsp-nas としてアクセスでき、share が共有用のディレクトリであるとします。/mnt/omv にマウントする場合以下のようになります。
$ sudo mkdir /mnt/omv
$ sudo mount -t drvfs \\\\rsp-nas\\share /mnt/omv
別途確認したところ、上で文字化けしている King Gnu の楽曲はアルバム『Tokyo Randez-Vouz』の「あなたは蜃気楼」でした。ファイルを確認します。
$ cd /mnt/omv/media/music/King\ Gnu/Tokyo\ Rendez-Vous/
$ ls
'01 Tokyo Rendez-Vous.mp3' '05 破裂.mp3' AlbumArtSmall.jpg
'02 McDonald Romance.mp3' '06 ロウラヴ.mp3' AlbumArt_{B5020207-474E-4720-7F17-ED1ADF57F100}_Large.jpg
'03 あなたは蜃気楼.mp3' '07 MIDNIGHT POOL.mp3' AlbumArt_{B5020207-474E-4720-7F17-ED1ADF57F100}_Small.jpg
'04 Vinyl.mp3' '08 サマ―レイン・ダイバー.mp3' Folder.jpg
ファイル名は問題ないですね。でも DLNA ではプレーヤーに表示されるタイトル等とファイル名は関係ないのでメタデータを確認する必要があります。MP3 の音楽ファイルでは ID3 という形式のメタデータが使われているので、これを扱えるようにする必要があります。調べると mutagen という Python モジュールが使えるようです。
Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC, MP4, Monkey’s Audio, MP3, Musepack, Ogg Opus, Ogg FLAC, Ogg Speex, Ogg Theora, Ogg Vorbis, True Audio, WavPack, OptimFROG, and AIFF audio files. All versions of ID3v2 are supported, and all standard ID3v2.4 frames are parsed. It can read Xing headers to accurately calculate the bitrate and length of MP3s. ID3 and APEv2 tags can be edited regardless of audio format. It can also manipulate Ogg streams on an individual packet/page level.
mutagen
インストールします。
$ sudo apt install python-mutagen
コマンドラインツールによるメタデータの内容確認
ドキュメントの Command Line Tools を見ると mid3v2 というコマンドで ID3 の内容確認ができるようです。試してみます。
$ mid3v2 03\ あなたは蜃気楼.mp3
IDv2 tag info for 03 あなたは蜃気楼.mp3
MCDI=[unrepresentable data]
PRIV=AverageLevel='{%\x00\x00'
PRIV=PeakValue='\xa1~\x00\x00'
TALB=Tokyo Rendez-Vous
TCOM=mcåó
TCON=Indie / Alternative
TIT2= ȽÍåC
Wikipedia の ID3 タグ でフレーム ID を確認すると、楽曲タイトルは TIT2 らしいですが…
これではわからないので mid3v2 のオプションを確認すると –list-raw で生データが見られるようです。
$ mid3v2 --list-raw '03 あなたは蜃気楼.mp3'
Raw IDv2 tag info for 03 あなたは蜃気楼.mp3
TLEN(encoding=<Encoding.LATIN1: 0>, text=[u'196426'])
TYER(encoding=<Encoding.LATIN1: 0>, text=[u'2017'])
PRIV(owner=u'AverageLevel', data='{%\x00\x00')
TALB(encoding=<Encoding.LATIN1: 0>, text=[u'Tokyo Rendez-Vous'])
TRCK(encoding=<Encoding.LATIN1: 0>, text=[u'3'])
MCDI(data='8\x00+\x009\x006\x00+\x004\x007\x005\x009\x00+\x007\x007\x00E\x007\x00+\x00B\x001\x007\x003\x00+\x001\x000\x007\x00B\x002\x00+\x001\x006\x005\x001\x003\x00+\x001\x00A\x003\x005\x00A\x00+\x001\x00C\x009\x008\x00A\x00+\x002\x001\x004\x00E\x009\x00\x00\x00')
TPE1(encoding=<Encoding.LATIN1: 0>, text=[u'King Gnu'])
TIT2(encoding=<Encoding.LATIN1: 0>, text=[u'\x82\xa0\x82\xc8\x82\xbd\x82\xcd\xe5\x87\x8bC\x98O'])
TCOM(encoding=<Encoding.LATIN1: 0>, text=[u'\x8f\xed\x93c\x91\xe5\x8a\xf3'])
TCON(encoding=<Encoding.LATIN1: 0>, text=[u'Indie / Alternative'])
PRIV(owner=u'PeakValue', data='\xa1~\x00\x00')
文字コードが LATIN1 になっていますが、これはあり得ないですね。これについては MP3のタグの種類と、文字化けについて に説明がありました。
ところで、ISO8859-1という聞き慣れない言葉が出てきましたが、ISO8859-1とは西欧文字専用コードで、日本語文字は一切扱えません。日本では「ISO8859-1とはシフトJISのこと」と勘違いしてる人も多いようです。
https://ja.wikipedia.org/wiki/ISO/IEC_8859-1
つまり規格上は、ID3v2系で日本語や中国語、韓国語といった言語の文字を扱う場合はユニコードを選ぶのが必須です。
・・・ところが、ISO8859-1と宣言しつつ、ID3v1系と同様に各システムのデフォルトコード(日本語WinならシフトJISコード)をそのまま使うことで各国言語を扱えるようにするというインチキが広くまかり通っています。
MP3のタグの種類と、文字化けについて
ISO8859-1 は別名 Latin-1 なので、まさにそのインチキを目の当たりにしていることになります。
念のためそれぞれのフィールドで何と書いてあるか確認してみます。手っ取り早く Python でインタラクティブに TIT2 (タイトル) と TCOM (作曲者) のそれぞれの文字列をデコード。
$ python3
Python 3.6.9 (default, Dec 8 2021, 21:08:43)
[GCC 8.4.0] on linux
>>> b'\x82\xa0\x82\xc8\x82\xbd\x82\xcd\xe5\x87\x8bC\x98O'.decode('sjis')
'あなたは蜃気楼'
>>> b'\x8f\xed\x93c\x91\xe5\x8a\xf3'.decode('sjis')
'常田大希'
おお、確かに。
というわけで
今日のところは時間切れ。基本的な現象はわかりました。基本的には Latin-1 と言いつつ Shift_JIS の文字列が入っているデータをデコードしてユニコードで格納しなおす、という処理をすれば良さそうです。
ただ私の場合、日本語以外にスペイン語やポルトガル語の楽曲も多く持っていて、それらの言語は ASCII の範囲は超えているけど Latin-1 で表記できるはずなので、もう少し慎重に調べなければならないかもしれません。というわけで、その辺対応できたらまた書きます。
卓球好き、音楽好きです。飲み食い好きが高じて料理もします。2024年ソニーグループ(株)を退職し、同年より(株)fcuro勤務のAIエンジニアです。アルゼンチンタンゴ等の音楽について雑誌に文章を書いたりすることもあります。
なお、当然ながら本サイトでの私の発言は私個人の見解であります。所属組織の方針や見解とは関係ありません (一応お約束)。
商品へのリンクには以下のアフィリエイトが設定されている場合があります。
Amazon.co.jpアソシエイト
楽天アフィリエイト
“DLNA 経由でアクセスする音楽のメタデータ文字化け問題を調べる” に対して1件のコメントがあります。