問題は「ファイルを選択」の段階で起きていた
当初のアップロード入口では、ファイル選択を一般的な音声MIMEタイプに制限していました。デスクトップブラウザでは通常問題ありませんが、一部のAndroidではM4Aを video/mp4、application/mp4、あるいは不完全なタイプを返すことさえあります。実際には音声を含むファイルでも、システムの選択画面がタイプラベルだけで判断するため、アップロードする前の段階で選択できなくなります。
今回の問題が示したのは、ブラウザに表示されるMIMEはデバイスやファイルマネージャーが提供する説明であって、ファイル内容の最終判定ではないということです。絶対的な事実として扱うと、モバイル環境に互換性の断点を作ってしまいます。
拡張子、MIME、コンテナ、コーデックは別のもの
.m4a は一般的な拡張子です。MIMEはシステムがWebページへ渡すタイプラベル、MP4はコンテナで、その中には通常AACなどの実際の音声コーデックが入っています。4つは関連していますが、互いに置き換えられるものではありません。拡張子を変えてもコーデックは変換されず、MIMEが誤っていてもファイルが破損しているとは限りません。
| 手がかり | 分かること | 分からないこと |
|---|---|---|
| 拡張子 | ユーザーやアプリがファイルをどう開く想定か | 内部のコーデックが実際に有効とは証明できない |
| MIME | デバイスが今回の選択をどう表すか | Androidのシステムによって異なる値になる場合がある |
| コンテナ | 音声ストリームとメタデータをどう格納するか | 同じコンテナでも異なるコーデックを含められる |
| デコード結果 | サーバー側で本当に音声を読み取れるか | 内容が音声分析に適しているとは依然として証明できない |
CVoiceで採用した修正方法
アップロード入口を汎用ファイル選択に変更し、Android側でM4Aが事前にブロックされないようにしました。ファイル選択後にWebページ側で許可リストを検証し、WAV、MP3、M4A、WebM、OGG、AMRだけを受け付けます。信頼して識別できるものの標準拡張子がないファイルには、ページ側でファイル名を補完し、audio/mp4、audio/x-m4a、video/mp4 と application/mp4 はいずれもM4A互換処理の分岐に入ります。
これは「すべてのファイルを受け入れる」という意味ではありません。選択画面はユーザーがファイルを選べるようにし、フロントエンドの許可リストが第一段階の安全確認を行い、サーバー側のデコードで実際の内容を検証し、さらに音声品質の基準でレポート生成に十分か判断します。修正時にはサービス全体の79項目のテストがすべて通過し、AndroidのM4A MIMEエイリアス専用チェックも追加しました。
今回の修正から得た汎用的な確認順序
- まずファイルがシステムの選択画面に表示されるか確認し、最初から分析アルゴリズムを疑わないようにします。
- 「アップロード失敗」だけで終わらせず、デバイスが報告した拡張子とMIMEも記録します。
- 「選択を許可する」と「処理を許可する」を二段階に分け、互換性のために検証を捨てないようにします。
- デコードエラー、長さ不足、無音が多すぎる場合、非対応形式で、それぞれ別のメッセージを表示します。
- デスクトップブラウザのエミュレーションだけに頼らず、実際のモバイル端末で再確認します。