fix bug
This commit is contained in:
@@ -146,14 +146,11 @@ function createRecognition() {
|
|||||||
if (!SpeechRecognition) return null;
|
if (!SpeechRecognition) return null;
|
||||||
const r = new SpeechRecognition();
|
const r = new SpeechRecognition();
|
||||||
r.lang = 'de-DE';
|
r.lang = 'de-DE';
|
||||||
r.continuous = true;
|
r.continuous = false; // one phrase per session — avoids all Android e.resultIndex bugs
|
||||||
r.interimResults = true;
|
r.interimResults = true; // stream words within the phrase
|
||||||
r.maxAlternatives = 1;
|
r.maxAlternatives = 1;
|
||||||
|
|
||||||
// Android Chrome bug: onresult re-fires old results with e.resultIndex=0.
|
let committed = false; // guard: each session commits at most one final result
|
||||||
// highestFinalIndex guards against processing the same final result twice.
|
|
||||||
let highestFinalIndex = -1;
|
|
||||||
let sessionFinal = ''; // final text committed within this recognition session
|
|
||||||
|
|
||||||
r.onstart = () => {
|
r.onstart = () => {
|
||||||
recordBtn.classList.add('recording');
|
recordBtn.classList.add('recording');
|
||||||
@@ -162,35 +159,27 @@ function createRecognition() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
r.onresult = (e) => {
|
r.onresult = (e) => {
|
||||||
let interim = '';
|
if (committed) return;
|
||||||
for (let i = 0; i < e.results.length; i++) {
|
const result = e.results[0];
|
||||||
if (e.results[i].isFinal) {
|
const text = result[0].transcript;
|
||||||
if (i > highestFinalIndex) {
|
if (result.isFinal) {
|
||||||
sessionFinal += (sessionFinal ? ' ' : '') + e.results[i][0].transcript;
|
committed = true;
|
||||||
highestFinalIndex = i;
|
state.finalTranscript += (state.finalTranscript ? ' ' : '') + text;
|
||||||
}
|
state.transcript = state.finalTranscript;
|
||||||
} else {
|
} else {
|
||||||
interim = e.results[i][0].transcript; // only the latest interim matters
|
// interim — show but don't commit
|
||||||
}
|
state.transcript = (state.finalTranscript ? state.finalTranscript + ' ' : '') + text;
|
||||||
}
|
}
|
||||||
const base = state.finalTranscript;
|
if (state.transcript.trim().split(/\s+/).length >= MAX_RECORD_WORDS) {
|
||||||
const combined = base + (base && sessionFinal ? ' ' : '') + sessionFinal;
|
|
||||||
const display = combined + (interim ? (combined ? ' ' : '') + interim : '');
|
|
||||||
if (display.trim().split(/\s+/).length >= MAX_RECORD_WORDS) {
|
|
||||||
stopRecording();
|
stopRecording();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateTranscriptBox(display);
|
updateTranscriptBox(state.transcript);
|
||||||
state.transcript = display;
|
checkBtn.disabled = !state.transcript.trim();
|
||||||
checkBtn.disabled = !display.trim();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
r.onend = () => {
|
r.onend = () => {
|
||||||
if (!state.isRecording) return;
|
if (!state.isRecording) return;
|
||||||
// Merge this session's final text into the persistent accumulator before restarting
|
|
||||||
if (sessionFinal) {
|
|
||||||
state.finalTranscript += (state.finalTranscript ? ' ' : '') + sessionFinal;
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!state.isRecording) return;
|
if (!state.isRecording) return;
|
||||||
recognition = createRecognition();
|
recognition = createRecognition();
|
||||||
@@ -198,7 +187,6 @@ function createRecognition() {
|
|||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 'aborted' fires during normal restart cycle — ignore it
|
|
||||||
r.onerror = (e) => {
|
r.onerror = (e) => {
|
||||||
if (e.error !== 'no-speech' && e.error !== 'aborted') stopRecording();
|
if (e.error !== 'no-speech' && e.error !== 'aborted') stopRecording();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user