SpeechSynthesis API 可用但需兼容处理:Chrome/Edge/Safari(新版)支持完整功能,Firefox仅部分支持;须监听voiceschanged事件再获取语音列表,按lang筛选后fallback关键词匹配;控制朗读需保存utterance实例并结合pending/speaking/paused状态安全操作;中文推荐rate 0.85–0.95、pitch 0.7–0.85,并显式设lang='zh-CN'。

SpeechSynthesis API 能不能直接用?
能,但得看浏览器。Chrome、Edge、Safari(macOS 12+ / iOS 15.4+)支持完整功能;Firefox 只支持部分语言且不触发 onend;旧版 Safari 不支持 voiceURI 切换。别在页面一加载就调 speechSynthesis.getVoices()——它异步加载,初始返回空数组,得监听 voiceschanged 事件。
怎么选对语音(voice)而不是硬写名字?
语音列表动态加载,不能靠 find(v => v.name === 'Google US English') 这种写死逻辑。实际做法是:
- 先等
speechSynthesis.onvoiceschanged触发,再调getVoices() - 按
lang筛选(如'zh-CN'),再 fallback 到name包含关键词(如'Chinese'或'TTS') - 避免用
voiceURI,它已被 Chrome 废弃,Safari 不识别
示例判断逻辑:
const voices = speechSynthesis.getVoices();
const zhVoice = voices.find(v => v.lang.startsWith('zh')) ||
voices.find(v => /chinese|tts/i.test(v.name));
朗读中途暂停/恢复/取消怎么不出错?
直接调 pause() / resume() 前必须确认当前有正在播放的 SpeechSynthesis 实例,否则静默失败。更安全的做法是:
- 始终保存上一次
speechSynthesis.speak(utterance)返回的utterance实例 - 用
speechSynthesis.pending+speechSynthesis.speaking+speechSynthesis.paused组合判断状态 - 取消时优先用
speechSynthesis.cancel(),它会清空队列并终止当前发音
常见坑:连续点两次“朗读”,没 cancel 就再 speak,结果语音重叠或卡住。
立即学习“前端免费学习笔记(深入)”;
中文朗读生硬?这些参数调了才像人话
默认语速(rate: 1)、音高(pitch: 1)、音量(volume: 1)对中文很不友好。实测更自然的组合:
-
rate: 0.85–0.95(太快易吞字,尤其带标点停顿) -
pitch: 0.7–0.85(太高显机械,中文宜偏低沉) - 加标点停顿:把文本按句号、问号、感叹号切分,每段设
utterance.delay = 300(需手动控制队列)
注意:lang 必须显式设为 'zh-CN',否则 Chrome 可能按英文规则断词。
真正麻烦的是跨浏览器语音质量差异——同一段中文,在 Chrome 里用系统语音自然,在 Safari 里可能全靠 WebKit 内置 TTS,颗粒感强。如果对听感要求高,得准备降级方案,比如 fallback 到音频文件流式播放。










