🚀 Auto-deploy: Camila atualizado em 26/05/2026 13:07:23

This commit is contained in:
2026-05-26 13:07:23 +00:00
parent bfbc0c2a10
commit ace6c53448
+38 -16
View File
@@ -239,18 +239,36 @@ const initApp = () => {
loadVoices().then(voices => { cachedVoices = voices; });
// Escolher melhor voz feminina brasileira disponível
// Prioridade: Google pt-BR > Microsoft Natural > qualquer feminina > qualquer pt-BR
const getBestBRVoice = () => {
const brVoices = cachedVoices.filter(v => v.lang.includes('pt'));
// Prioridade: feminina > masculino, local > remote
const female = brVoices.find(v =>
/female|brasil|maria|luciana|fernanda|virtual/i.test(v.name)
);
const brVoices = cachedVoices.filter(v => v.lang === 'pt-BR' || v.lang === 'pt_BR');
if (brVoices.length === 0) {
// Fallback: qualquer voz portuguesa
const ptVoices = cachedVoices.filter(v => v.lang.startsWith('pt'));
return ptVoices[0] || null;
}
// 1. Melhor: vozes Google (muito naturais no Chrome/Android)
const google = brVoices.find(v => /google/i.test(v.name) && /femin|female/i.test(v.name));
if (google) return google;
const googleAny = brVoices.find(v => /google/i.test(v.name));
if (googleAny) return googleAny;
// 2. Microsoft Natural / Online (Edge tem vozes excelentes como Francisca)
const msNatural = brVoices.find(v => /natural|online|francisca|thalita|giovanna/i.test(v.name));
if (msNatural) return msNatural;
// 3. Qualquer voz feminina explícita
const female = brVoices.find(v => /female|femin|maria|luciana|fernanda|raquel|camila/i.test(v.name));
if (female) return female;
// fallback: qualquer voz brasileira
const brazil = brVoices.find(v => /brasil|brazil|pt-BR/i.test(v.lang));
if (brazil) return brazil;
// fallback: qualquer voz portuguesa
return brVoices[0] || null;
// 4. Vozes locais (melhor que remotas genéricas)
const local = brVoices.find(v => v.localService === true);
if (local) return local;
// 5. Qualquer voz pt-BR disponível
return brVoices[0];
};
// Falar texto com TTS nativo
@@ -268,16 +286,20 @@ const initApp = () => {
// Limpar markdown básico antes de falar
const clean = text
.replace(/```[\s\S]*?```/g, 'trecho de código ignorado')
.replace(/`[^`]+`/g, '')
.replace(/[*_#~\[\]]/g, '')
.replace(/\n+/g, ' ')
.replace(/```[\s\S]*?```/g, '') // remover blocos de código inteiros
.replace(/`[^`]+`/g, '') // remover inline code
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // links → só texto
.replace(/[*_#~\[\]>]/g, '') // remover formatação
.replace(/\n+/g, '. ') // quebras viram pausas naturais
.replace(/\s{2,}/g, ' ')
.trim();
if (!clean) return;
const utterance = new window.SpeechSynthesisUtterance(clean);
utterance.lang = 'pt-BR';
utterance.rate = 0.95;
utterance.pitch = 1.05;
utterance.rate = 1.12; // levemente mais rápida que o padrão
utterance.pitch = 1.0; // tom natural sem distorção
const voice = getBestBRVoice();
if (voice) utterance.voice = voice;