fix: VAD - detector de silêncio no browser
- AudioContext + Analyser para monitorar nível de áudio em tempo real - Threshold: avg < 10 por 60% dos frames = silêncio detectado - Botão parar fica vermelho quando silêncio é detectado (aviso visual) - Tooltip 'Silêncio detectado - Clique se quiser parar' - Cleanup de AudioContext ao parar Isso mitiga hallucinação do Whisper em áudios silenciosos/muito limpos
This commit is contained in:
+59
-1
@@ -2000,11 +2000,17 @@ const initApp = () => {
|
||||
const btnAnalyzeTranscription = document.getElementById('btnAnalyzeTranscription');
|
||||
const recordProcessingText = document.getElementById('recordProcessingText');
|
||||
const recordProcessingSubtext = document.getElementById('recordProcessingSubtext');
|
||||
|
||||
// Variáveis de gravação
|
||||
let mediaRecorder = null;
|
||||
let audioChunks = [];
|
||||
let recordingStartTime = null;
|
||||
let timerInterval = null;
|
||||
let audioContext = null;
|
||||
let analyser = null;
|
||||
let frequencyData = null;
|
||||
let silenceFrames = 0;
|
||||
let totalFrames = 0;
|
||||
let vadCheckInterval = null;
|
||||
let generatedReport = null;
|
||||
let generatedCriancas = null;
|
||||
let generatedTurma = 'não informada';
|
||||
@@ -2021,6 +2027,9 @@ const initApp = () => {
|
||||
}
|
||||
}
|
||||
clearInterval(timerInterval);
|
||||
clearInterval(vadCheckInterval);
|
||||
if (audioContext) { audioContext.close(); audioContext = null; }
|
||||
if (analyser) { analyser = null; frequencyData = null; }
|
||||
audioChunks = [];
|
||||
generatedReport = null;
|
||||
recordModal.style.display = 'none';
|
||||
@@ -2074,6 +2083,52 @@ const initApp = () => {
|
||||
options = { mimeType: 'audio/mp4' };
|
||||
}
|
||||
}
|
||||
// Configurar AudioContext para VAD
|
||||
audioContext = new AudioContext();
|
||||
const source = audioContext.createMediaStreamSource(stream);
|
||||
analyser = audioContext.createAnalyser();
|
||||
analyser.fftSize = 256;
|
||||
source.connect(analyser);
|
||||
frequencyData = new Uint8Array(analyser.frequencyBinCount);
|
||||
|
||||
// Iniciar verificação de silêncio (VAD)
|
||||
silenceFrames = 0;
|
||||
totalFrames = 0;
|
||||
vadCheckInterval = setInterval(() => {
|
||||
if (!analyser) return;
|
||||
analyser.getByteFrequencyData(frequencyData);
|
||||
const avg = frequencyData.reduce((a, b) => a + b, 0) / frequencyData.length;
|
||||
totalFrames++;
|
||||
if (avg < 10) {
|
||||
silenceFrames++;
|
||||
} else {
|
||||
silenceFrames = Math.max(0, silenceFrames - 2); // recupera mais rápido
|
||||
}
|
||||
// Atualizar indicator visual
|
||||
const recordWaveform = document.getElementById('recordWaveform');
|
||||
if (recordWaveform && recordWaveform.children[0]) {
|
||||
const bars = recordWaveform.children;
|
||||
bars.forEach((bar) => {
|
||||
const h = Math.max(4, (avg / 255) * 50 + Math.random() * 10);
|
||||
bar.style.height = `${h}px`;
|
||||
});
|
||||
}
|
||||
// Se mais de 60% dos últimos 30 frames for silêncio, avisar
|
||||
if (totalFrames > 30 && (silenceFrames / 30) > 0.6) {
|
||||
const btnStopRecord = document.getElementById('btnStopRecord');
|
||||
if (btnStopRecord && !btnStopRecord.disabled) {
|
||||
btnStopRecord.style.borderColor = '#ff6b6b';
|
||||
btnStopRecord.title = 'Silêncio detectado - Clique se quiser parar';
|
||||
}
|
||||
} else {
|
||||
const btnStopRecord = document.getElementById('btnStopRecord');
|
||||
if (btnStopRecord) {
|
||||
btnStopRecord.style.borderColor = '';
|
||||
btnStopRecord.title = '';
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
|
||||
mediaRecorder = new MediaRecorder(stream, options);
|
||||
|
||||
mediaRecorder.ondataavailable = (e) => {
|
||||
@@ -2110,6 +2165,9 @@ const initApp = () => {
|
||||
}
|
||||
}
|
||||
clearInterval(timerInterval);
|
||||
clearInterval(vadCheckInterval);
|
||||
if (audioContext) { audioContext.close(); audioContext = null; }
|
||||
if (analyser) { analyser = null; frequencyData = null; }
|
||||
|
||||
// Mostra processando com texto de transcrição
|
||||
if (recordProcessingText) recordProcessingText.textContent = 'Transcrevendo áudio...';
|
||||
|
||||
Reference in New Issue
Block a user