62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
import Speech from 'speak-tts'
|
||
import { useSpeakStore } from '@/store/speak'
|
||
|
||
let speechInstance = null
|
||
let lastVoice = ''
|
||
|
||
export async function speakText(text) {
|
||
if (!text) return
|
||
const speakStore = useSpeakStore()
|
||
if (!speechInstance) {
|
||
speechInstance = new Speech()
|
||
if (!speechInstance.hasBrowserSupport()) {
|
||
console.warn('当前浏览器不支持语音合成')
|
||
return
|
||
}
|
||
await speechInstance.init({
|
||
lang: 'zh-CN',
|
||
volume: speakStore.ttsVolume,
|
||
rate: speakStore.ttsRate,
|
||
pitch: speakStore.ttsPitch,
|
||
splitSentences: true,
|
||
voice: speakStore.ttsVoice || undefined
|
||
})
|
||
lastVoice = speakStore.ttsVoice || ''
|
||
}
|
||
// 切换voice或参数时重新init
|
||
if ((speakStore.ttsVoice || '') !== lastVoice
|
||
|| speechInstance._volume !== speakStore.ttsVolume
|
||
|| speechInstance._rate !== speakStore.ttsRate
|
||
|| speechInstance._pitch !== speakStore.ttsPitch) {
|
||
await speechInstance.init({
|
||
lang: 'zh-CN',
|
||
volume: speakStore.ttsVolume,
|
||
rate: speakStore.ttsRate,
|
||
pitch: speakStore.ttsPitch,
|
||
splitSentences: true,
|
||
voice: speakStore.ttsVoice || undefined
|
||
})
|
||
lastVoice = speakStore.ttsVoice || ''
|
||
}
|
||
speakStore.setTTSStatus('playing')
|
||
speechInstance.speak({
|
||
text,
|
||
onend: () => speakStore.setTTSStatus('idle'),
|
||
onerror: () => speakStore.setTTSStatus('idle')
|
||
})
|
||
}
|
||
|
||
export async function getTTSVoices() {
|
||
// 兼容speak-tts 2.x,使用浏览器原生API
|
||
return new Promise((resolve) => {
|
||
let voices = window.speechSynthesis.getVoices();
|
||
if (voices.length) {
|
||
resolve(voices);
|
||
} else {
|
||
window.speechSynthesis.onvoiceschanged = () => {
|
||
voices = window.speechSynthesis.getVoices();
|
||
resolve(voices);
|
||
};
|
||
}
|
||
});
|
||
} |