From b70adcd2957ec737f7037b56faa3e262efee4af1 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 2 Apr 2026 11:25:04 +0000 Subject: [PATCH] Autosave: 20260402-112504 --- assets/js/main.js | 72 +++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/assets/js/main.js b/assets/js/main.js index da716e1..e99f77b 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -215,40 +215,50 @@ document.addEventListener('DOMContentLoaded', () => { playChime(); - if ('speechSynthesis' in window) { - setTimeout(() => { - const text = locale === 'ar' ? (latest.dataset.announcementAr || '') : (latest.dataset.announcementEn || ''); - if (text) { - // Removed window.speechSynthesis.cancel(); as it can prevent speech in some browsers - const utterance = new SpeechSynthesisUtterance(text); - utterance.lang = locale === 'ar' ? 'ar-SA' : 'en-US'; - const voices = availableVoices.length > 0 ? availableVoices : window.speechSynthesis.getVoices(); - const langPrefix = locale === 'ar' ? 'ar' : 'en'; - const langVoices = voices.filter(v => v.lang.toLowerCase().startsWith(langPrefix)); - - if (langVoices.length > 0) { - // Try to find a high-quality (Google/Microsoft Natural) voice - const bestVoice = langVoices.find(v => - v.name.includes('Google') || - v.name.includes('Natural') || - v.name.includes('Premium') || - v.name.includes('Online') - ) || langVoices.find(v => v.name.includes('Microsoft')) || langVoices[0]; + setTimeout(() => { + const text = locale === 'ar' ? (latest.dataset.announcementAr || '') : (latest.dataset.announcementEn || ''); + if (text) { + // Use Google Translate TTS (outside high-quality voice API) + const tl = locale === 'ar' ? 'ar' : 'en'; + const gTtsUrl = 'https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=' + tl + '&q=' + encodeURIComponent(text); + + const audio = new Audio(gTtsUrl); + audio.onended = () => { if (videoPlayer) videoPlayer.volume = 1.0; }; + + audio.onerror = () => { + // Fallback to built-in if external TTS fails + console.warn("External TTS failed, falling back to built-in speech"); + if ('speechSynthesis' in window) { + const utterance = new SpeechSynthesisUtterance(text); + utterance.lang = locale === 'ar' ? 'ar-SA' : 'en-US'; + const voices = availableVoices.length > 0 ? availableVoices : window.speechSynthesis.getVoices(); + const langPrefix = locale === 'ar' ? 'ar' : 'en'; + const langVoices = voices.filter(v => v.lang.toLowerCase().startsWith(langPrefix)); - utterance.voice = bestVoice; + if (langVoices.length > 0) { + const bestVoice = langVoices.find(v => + v.name.includes('Google') || v.name.includes('Natural') || v.name.includes('Premium') || v.name.includes('Online') + ) || langVoices.find(v => v.name.includes('Microsoft')) || langVoices[0]; + if (bestVoice) utterance.voice = bestVoice; + } + + utterance.onend = () => { if (videoPlayer) videoPlayer.volume = 1.0; }; + utterance.onerror = () => { if (videoPlayer) videoPlayer.volume = 1.0; }; + window.speechSynthesis.speak(utterance); + } else { + if (videoPlayer) videoPlayer.volume = 1.0; } - - utterance.onend = () => { if (videoPlayer) videoPlayer.volume = 1.0; }; - utterance.onerror = () => { if (videoPlayer) videoPlayer.volume = 1.0; }; - - window.speechSynthesis.speak(utterance); - } else { - if (videoPlayer) videoPlayer.volume = 1.0; + }; + + // Attempt to play external audio + const playPromise = audio.play(); + if (playPromise !== undefined) { + playPromise.catch(audio.onerror); } - }, 1200); // play voice after chime finishes - } else { - setTimeout(() => { if (videoPlayer) videoPlayer.volume = 1.0; }, 2000); - } + } else { + if (videoPlayer) videoPlayer.volume = 1.0; + } + }, 1200); // play voice after chime finishes } } }