Spanish Problema TTS - máximo de caracteres [SOLUCIONADO]

elgransipe

Member
Licensed User
Longtime User
Hola.

Tengo un problema con la librería TTS. Cuando ha de "leer" textos de más de 4000 caracteres da error: "java.lang.RuntimeException: Error speaking text."

He estado haciendo pruebas y, efectivamente, cuando tengo alrededor de 4036 caracteres da dicho error.

He estado buscando info al respecto y he encontrado esto.

https://www.b4x.com/android/forum/threads/tts-maximum.23665/

http://stackoverflow.com/questions/19312536/android-tts-fails-to-speak-large-amount-of-text

http://stackoverflow.com/questions/13440251/android-tts-text-longer-than-4k-chars-not-playing

mi pregunta es, ¿hay alguna solución y/o alternativa a TTS?

he visto una librería (https://www.b4x.com/android/help/icoslibrary.html#icostexttospeech) pero no he conseguido hacer que funcione :(

Gracias y un saludo.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Cuando trabajé con TTS hace tiempo ya tuve esos problemas que creia que eran por la versión de Android, y se me ocurrió una forma simple de solucionarlo, al menos con el texto que yo trabajaba.

El texto que tenia que pasar a voz, antes de enviarlo a: TTS1.Speak(Texto, False) , miraba donde estaba el primer CRLF y enviaba ese trozo, luego me ponia en un bucle Do While Loop hasta que entraba en el evento Sub PE_TextToSpeechFinish (Intent As Intent) , en este evento tenia una variable global que me decia que habia acabado la pronunciación, el bucle lo detectaba y volvia a coger desde el ultimo CRLF hasta el siguiente y lo volvia a enviar, y asi hasta acabar todo el texto. Claro, me iba bien por que no tenia textos que no tuvieran un salto de linea en mas de 4000 caracteres. Si en tu texto no tienes CRLF, puedes enviar cuando detectes un punto "." , no quedará mal que en cada punto se detenga casi nada la pronunciación.

No se si me expliqué bien, si no lo tienes claro me lo dices y te hago un código rápido.

Saludos
 

elgransipe

Member
Licensed User
Longtime User
Hola

Cuando trabajé con TTS hace tiempo ya tuve esos problemas que creia que eran por la versión de Android, y se me ocurrió una forma simple de solucionarlo, al menos con el texto que yo trabajaba.

El texto que tenia que pasar a voz, antes de enviarlo a: TTS1.Speak(Texto, False) , miraba donde estaba el primer CRLF y enviaba ese trozo, luego me ponia en un bucle Do While Loop hasta que entraba en el evento Sub PE_TextToSpeechFinish (Intent As Intent) , en este evento tenia una variable global que me decia que habia acabado la pronunciación, el bucle lo detectaba y volvia a coger desde el ultimo CRLF hasta el siguiente y lo volvia a enviar, y asi hasta acabar todo el texto. Claro, me iba bien por que no tenia textos que no tuvieran un salto de linea en mas de 4000 caracteres. Si en tu texto no tienes CRLF, puedes enviar cuando detectes un punto "." , no quedará mal que en cada punto se detenga casi nada la pronunciación.

No se si me expliqué bien, si no lo tienes claro me lo dices y te hago un código rápido.

Saludos
Gracias.

Mas o menos era la idea que tenía y desconocía que existía el evento PE_TextToSpeechFinish para controlar cuando se ha dejado de "leer"

Voy a intentarlo a ver que sale :)

Gracias.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Acuerdate que para que se cumpla ese evento debes emplear la libreria Phone, seria algo asi:


B4X:
Sub Process_Globals
   Dim TTS1 As TTS
   Dim EstadoTelefono As PhoneEvents
   Dim MensajeVozFinalizado As Boolean
   Dim SalirBoton As Boolean
' ..............
' ..............
' ..............

Sub Activity_Create(FirstTime As Boolean)

Dim PhoneId As PhoneId
Dim PE As PhoneEvents
EstadoTelefono.InitializeWithPhoneState("PE",PhoneId)
' ..............
' ..............
' ..............

Sub PE_TextToSpeechFinish (Intent As Intent)
   MensajeVozFinalizado = True
End Sub


' ------------- Donde llames a poner el texto --------------
TTS1.Speak(Texto, False)
MensajeVozFinalizado = False
SalirBoton = False ' para salir del bucle sin acabar el mensaje de voz
   
Do While MensajeVozFinalizado = False And SalirBoton=False
   DoEvents
Loop

Saludos
 

elgransipe

Member
Licensed User
Longtime User
Gracias. Ya lo tengo en marcha.

Tan solo un apunte por si a alguien le sirve. Si el teléfono entra en ahorro de energía (activity pause) deja de funcionar "Sub PE_TextToSpeechFinish (IntentAsIntent)"

Un saludo.

P.D. el texto más largo de mi aplicación tiene casi 30.000 caracteres ;-)
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Me alegro que ya te funcione, puedes añadir al nombre del post [SOLUCIONADO] ? ,de esa forma hacemos mas agil el foro.

Gracias

Saludos
 
Top