問題發生在「選擇檔案」這一步
最初的上傳入口把檔案選擇器限制為常見的音訊 MIME 類型。這在桌面瀏覽器通常有效,但部分 Android 系統會把 M4A 回報為 video/mp4、application/mp4,甚至會給出不完整的類型。檔案實際上包含音訊,系統選擇器卻只依照類型標籤判斷,因此使用者甚至還沒上傳,就已經無法選取。
這次問題提醒我們:瀏覽器顯示的 MIME 是裝置與檔案管理器提供的描述,不是對檔案內容的最終鑑定。若把它當成絕對事實,就會在行動裝置上製造相容性斷點。
副檔名、MIME、容器與編碼不是同一回事
.m4a 是常見的副檔名;MIME 是系統傳給網頁的類型標籤;MP4 是容器;容器內通常還包含 AAC 等實際的音訊編碼。四者彼此相關,卻不能互相取代。更改副檔名不會轉換編碼,MIME 標示錯誤也不代表檔案一定損壞。
| 線索 | 能說明什麼 | 不能說明什麼 |
|---|---|---|
| 副檔名 | 使用者與應用程式預期如何開啟檔案 | 無法證明內部編碼確實有效 |
| MIME | 裝置如何描述這次選擇 | 不同 Android 系統可能給出不同值 |
| 容器 | 音訊串流與中繼資料如何封裝 | 同一種容器可以包含不同編碼 |
| 解碼結果 | 伺服器端是否真的能讀出音訊 | 仍無法證明內容適合聲音分析 |
CVoice 採用的修正方式
上傳入口改成通用檔案選擇器,讓 Android 系統不再預先封鎖 M4A;檔案被選取後,再由網頁執行白名單驗證,只接受 WAV、MP3、M4A、WebM、OGG 與 AMR。對於能可靠辨識、但缺少標準副檔名的檔案,頁面會補齊檔名;audio/mp4、audio/x-m4a、video/mp4 與 application/mp4 都會進入 M4A 相容性分支。
這並不是「接受所有檔案」。選擇器負責讓使用者能選到檔案,前端白名單負責第一層安全檢查,伺服器端解碼負責驗證真實內容,再由聲音品質門檻判斷是否足以產生報告。修正時完整服務測試共 79 項通過,並新增 Android M4A MIME 別名的專項檢查。
從這次修正得到的通用檢查順序
- 先確認檔案是否會出現在系統選擇器中,而不是一開始就懷疑分析演算法。
- 記錄裝置提供的副檔名與 MIME,不要只收集一句「上傳失敗」。
- 把「允許選擇」與「允許處理」拆成兩層,避免為了相容性而放棄驗證。
- 讓解碼錯誤、時長不足、靜音過多與格式不支援顯示不同提示。
- 用真實的行動裝置複查,不要只依賴桌面瀏覽器模擬。
適用邊界這套映射解決的是「有效音訊被錯誤攔截」的問題。它無法修復內部資料損壞、編碼器異常,或偽裝成音訊的其他檔案;最終仍應以實際解碼結果為準。