diff --git a/index.html b/index.html index 25daf9d..0d5993f 100644 --- a/index.html +++ b/index.html @@ -53,7 +53,7 @@ let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = ''; let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null; let recordStartTime = 0, recordDuration = 0; // ---------- Версия ---------- -const VERSION = 'v51'; +const VERSION = 'v52'; document.getElementById('ver').textContent = VERSION; // ---------- Перевод на русский (Groq) ---------- @@ -221,19 +221,28 @@ async function doCompare(blob, originalText, duration) { const elapsed = ((Date.now() - startTime) / 1000).toFixed(1); setStatus('Анализ... ' + elapsed + 'с'); }, 150); - let whisperResult, phon; + + // Шаг 1: транскрипция (быстро, ~0.5с) + let whisperResult = { text: '', error: null }; + try { whisperResult = await transcribe(blob); } + catch(e) { console.log('[COMPARE] transcribe failed:', e); } + + // Шаг 2: фонетика (может виснуть на decodeAudioData, таймаут 10с) + let phon = { pitchHz: 0, pitchStability: 0, voiceClarity: 0, phonScore: 0 }; try { - [whisperResult, phon] = await Promise.all([ - transcribe(blob), - phoneticAnalysis(blob) + phon = await Promise.race([ + phoneticAnalysis(blob), + new Promise(r => setTimeout(() => r({ pitchHz: 0, pitchStability: 0, voiceClarity: 0, phonScore: 0 }), 10000)) ]); - } catch(e) { - clearInterval(timerId); - isAnalyzing = false; - setStatus('Ошибка анализа.'); + } catch(e) { console.log('[COMPARE] phonetics failed:', e); } + + clearInterval(timerId); + isAnalyzing = false; + + if (whisperResult.error && !whisperResult.text) { + setStatus('Ошибка: ' + (whisperResult.error || 'сеть')); return ''; } - clearInterval(timerId); const phonEmoji = phon.phonScore >= 85 ? '🟢' : phon.phonScore >= 60 ? '🟡' : '🔴'; let recHTML = '', diffHTML = ''; @@ -264,7 +273,6 @@ async function doCompare(blob, originalText, duration) { ''; setStatus('Готово.'); - isAnalyzing = false; return whisperResult.text || ''; }