iPhoneでWeb Speech APIの英語がカタカナ読みになる問題の解決法を教えてください
【iPhone】Web Speech APIで英語単語がカタカナ読みになる問題の解決法
解決したいこと
初心者です。
バニラJavaScriptでWeb Speech APIを使ったシンプルな英語学習アプリを開発しています。
一部のiPhone端末で、英語単語(例: "apple", "water")が意図した英語発音ではなく、カタカナ読み(「アップル」「ウォーター」)で音声合成されてしまいます。
iPhone端末間で音声合成結果が異なる原因と、確実に英語音声で再生させる方法を教えてください。
発生している問題・エラー
エラーメッセージは出ませんが、以下の症状が発生しています:
期待する結果: "apple" → 英語発音 /ˈæp.əl/
実際の結果: "apple" → カタカナ読み「アップル」
期待する結果: "water" → 英語発音 /ˈwɔː.tər/
実際の結果: "water" → カタカナ読み「ウォーター」
環境差異:
- 動作正常: 一部のiPhone端末(Safari・Chrome共に正常動作確認済み)
- カタカナ読み: 別のiPhone端末群(ユーザーから複数報告)
- PC環境: 問題なし(全ブラウザで英語音声)
該当するソースコード
// 音声合成メイン関数
function speakWord(word) {
setupSpeech(); // 音声コンテキスト初期化
const textToSpeak = typeof word === 'string' ? word : word.english;
const utterance = new SpeechSynthesisUtterance(textToSpeak);
// 言語・音声設定
utterance.lang = 'en-US';
utterance.rate = 0.8;
utterance.pitch = 1.0;
utterance.volume = 1.0;
// 英語音声の優先選択
const voices = speechSynthesis.getVoices();
const englishVoice = voices.find(voice =>
voice.lang.startsWith('en') &&
(voice.name.includes('English') ||
voice.name.includes('US') ||
voice.name.includes('United States'))
);
if (englishVoice) {
utterance.voice = englishVoice;
}
window.speechSynthesis.speak(utterance);
}
// 音声コンテキスト初期化(Safari対策)
function setupSpeech() {
if ('speechSynthesis' in window) {
if (!window.speechSynthesis._warmedUp) {
const dummy = new SpeechSynthesisUtterance('...');
dummy.lang = 'en-US';
dummy.rate = 1;
dummy.volume = 0; // 無音
dummy.onend = function() {
window.speechSynthesis._warmedUp = true;
};
window.speechSynthesis.speak(dummy);
}
return true;
}
return false;
}
// 音声リスト取得の非同期対応
let availableVoices = [];
window.speechSynthesis.onvoiceschanged = function() {
availableVoices = window.speechSynthesis.getVoices();
};
自分で試したこと
-
音声コンテキストの事前初期化
- Safari対策としてダミー音声で初期化
-
speechSynthesis.onvoiceschanged
での非同期取得対応 - 結果:音声再生は安定、カタカナ読み問題は継続
-
英語音声の選択ロジック実装
-
voice.lang.startsWith('en')
でフィルタリング -
voice.name
で英語音声を優先選択 - 結果:一部端末で改善されず
-
-
ユーザー環境の確認
- Siri設定の有無は無関係であることを確認
- ブラウザ種類(Safari・Chrome)は無関係であることを確認
-
より厳密な音声フィルタリング(検討中)
const englishVoices = voices.filter(v => v.lang.startsWith('en') && !v.name.match(/日本語|Kyoko|Otoya|Google 日本語|Nihongo/) );
質問内容:
- iPhone端末間で音声合成結果が異なる根本的な原因は何でしょうか?
- 確実に英語音声で再生させるための実装方法はありますか?
- ユーザー側で設定変更により改善可能な手順はありますか?
- Web Speech API以外の代替手法(音声ファイル再生等)を検討すべきでしょうか?
よろしくお願いいたします。