Apache で M4A ファイルの MIME タイプが MP3 と同じになってしまうのを直す

この記事は最終更新日から1年以上が経過しています。情報が古くなっている可能性があります。

Apache 上で M4A ファイルをホストする機会があったのですが、拡張子はちゃんと M4A になっているのにダウンロードすると拡張子が MP3 になってしまう、という怪奇現象が発生しました(どうして…)
わけがわからないよ… という事で原因と解決した方法をメモ。

Sponsored Link

原因

  1. 拡張子が .mp3 のファイルの MIME タイプは audio/mpeg が指定されている
  2. 拡張子が .m4a (AAC) のファイルの MIME タイプは統一されておらずaudio/aac, audio/aacp, audio/3gpp, audio/3gpp2, audio/mp4, audio/MP4A-LATM, audio/mpeg4-generic という具合でバラバラ…
  3. 私の Apache 環境では、拡張子が .m4a (AAC) のファイルの MIME タイプは MP3 と同じ audio/mpeg が指定されている
  4. さらに Chrome 側の仕様で、MIME タイプと実際の拡張子が異なる場合、たとえ a 要素のダウンロード属性に .m4a と指定したとしても強制的に拡張子を MIME タイプから推測される拡張子に変更してしまう
  5. M4A ファイルの MIME タイプが拡張子が MP3 ファイルと同じになっているため、結果的に少なくとも Chrome では強制的に M4A ファイルの拡張子を audio/mpeg から推測される .mp3 に変更してしまう
  6. 拡張子だけ .mp3 に変わっているだけなので、中身は M4A ファイルのまま

まず M4A ファイルの MIME タイプが定まってないのもどうかと思うんですが、MIME タイプと拡張子が一致しなかったらダウンロード属性の値すら上書きして拡張子勝手に変える Chrome って…

MIME タイプが audio/mpeg であってもブラウザ上では普通に再生できるので、ますます厄介…

解決方法

Linux の場合、どうやら MIME タイプはシステムレベルで共通の設定を利用しているらしく、Apache もそれを使って MIME タイプを判定しているようです。この記事では Ubuntu の場合で説明します。

/etc/ 以下に mime.types という設定ファイルがあるので、何かしらのエディターで開きます。
nano なら sudo nano /etc/mime.types という具合に。

MIME タイプとそれに関連付ける拡張子が沢山記述されています。audio/mpeg で検索して絞り込みましょう。

audio/mpeg mpga mpega mp2 mp3 m4a

私の環境の場合、MIME タイプ audio/mpeg の拡張子には mp3 に加えて m4a が登録されていました。これが元凶とみて間違いありません( mpgampegamp2 は今となってはほとんど使われないので説明は省きます)。
とりあえず、m4a と書かれた部分を削除します。

これで M4A ファイルが MP3 と同じ MIME タイプになることは回避できましたが、代わりの MIME タイプが悩ましいです。この記事 には x-m4a を設定すればいけた、とあるので、ひとまず audio/x-wav の下辺りに audio/x-m4a m4a と追記しておきました。

sudo service apache2 restart

最後に、Apache を再起動しておきましょう。

結果

無事 M4A ファイルを拡張子を勝手に変更されることなくダウンロードできるようになりました!
Chrome Dev Tools から確認できる HTTP ヘッダの MIME タイプも audio/x-m4a に変わっていました。
引き続きブラウザでの再生も可能なので、特に問題はないように見えます。

ただし、x-m4a という x- の prefix がついた非標準の MIME タイプをブラウザ側が認識しているのかは定かではありません。単に x-m4a が不明な MIME タイプだから拡張子が変更されなかったのか、はたまた x-m4a を M4A 用の MIME タイプとして認識した上での挙動なのか……。

コメント