chore: auto-merge develop → main
Triggered by: 149cff3 fix(kiosk): force STREAM_MUSIC for TTS + JS feedback callbacks
This commit is contained in:
+19
-1
@@ -14180,8 +14180,26 @@ async function testTTS() {
|
|||||||
s.tts_rate = parseFloat(document.getElementById('setting-tts-rate')?.value) || 1;
|
s.tts_rate = parseFloat(document.getElementById('setting-tts-rate')?.value) || 1;
|
||||||
s.tts_pitch = parseFloat(document.getElementById('setting-tts-pitch')?.value) || 1;
|
s.tts_pitch = parseFloat(document.getElementById('setting-tts-pitch')?.value) || 1;
|
||||||
saveSettingsToStorage(s);
|
saveSettingsToStorage(s);
|
||||||
|
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status'; statusEl.textContent = '⏳ Invio al motore TTS Android...'; }
|
||||||
|
// Register callbacks: Android will call these after speak completes/fails
|
||||||
|
let _ttsTestTimer = null;
|
||||||
|
window._kioskTtsDone = (uid) => {
|
||||||
|
clearTimeout(_ttsTestTimer);
|
||||||
|
window._kioskTtsDone = null; window._kioskTtsError = null;
|
||||||
|
if (statusEl) { statusEl.className = 'settings-status success'; statusEl.textContent = '✅ Voce riprodotta correttamente.'; }
|
||||||
|
};
|
||||||
|
window._kioskTtsError = (uid, code) => {
|
||||||
|
clearTimeout(_ttsTestTimer);
|
||||||
|
window._kioskTtsDone = null; window._kioskTtsError = null;
|
||||||
|
const msg = code == -1 ? 'sintesi non riuscita' : code == -2 ? 'lingua non supportata' : code == -3 ? 'servizio non disponibile' : ('codice ' + code);
|
||||||
|
if (statusEl) { statusEl.className = 'settings-status error'; statusEl.textContent = '❌ Errore TTS Android (' + msg + ') — installa o aggiorna Google Text-to-Speech dal Play Store.'; }
|
||||||
|
};
|
||||||
|
// Timeout: if Android doesn't callback within 4s, warn about media volume
|
||||||
|
_ttsTestTimer = setTimeout(() => {
|
||||||
|
window._kioskTtsDone = null; window._kioskTtsError = null;
|
||||||
|
if (statusEl) { statusEl.className = 'settings-status error'; statusEl.textContent = '⚠️ Nessun feedback ricevuto. Controlla: 1) volume media del dispositivo non sia 0; 2) Google Text-to-Speech installato e aggiornato; 3) pacchetto vocale italiano scaricato.'; }
|
||||||
|
}, 4000);
|
||||||
_speakBrowser('Test vocale EverShelf. La sintesi vocale funziona correttamente.');
|
_speakBrowser('Test vocale EverShelf. La sintesi vocale funziona correttamente.');
|
||||||
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status success'; statusEl.textContent = '✅ Riproduzione in corso — controlla l\'audio del dispositivo.'; }
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!window.speechSynthesis) {
|
if (!window.speechSynthesis) {
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.media.AudioManager
|
||||||
import android.speech.tts.TextToSpeech
|
import android.speech.tts.TextToSpeech
|
||||||
|
import android.speech.tts.UtteranceProgressListener
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import android.view.WindowInsetsController
|
import android.view.WindowInsetsController
|
||||||
@@ -144,6 +146,25 @@ class KioskActivity : AppCompatActivity() {
|
|||||||
if (res == TextToSpeech.LANG_MISSING_DATA || res == TextToSpeech.LANG_NOT_SUPPORTED) {
|
if (res == TextToSpeech.LANG_MISSING_DATA || res == TextToSpeech.LANG_NOT_SUPPORTED) {
|
||||||
tts?.language = Locale.getDefault()
|
tts?.language = Locale.getDefault()
|
||||||
}
|
}
|
||||||
|
tts?.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
|
||||||
|
override fun onStart(utteranceId: String?) {}
|
||||||
|
override fun onDone(utteranceId: String?) {
|
||||||
|
runOnUiThread {
|
||||||
|
webView.evaluateJavascript("if(window._kioskTtsDone)window._kioskTtsDone('$utteranceId')", null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Deprecated("Deprecated in API 21")
|
||||||
|
override fun onError(utteranceId: String?) {
|
||||||
|
runOnUiThread {
|
||||||
|
webView.evaluateJavascript("if(window._kioskTtsError)window._kioskTtsError('$utteranceId','error')", null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onError(utteranceId: String?, errorCode: Int) {
|
||||||
|
runOnUiThread {
|
||||||
|
webView.evaluateJavascript("if(window._kioskTtsError)window._kioskTtsError('$utteranceId',$errorCode)", null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
ttsReady = true
|
ttsReady = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +487,10 @@ class KioskActivity : AppCompatActivity() {
|
|||||||
if (!ttsReady) return
|
if (!ttsReady) return
|
||||||
engine.setSpeechRate(rate.coerceIn(0.1f, 4f))
|
engine.setSpeechRate(rate.coerceIn(0.1f, 4f))
|
||||||
engine.setPitch(pitch.coerceIn(0.1f, 4f))
|
engine.setPitch(pitch.coerceIn(0.1f, 4f))
|
||||||
engine.speak(text, android.speech.tts.TextToSpeech.QUEUE_FLUSH, null, "kiosk_tts")
|
val params = Bundle().apply {
|
||||||
|
putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_MUSIC)
|
||||||
|
}
|
||||||
|
engine.speak(text, TextToSpeech.QUEUE_FLUSH, params, "kiosk_tts")
|
||||||
}
|
}
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
fun stopSpeech() { tts?.stop() }
|
fun stopSpeech() { tts?.stop() }
|
||||||
|
|||||||
Reference in New Issue
Block a user