在 Web 应用中实现文字转语音(TTS),早已不需要依赖第三方服务或笨重的音频文件。Chrome 浏览器原生支持的 SpeechSynthesisUtterance API,让前端开发者只需几行代码,就能让网页 “开口说话”。本文将全面拆解这个 API 的用法、特性、坑点与最佳实践。
一、什么是 SpeechSynthesisUtterance
SpeechSynthesisUtterance 是 Web Speech API 中语音合成(Speech Synthesis)模块的核心接口,代表一个 “语音朗读请求”。你可以把它理解为一份 “朗读任务单”—— 上面写着要读什么文本、用什么语言、语速多快、音调多高,然后交给浏览器的语音引擎去执行。
Web Speech API 分为两大部分:
- 语音识别(Speech Recognition):语音转文字
- 语音合成(Speech Synthesis):文字转语音
而 SpeechSynthesisUtterance 就是语音合成部分的主角。
二、5 行代码快速上手
最简单的朗读功能,只需要几行代码:
// 创建一个朗读实例
const utterance = new SpeechSynthesisUtterance('你好,欢迎来到前端语音世界');
// 设置语言为中文
utterance.lang = 'zh-CN';
// 开始朗读
window.speechSynthesis.speak(utterance);
打开 Chrome 开发者工具,在控制台粘贴以上代码,就能直接听到朗读效果。
三、核心属性详解
SpeechSynthesisUtterance 提供了丰富的属性来控制朗读效果,以下是最常用的 6 个核心属性:
1. text:朗读内容
- 类型:
string - 必填:是
- 说明:要被朗读的文本内容,最长支持约 32768 个字符
- 注意:过长的文本可能会被某些引擎截断,建议分段朗读
utterance.text = '这是要朗读的文本内容';
2. lang:语言代码
- 类型:
string - 默认值:跟随浏览器语言
- 格式:BCP 47 语言标签
常用语言代码:
表格
| 代码 | 语言 |
|---|---|
zh-CN |
中文(普通话) |
zh-TW |
中文(台湾国语) |
en-US |
英语(美式) |
en-GB |
英语(英式) |
ja-JP |
日语 |
ko-KR |
韩语 |
utterance.lang = 'zh-CN';
3. rate:语速
- 类型:
number - 默认值:
1 - 范围:
0.1~10 - 说明:1 表示正常语速,2 表示 2 倍速,0.5 表示半速
utterance.rate = 1.2; // 稍快的语速,体验较好
4. pitch:音调
- 类型:
number - 默认值:
1 - 范围:
0~2 - 说明:值越高声音越尖锐,越低越低沉
utterance.pitch = 1; // 正常音调
5. volume:音量
- 类型:
number - 默认值:
1 - 范围:
0~1 - 说明:0 为静音,1 为最大音量
utterance.volume = 0.8;
6. voice:指定发音人
- 类型:
SpeechSynthesisVoice对象 - 默认值:系统默认语音
- 说明:可以指定特定的语音包(男声、女声、方言等)
// 获取所有可用语音
const voices = speechSynthesis.getVoices();
// 选择第一个中文语音
const chineseVoice = voices.find(v => v.lang.startsWith('zh'));
if (chineseVoice) {
utterance.voice = chineseVoice;
}
四、完整的事件监听机制
朗读过程中有丰富的事件可以监听,方便我们做状态管理和 UI 同步:
const utterance = new SpeechSynthesisUtterance('测试文本');
// 开始朗读时触发
utterance.onstart = (e) => {
console.log('开始朗读', e.charIndex);
};
// 朗读结束时触发
utterance.onend = (e) => {
console.log('朗读结束,总时长', e.elapsedTime + 'ms');
};
// 朗读出错时触发
utterance.onerror = (e) => {
console.error('朗读出错:', e.error);
};
// 暂停时触发
utterance.onpause = () => {
console.log('朗读已暂停');
};
// 恢复时触发
utterance.onresume = () => {
console.log('朗读已恢复');
};
// 读到词语边界时触发(可用于高亮同步)
utterance.onboundary = (e) => {
console.log('当前读到第', e.charIndex, '个字符');
};
其中 onboundary 事件非常实用,可以实现 “读到哪、高亮到哪” 的逐字同步效果。
五、全局控制方法
所有朗读任务都由 window.speechSynthesis 统一管理,提供 4 个控制方法:
1. speak () – 开始朗读
将朗读任务加入队列,按顺序执行。
speechSynthesis.speak(utterance);
2. cancel () – 停止全部
立即停止当前朗读,并清空所有待执行的队列。
speechSynthesis.cancel();
3. pause () – 暂停
暂停当前朗读。
speechSynthesis.pause();
4. resume () – 恢复
从暂停处继续朗读。
speechSynthesis.resume();
此外还有两个只读属性用于查询状态:
speechSynthesis.speaking:是否正在朗读speechSynthesis.paused:是否处于暂停状态
六、语音列表与 voiceschanged 事件
获取系统可用的语音列表是常见需求,但这里有个经典的坑:getVoices() 可能返回空数组。
这是因为浏览器加载语音列表是异步的,需要监听 voiceschanged 事件:
// 正确获取语音列表的方式
function loadVoices() {
const voices = speechSynthesis.getVoices();
console.log('可用语音数量:', voices.length);
voices.forEach((voice, index) => {
console.log(`${index}: ${voice.name} (${voice.lang}) - ${voice.localService ? '本地' : '云端'}`);
});
}
// 首次加载可能为空,监听变化事件
loadVoices();
speechSynthesis.onvoiceschanged = loadVoices;
每个 SpeechSynthesisVoice 对象包含:
name:语音名称(如 “Microsoft Huihui”)lang:语言代码localService:是否为本地语音(false表示云端语音,需要联网)default:是否为默认语音
七、Chrome 中的常见坑与最佳实践
坑 1:移动端必须用户交互触发
Chrome 移动端(包括 Android)遵循自动播放策略,语音合成必须在用户点击、触摸等交互事件中触发,否则会被浏览器拦截。
✅ 正确写法:
document.getElementById('speakBtn').addEventListener('click', () => {
speechSynthesis.speak(utterance);
});
坑 2:多次调用 speak 会排队
如果循环调用 speak(),所有任务会进入队列依次朗读,而不是覆盖。想要 “说新的话、打断旧的”,必须先 cancel:
function speakText(text) {
// 先停止之前的
speechSynthesis.cancel();
// 再朗读新的
const u = new SpeechSynthesisUtterance(text);
speechSynthesis.speak(u);
}
坑 3:长文本被截断
不同浏览器和引擎对文本长度限制不同,Chrome 桌面端限制约 32768 字符。超出限制可能导致朗读中途停止。
最佳实践:长文本按段落或句子分段,依次朗读。
坑 4:页面不可见时朗读停止
Chrome 会在标签页切到后台时,自动暂停或降低语音合成的优先级。如果需要后台持续朗读,需要配合其他方案。
坑 5:中文多音字问题
原生 TTS 对多音字的处理并不完美,比如 “银行” 和 “行走” 的 “行”,可能会读错。重要场景建议使用 SSML 标记或专业 TTS 服务。
八、浏览器兼容性
截至 2026 年,主流浏览器对 SpeechSynthesisUtterance 的支持情况如下:
表格
| 浏览器 | 支持程度 | 中文支持 | 备注 |
|---|---|---|---|
| Chrome 桌面 | ✅ 完全支持 | ✅ 完美支持 | 推荐开发环境 |
| Edge | ✅ 完全支持 | ✅ 支持 | 同 Chromium 内核 |
| Firefox | ✅ 基本支持 | ⚠️ 依赖系统 | 需安装语音包 |
| Safari 桌面 | ✅ 基本支持 | ✅ 支持 | 功能有限制 |
| Chrome Android | ✅ 支持 | ✅ 支持 | 需用户交互触发 |
| iOS Safari | ⚠️ 有缺陷 | ❌ 问题较多 | 长期存在兼容性 Bug |
结论:Chrome 是目前对 Web Speech API 支持最好、最稳定的浏览器,也是开发语音相关应用的首选环境。
九、实际应用场景
- 无障碍阅读:帮助视力障碍用户浏览网页内容
- 有声读物:小说、文章的在线朗读
- 智能客服:语音播报回复内容
- 教育应用:单词发音、课文朗读
- 游戏交互:NPC 对话语音
- 导航提示:表单填写、操作步骤的语音引导
- 后台通知:新消息、订单状态的语音提醒
十、完整示例:一个简易的朗读器
最后给大家一个可直接运行的完整示例,包含播放、暂停、停止、语速调节功能:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Chrome 语音朗读器</title>
</head>
<body>
<textarea id="textInput" rows="5" cols="50">欢迎使用 Chrome 原生语音合成技术。
这是一个 SpeechSynthesisUtterance 的演示示例。</textarea>
<br>
<label>语速:
<input type="range" id="rate" min="0.5" max="2" step="0.1" value="1">
<span id="rateValue">1.0</span>
</label>
<br>
<button id="speakBtn">开始朗读</button>
<button id="pauseBtn">暂停</button>
<button id="resumeBtn">继续</button>
<button id="stopBtn">停止</button>
<script>
const textInput = document.getElementById('textInput');
const rateInput = document.getElementById('rate');
const rateValue = document.getElementById('rateValue');
let currentUtterance = null;
// 更新语速显示
rateInput.addEventListener('input', () => {
rateValue.textContent = rateInput.value;
});
// 开始朗读
document.getElementById('speakBtn').addEventListener('click', () => {
// 先停止之前的
speechSynthesis.cancel();
currentUtterance = new SpeechSynthesisUtterance(textInput.value);
currentUtterance.lang = 'zh-CN';
currentUtterance.rate = parseFloat(rateInput.value);
currentUtterance.pitch = 1;
currentUtterance.onend = () => {
console.log('朗读完成');
};
speechSynthesis.speak(currentUtterance);
});
// 暂停
document.getElementById('pauseBtn').addEventListener('click', () => {
speechSynthesis.pause();
});
// 继续
document.getElementById('resumeBtn').addEventListener('click', () => {
speechSynthesis.resume();
});
// 停止
document.getElementById('stopBtn').addEventListener('click', () => {
speechSynthesis.cancel();
});
</script>
</body>
</html>
结语
SpeechSynthesisUtterance 是一个被低估的浏览器原生能力。它零依赖、零成本、调用简单,足够应对大多数基础语音场景。虽然在音色自然度上不如专业的云端 TTS 服务,但胜在方便快捷、离线可用,非常适合快速原型开发和内部工具使用。
如果你正在做需要语音播报的 Web 项目,不妨先从原生 API 开始尝试,也许就能满足你的全部需求。