wav から TOYOTA のカーナビでメタデータを読める m4a を作る方法

2026-08-28 15:49 (84 minutes ago)

トヨタ純正ナビの SD カード再生で、ffmpeg で作った m4a は音は鳴るのに曲名・アーティスト名・アルバム名が全部 (NO DATA) になる。macOS 標準の afconvert で作り直すと読めるようになる。

動くやり方

afconvert -f m4af -d aac -b 256000 input.wav output.m4a

タグは mutagen で書く。

from mutagen.mp4 import MP4

f = MP4("output.m4a")
f["\xa9nam"] = ["曲名"]
f["\xa9ART"] = ["アーティスト名"]
f["aART"] = ["アーティスト名"]
f["\xa9alb"] = ["アルバム名"]
f["trkn"] = [(4, 25)]
f.save()

afconvert は moov アトムを最初からファイル先頭に置き、タグ用の free 領域も確保する。-movflags +faststart に相当する後処理はいらない。

タグを書いた後に ffmpeg を通してはいけない。 -c copy であってもコンテナが ffmpeg 形式に組み直され、また読めなくなる。

なぜ ffmpeg ではダメなのか

ナビのパーサーが hdlr アトムを 34 バイト固定と決め打ちしているため。

hdlr は末尾に可変長の name フィールドを持つので、書き手によってサイズが変わる。

meta > hdlr mdia > hdlr
iTunes / afconvert 34 (name はゼロ 2 バイト) 34 (name 空)
ffmpeg 33 (name はゼロ 1 バイト) 45 (name は "SoundHandler")

34 バイト決め打ちで次のアトムの位置を計算すると、ffmpeg 製のファイルでは 1 バイトずれた場所を ilst の先頭として読むことになる。そこにゴミを掴んで、タグが無いと判断する。音声トラックの読み出しは別経路なので再生だけは成功する。

ffmpeg は他にも、trakedts (エディットリスト)、stblsgpd / sbgp を足す。iTunes と afconvert はどれも書かない。

効かない対策

以下はどれもナビの表示を変えなかった。

  • -movflags +faststart で moov をファイル先頭に移す
  • ftyp を iTunes と同じにする (minor_version を 0、compatible_brandsmp42 を含める)
  • アルバムアート (covr) を入れる
  • 余計なタグを削る (©cmt のコメント、©too のエンコーダ名)
  • サンプリング周波数を 48kHz から 44.1kHz に落とす。そもそも 48kHz でも再生はできる
  • mutagen で ffmpeg 製ファイルのタグを書き直す。mutagen は hdlr を書き換えないので、ffmpeg の 33 バイトがそのまま残る

hdlr を 33 から 34 バイトへバイト単位で書き換えるパッチも試したが、これも足りない。mdia > hdlr が 45 バイトのままだと読めない。ffmpeg 側の差分を個別に潰していく方針は割に合わない。

著作権保護 (CPRM / SD-Audio) も無関係。CPRM 保護された音楽は SD_AUDIO フォルダに暗号化ファイルとして入り、鍵はカードの保護領域に書かれる。Finder でコピーしただけのファイルは原理的にその形式にならないし、カードに SD_AUDIO フォルダが無ければそもそも別の話になる。

手元のファイルを判定する

hdlr のサイズを見れば、実機に挿す前にわかる。

import struct
import sys

d = open(sys.argv[1], "rb").read(400000)

i = d.find(b"mdirappl")          # meta の hdlr は mdir/appl の手前にある
h = d.rfind(b"hdlr", 0, i)
print("meta hdlr:", struct.unpack(">I", d[h - 4:h])[0])

f = d.find(b"hdlr")              # 最初に出てくるのが mdia の hdlr
print("mdia hdlr:", struct.unpack(">I", d[f - 4:f])[0])

両方 34 なら読める。33 や 45 が出たら ffmpeg 製で、そのままでは読めない。

実機での切り分け方

再生自体は成功してしまうので、ファイルを眺めているだけでは原因にたどり着けない。条件を変えたファイルを並べたテストフォルダを作り、1 回の乗車でまとめて試すのが速い。

コツが 2 つある。

曲名タグに条件名を入れる。 T2.m4a の曲名タグを TAG2 OK にしておくと、画面に TAG2 OK と出ればタグを読んでいる、T2 と出ればファイル名にフォールバックしている、と運転席から一目で判別できる。

ID3v2 タグ付きの MP3 を 1 曲、対照群として同じフォルダに混ぜる。 その MP3 が読めて m4a が読めないなら、原因は m4a のコンテナ構造に絞られる。カードの状態やナビ側の挙動のように、同じフォルダの全ファイルへ等しくかかる要因はこれで外れる。

評価をお願いします (会員登録・ログイン不要)
まだ評価がありません
著者は、アプリケーション開発会社 Cyberneura を運営しています。
開発相談をお待ちしています。

アーカイブ