You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:23:14