iOS 17 SpeechSynthesis API特定文本失效问题及iOS 18修复说明
更新:该问题已在iOS 18中修复
问题描述
开发的PWA应用使用Speech Synthesis API,在iOS 16.5的Safari中可正常运行,但升级至iOS 17后出现失效问题:在搭载iOS 17的iPhone SE3设备上,尝试朗读带中文引号的“你好”时无任何反应;移除引号仅保留“你好”时,朗读功能可正常工作。
复现代码
JavaScript代码
let voice = null; function updateVoice() { voice = speechSynthesis.getVoices().find(voice => voice.voiceURI == 'com.apple.voice.compact.zh-CN.Tingting') document.getElementById('voice_name').textContent = voice?.name ?? '(No Voice)'; } speechSynthesis.addEventListener('voiceschanged', updateVoice); updateVoice() const speak = document.getElementById('speak'); const text = document.getElementById('text'); speak.addEventListener('click', () => { const ssu = new SpeechSynthesisUtterance(text.value); ssu.voice = voice; ssu.lang = 'zh-CN'; ssu.addEventListener('start', e => console.log('start', e)); ssu.addEventListener('end', e => console.log('end', e)); ssu.addEventListener('error', e => console.log('error', e)); speechSynthesis.speak(ssu); });
HTML代码
<textarea id="text">“你好”</textarea> <div id="voice_name"></div> <button type="button" id="speak"> Speak </button>
临时解决方案
对输入文本进行预处理,替换中文全角引号为英文半角引号(或直接移除),避免iOS 17的Speech Synthesis API解析异常。修改后的JS代码如下:
let voice = null; function updateVoice() { voice = speechSynthesis.getVoices().find(voice => voice.voiceURI == 'com.apple.voice.compact.zh-CN.Tingting') document.getElementById('voice_name').textContent = voice?.name ?? '(No Voice)'; } speechSynthesis.addEventListener('voiceschanged', updateVoice); updateVoice() const speak = document.getElementById('speak'); const text = document.getElementById('text'); speak.addEventListener('click', () => { // 预处理文本:替换中文引号为英文引号 const cleanedText = text.value.replace(/“|”/g, '"'); const ssu = new SpeechSynthesisUtterance(cleanedText); ssu.voice = voice; ssu.lang = 'zh-CN'; ssu.addEventListener('start', e => console.log('start', e)); ssu.addEventListener('end', e => console.log('end', e)); ssu.addEventListener('error', e => console.log('error', e)); speechSynthesis.speak(ssu); });
如果不需要保留引号,也可以直接移除:
const cleanedText = text.value.replace(/“|”/g, '');
内容的提问来源于stack exchange,提问作者tsh
相关产品推荐
相关产品推荐

