在 JavaScript 中把文字转成语音,最常用、最简单的是 Web Speech API 的 SpeechSynthesis。浏览器原生支持,无需额外库。
简单的文字转语音播放功能,不用调用云端 TTS
✅ 支持 Chrome / Edge / Safari
❌ 不支持 IE
/**
* 播放指定文字
* @param text
*/
function speak(text) {
//const text = "你好,这是一段文字转语音的演示";
const utterance = new SpeechSynthesisUtterance(text);
utterance.onstart = () => console.log('入队播放开始:', text);
utterance.onend = () => console.log('播放结束,出队:', text, '当前pending:', speechSynthesis.pending);
utterance.onerror = (e) => console.error('播放出错/中断:', text, e);
// 可选设置
utterance.lang = 'zh-CN'; // 语言
utterance.rate = 1; // 语速 0.1 ~ 10
utterance.pitch = 1; // 音调 0 ~ 2
utterance.volume = 1; // 音量 0 ~ 1
/*
const voices = speechSynthesis.getVoices();
console.log("voices:", voices);
const maleVoice = voices.find(v => {
console.log("v:", v)
return v.name.includes("Google 普通话(中国大陆)") || v.name.includes("Male");
});
console.log("maleVoice:", maleVoice)
if (maleVoice) {
utterance.voice = maleVoice;
}
*/
//console.log("utterance:", utterance)
/**
* 🔹 播放语音
* 🔹 必须用户交互触发(点击)?
* 🔹 可多次调用 → 自动排队
*/
speechSynthesis.speak(utterance);
console.log('已加入队列, speaking:', speechSynthesis.speaking, 'pending:', speechSynthesis.pending);
}
speak('1号硫化工作台有24个待生产任务');
/**
* 查看语音包
*/
function loadVoices() {
const voices = speechSynthesis.getVoices();
voices.forEach((voice, i) => {
//console.log("voice:", voice)
console.log(i, voice.name, voice.lang, voice.gender || '未知');
});
}
/**
* ✅ 语音列表加载完成时触发
* ✅ 获取 voice 必须用
* speechSynthesis.onvoiceschanged = () => {}
*/
speechSynthesis.onvoiceschanged = loadVoices;
/**
* 停止并清空
* 立即清空所有排队和正在播的语音
*/
speechSynthesis.cancel();
/**
* 暂停播放
*/
speechSynthesis.pause();
/**
* 恢复播放
*/
speechSynthesis.resume();
/**
* 🔹 获取可用语音列表
* 🔹 异步
*/
speechSynthesis.getVoices();
/**
* 判断当前是否正在播放语音(包括暂停状态)
* 只有 cancel()或播放自然结束才会变 false
* return boolean
*/
let speakingStatus = speechSynthesis.speaking;
/**
* 判断是否有语音正在排队等待播放
* return boolean
*/
let pendingStatus = speechSynthesis.pending;
/**
* 判断当语音是否被暂停
* 只有 手动调用 pause()才会变成 true
* 播放完自动结束 → false
* cancel()→ false
* return boolean
*/
let pausedStatus = speechSynthesis.paused;
/**
* 创建语音对象
* @type {SpeechSynthesisUtterance}
* 属性
* text:'内容' // 朗读文本
* lang:'zh-CN' // 语言(zh-CN / en-US)
* voice:object // 指定语音对象 speechSynthesis.getVoices() 中获取
* rate:1 // 语速(0.1–10)
* pitch:1 // 音调(0–2)
* volume:1 // 音量(0–1)
*/
const utterance = new SpeechSynthesisUtterance('你好,测试文字转语音');
//utterance.text = "朗读文本内容"; // 可选
utterance.lang = 'zh-CN';
utterance.rate = 1;
utterance.pitch = 1;
utterance.volume = 1;
// 播放
speechSynthesis.speak(utterance);
/**
* 监听事件
*/
utterance.onstart = () => console.log('开始');
utterance.onend = () => console.log('结束');
utterance.onerror = e => console.error('错误', e);
utterance.onpause = () => console.log('暂停');
utterance.onresume = () => console.log('恢复');
utterance.onboundary = e => console.log('边界', e.name);
/**
* 生命周期
*/
getVoices()
↓
speak()
↓ onstart
↓ onboundary(可选)
↓ pause()
↓ resume()
↓ onend
↓ cancel()
/**
* 能力检测(推荐)
*/
if (!('speechSynthesis' in window)) {
alert('当前浏览器不支持语音合成');
}
3204

被折叠的 条评论
为什么被折叠?



