Web音声アプリ開発で詰まったポイントと解決法まとめ(2025年5月版)
はじめに
音声認識+音声合成のWebアプリを作る中で、以下のような構成を実装しました:
- Next.js + Clerk + FastAPI + Azure Speech Service
- 音声録音:
MediaRecorder
- 音声認識:Azure Speech to Text
- 音声合成:Azure Text to Speech(TTS)
その中で特にハマったポイントと、対処法をまとめておきます。
🧩 詰まったポイントと解決方法
1. iOSでTTS音声が自動再生されない
❌ 問題点:
iOS Safariでは自動再生(audio.play()
)がブロックされることが多く、TTS音声が再生されない。
✅ 解決策:
-
autoPlay
フラグをfalse
にして、ユーザー操作時のみ再生
にする。 - iOSデバイスを
navigator.userAgent
で検知し、再生方法を分岐。
useEffect(() => {
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
if (autoPlay && !isIOS) {
audioRef.current?.play().catch(err => console.warn("iOS autoplay blocked:", err));
}
}, [audioUrl]);
2. MediaRecorder の MIME type 問題
❌ 問題点:
ブラウザにより MediaRecorder
でサポートされる MIME type が異なる。
✅ 解決策:
録音前に isTypeSupported()
を使って、利用可能な MIME type を判定。
let mimeType = '';
if (MediaRecorder.isTypeSupported('audio/webm')) {
mimeType = 'audio/webm';
} else if (MediaRecorder.isTypeSupported('audio/ogg')) {
mimeType = 'audio/ogg';
}
3. ffmpeg で webm から wav 変換エラー
❌ 問題点:
Azure Speech で WAV形式が必要 → ffmpeg
を使って変換。
だが、環境によっては webm がうまくデコードできず Invalid data found
エラー。
✅ 解決策:
-
ffmpeg -i
に-f wav -ar 16000 -ac 1
の明示指定を追加。 - それでも失敗する場合は
application/octet-stream
としても別ルートで処理。 - 変換失敗時の fallback ロジックを用意する。
🔊 最終構成のアーキテクチャ(簡略図)
ユーザー音声
↓録音(MediaRecorder)
FastAPI
↓送信(blob形式)
ffmpeg(WAV変換)
↓
Azure Speech to Text
↓
OpenAI API(対話生成)
↓
Azure TTS
↓
クライアント再生(audio.play)
おわりに
iOSやブラウザ間の違い、MediaRecorderや音声再生のクセ、そしてffmpegやTTSの仕様にかなり悩まされました。
同じように音声アプリを作る方の参考になれば幸いです。