Read long text with voice in Android using TextToSpeech

Question:

I am implementing text reading with voice in .

The code works, but I am running into difficulty that TextToSpeech cannot read more than 4000 characters at a time.

How could I make my method read me all the text when it exceeds the limit allowed by TextToSpeech ?

EDITING NOTE :

It seems the best way is to create a mechanism that separates the text into several parts and reads it in a kind of read queue. I tried to read the different parts by calling inside a loop tts.speak(parteDelTexto, TextToSpeech.QUEUE_ADD, bundle, null) but only reads the first occurrence of the loop.

I've been researching and on various sites they talk about using QUEUE_ADD and onUtterance , but I can't figure out how to implement or create that read queue.

This is my code:

Function called when clicking on the read icon:

public void ttsFunction() {
        tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.SUCCESS) {
                    Locale locSpanish = new Locale("spa", "ESP");
                    int result = tts.setLanguage(locSpanish);
                    if (result == TextToSpeech.LANG_MISSING_DATA
                            || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Toast.makeText(getApplicationContext(), "Lenguaje no soportado", Toast.LENGTH_SHORT).show();
                    } else {
                        Log.v(TAG, "onInit exitoso");
                        final TextView mTextView = (TextView) findViewById(R.id.txt_oficio);

                        String strTexto = mTextView.getText().toString();
                        leerTexto(strTexto);
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "Falló la inicialización", Toast.LENGTH_SHORT).show();
                }

            }
        });
    }

Voice reading function itself

Limiting the content like this strTexto = strTexto.substring(0,3999); it works, but I want to read all the text.

void leerTexto(String strTexto){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Log.v(TAG, "API 21+");
        Bundle bundle = new Bundle();
        bundle.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_MUSIC);
        strTexto = strTexto.substring(0,3999); //Así funciona
        tts.speak(strTexto, TextToSpeech.QUEUE_FLUSH, bundle, null);
    } else {
        Log.v(TAG, "API 15-");
        HashMap<String, String> param = new HashMap<>();
        param.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
        tts.speak(strTexto, TextToSpeech.QUEUE_FLUSH, param);
    }
}

Answer:

Actually the limitation using TextToSpeech is the one obtained by getMaxSpeechInputLength() which is currently set to 4000 characters.

public static int getMaxSpeechInputLength() {
    return 4000;
}

The option here is to separate the playback of the text by blocks, however this will result in a pause when playing each block.

Based on this limitation, based on personal experience, a batch process had to be carried out to generate the audio of the texts, but using another option , by having the mp3 url, they are played through MediaPlayer .

Scroll to Top