feat: 集成Piper自建TTS并增加朗读回退
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
var speechVoices = [];
|
||||
var speechVoicesLoaded = false;
|
||||
var speechTimer = null;
|
||||
var piperFallbackTimer = null;
|
||||
|
||||
function refreshSpeechVoices() {
|
||||
if (!window.speechSynthesis) return;
|
||||
@@ -48,10 +49,39 @@ function doSpeak(text, lang) {
|
||||
}
|
||||
|
||||
function speakText(text, lang) {
|
||||
if (!text || !window.speechSynthesis) return;
|
||||
if (!text) return;
|
||||
if (piperFallbackTimer) clearTimeout(piperFallbackTimer);
|
||||
if (!window.speechSynthesis || !window.SpeechSynthesisUtterance) {
|
||||
playPiperAudio(text, lang);
|
||||
return;
|
||||
}
|
||||
refreshSpeechVoices();
|
||||
doSpeak(text, lang);
|
||||
window.speechSynthesis.getVoices();
|
||||
if (!speechVoicesLoaded) {
|
||||
if (piperFallbackTimer) clearTimeout(piperFallbackTimer);
|
||||
piperFallbackTimer = setTimeout(function() {
|
||||
refreshSpeechVoices();
|
||||
if (!speechVoicesLoaded) playPiperAudio(text, lang);
|
||||
}, 900);
|
||||
}
|
||||
}
|
||||
|
||||
function playPiperAudio(text, lang) {
|
||||
if (!text) return;
|
||||
fetch('/api/tts', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text: text, lang: lang || 'es' })
|
||||
}).then(function(res) {
|
||||
if (!res.ok) throw new Error('tts failed');
|
||||
return res.blob();
|
||||
}).then(function(blob) {
|
||||
var url = URL.createObjectURL(blob);
|
||||
var audio = new Audio(url);
|
||||
audio.onended = function() { URL.revokeObjectURL(url); };
|
||||
audio.play();
|
||||
}).catch(function() {});
|
||||
}
|
||||
|
||||
function initSpeech() {
|
||||
|
||||
Reference in New Issue
Block a user