Skip to content

Commit f06c0bd

Browse files
fix: use local speech synthesis only
Remove Google TTS fallback and the failure alert; pronunciation now relies solely on browser zh-CN speech synthesis. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a2ee788 commit f06c0bd

1 file changed

Lines changed: 8 additions & 77 deletions

File tree

js/app.js

Lines changed: 8 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -10,87 +10,18 @@
1010
let pronounceIndex = 0;
1111
let quizState = null;
1212
let chineseVoice = null;
13-
let currentSpeechAudio = null;
1413

15-
function stopSpeechAudio() {
16-
if (currentSpeechAudio) {
17-
currentSpeechAudio.pause();
18-
currentSpeechAudio = null;
19-
}
20-
}
21-
22-
function speechPlaybackRate(rate) {
23-
return rate >= 0.55 ? 0.85 : 0.65;
24-
}
25-
26-
function getGoogleTtsUrls(text) {
27-
const q = encodeURIComponent(text);
28-
return [
29-
`https://translate.google.com/translate_tts?ie=UTF-8&client=gtx&sl=zh-CN&tl=zh-CN&q=${q}`,
30-
`https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&sl=zh-CN&tl=zh-CN&q=${q}`,
31-
`https://translate.google.com/translate_tts?ie=UTF-8&client=gtx&tl=zh-CN&q=${q}`
32-
];
33-
}
34-
35-
function playAudioUrl(url, rate) {
36-
return new Promise((resolve, reject) => {
37-
const audio = new Audio(url);
38-
audio.playbackRate = speechPlaybackRate(rate);
39-
currentSpeechAudio = audio;
40-
audio.onended = resolve;
41-
audio.onerror = reject;
42-
audio.play().catch(reject);
43-
});
44-
}
14+
function speak(text, rate = DEFAULT_SPEECH_RATE) {
15+
if (!('speechSynthesis' in window)) return;
4516

46-
async function playGoogleTts(text, rate = DEFAULT_SPEECH_RATE) {
4717
speechSynthesis.cancel();
48-
stopSpeechAudio();
49-
50-
const urls = getGoogleTtsUrls(text);
51-
for (const url of urls) {
52-
try {
53-
await playAudioUrl(url, rate);
54-
return;
55-
} catch {
56-
stopSpeechAudio();
57-
}
58-
}
5918

60-
throw new Error('Google TTS failed');
61-
}
62-
63-
function speakWithSynth(text, rate = DEFAULT_SPEECH_RATE) {
64-
return new Promise((resolve, reject) => {
65-
if (!('speechSynthesis' in window)) {
66-
reject(new Error('No speech synthesis'));
67-
return;
68-
}
69-
70-
stopSpeechAudio();
71-
speechSynthesis.cancel();
72-
73-
const utterance = new SpeechSynthesisUtterance(text);
74-
utterance.lang = 'zh-CN';
75-
utterance.rate = rate;
76-
const voice = getChineseVoice();
77-
if (voice) utterance.voice = voice;
78-
utterance.onend = () => resolve();
79-
utterance.onerror = () => reject(new Error('Speech synthesis failed'));
80-
speechSynthesis.speak(utterance);
81-
});
82-
}
83-
84-
async function speak(text, rate = DEFAULT_SPEECH_RATE) {
85-
try {
86-
await speakWithSynth(text, rate);
87-
} catch {
88-
try {
89-
await playGoogleTts(text, rate);
90-
} catch {
91-
alert('Không phát được âm thanh. Kiểm tra mạng và thử lại.');
92-
}
93-
}
19+
const utterance = new SpeechSynthesisUtterance(text);
20+
utterance.lang = 'zh-CN';
21+
utterance.rate = rate;
22+
const voice = getChineseVoice();
23+
if (voice) utterance.voice = voice;
24+
speechSynthesis.speak(utterance);
9425
}
9526

9627
function initSpeech() {

0 commit comments

Comments
 (0)