HTML如何做语音合成_html SpeechSynthesis语音合成【总结】的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
SpeechSynthesis语音合成需用户手势触发、显式指定中文voice、手动管理播放状态。必须在click等交互回调中调用speak(),等待onvoiceschanged后筛选zh-CN语音,通过cancel()/pause()/resume()控制流程,并做好降级处理。
HTML 里用 SpeechSynthesis 做语音合成,不是加个标签就能响——它依赖浏览器原生 API,不支持自动播放、不能跨域加载语音资源、且多数浏览器默认静音策略下必须由用户手势(如点击)触发,否则直接静默失败。
几乎所有现代浏览器(Chrome/Firefox/Edge)都要求 speechSynthesis.speak() 调用发生在用户真实交互回调内,比如 onclick、oninput 或 addEventListener('click', ...)。在页面加载时直接调用、或在定时器(setTimeout)、fetch 回调里调用,都会被忽略,且不报错——只是一声不吭。
speechSynthesis.speak(utterance)
window.onload 或 fetch().then(...) 中调用SpeechSynthesis 默认 voice 不稳定:Chrome 在中文系统可能选英文 voice,Safari 可能根本没中文字体;不设 utterance.voice 就等于听天由命。
speechSynthesis.onvoiceschanged 触发,再调用 speechSynthesis.getVoices()
lang 包含 'zh-CN' 或 'zh' 的 voice,优先选 name 含 “Chinese”、“TTS” 或系统自带名称(如 macOS 的 “Ting-Ting”)utterance.voice = selectedVoice,别依赖默认值speechSynthesis.onvoiceschanged = () => { const zhVoice = speechSynthesis.getVoices().find(v => v.lang.includes('zh-CN')); if (zhVoice) utterance.voice = zhVoice;};
SpeechSynthesis 没有“正在播放中”的布尔属性,得靠监听 onstart、onend、onpause 等事件 + 自己维护状态变量。直接反复调用 cancel() 或 resume() 可能无效甚至报错。
speechSynthesis.pause() 只对当前正在播放的 utterance 生效;若没在播,无效果speechSynthesis.resume() 仅恢复被 pause() 暂停的 utterance,不能唤醒已 cancel() 掉的speechSynthesis.cancel() 清空队列,再新建 utterance 并 speakspeechSynthesis.pending + speechSynthesis.speaking 判断是否忙真正难的不是让字说出来,而是让“说的过程”可控、可预期、可降级——比如 voice 加载失败时 fallback 文本提示,或 iOS Safari 根本不支持时提前检测并隐藏语音按钮。这些逻辑不在 API 文档里,但在实际落地时躲不掉。