Autosave: 20260402-112504

This commit is contained in:
Flatlogic Bot 2026-04-02 11:25:04 +00:00
parent e8e0abdac5
commit b70adcd295

View File

@ -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));
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);
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];
const audio = new Audio(gTtsUrl);
audio.onended = () => { if (videoPlayer) videoPlayer.volume = 1.0; };
utterance.voice = bestVoice;
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));
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
}
}
}