Android TextToSpeech ведет себя нерегулярно - PullRequest
2 голосов
/ 09 марта 2019

Обновление: после некоторых копаний мне удалось найти некоторую информацию в Logcat. Смотри внизу.

Редактировать 2: Я теперь создал новую деятельность с нуля, чтобы уменьшить проблему. Это все еще не работает правильно. Вот код:

public class MainActivity extends AppCompatActivity {
    private TextToSpeech textToSpeech;
    private boolean isInitialized = false;
    private MainActivity mainActivity;
    int ctr = 0;
    private String words[] = {"ord", "kula", "fotboll"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mainActivity = this;

        textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.SUCCESS){
                    textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                        @Override
                        public void onStart(String utteranceId) {
                            System.out.println("---onStart");
                        }

                        @Override
                        public void onDone(String utteranceId) {
                           System.out.println("-----onDone");
                        }

                        @Override
                        public void onError(String utteranceId) {
                            System.out.println("-----onError");
                        }

                        @Override
                        public void onError(String utteranceId, int errorCode){
                            onError(utteranceId);
                            System.out.println("Error with code: " + errorCode);
                        }
                    });
                    isInitialized = true;
                    Locale locale = new Locale("swe");
                    textToSpeech.setLanguage(locale);
                }
            }
        });
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (isInitialized){
                    System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
                    textToSpeech.speak(words[ctr], TextToSpeech.QUEUE_FLUSH, null, "SpeakTest");
                    ctr++;
                    ctr %= words.length;
                } else {
                    Snackbar.make(view, "Speaker not ready", Snackbar.LENGTH_LONG)
                            .setAction("Action", null).show();
                }
            }
        });

    }
}

Что удивительно, так это то, что произносятся только слова «ord» и «fotboll», но не «kula». Если я поменяю words на {"kula", "kula", "kula"} и попробую достаточно долго, он вдруг начнет работать. Как я понял в документации, нужно использовать теги здесь . Я пытался se, swe, sv, все с тем же результатом. Далее, команда System.out.println(textToSpeech.getLanguage().getDisplayLanguage()); дает svenska, что является правильным.

Если я перейду на en, он будет работать постоянно. Также я получаю System.out.println(textToSpeech.getLanguage().getDisplayLanguage()); = engelska снова правильно.

Что на земле происходит?

EDIT:

Я добавил UtteranceProgressListener, в соответствии с это , метод

onError(String id) устарело и должно быть заменено на onError(String id, int errorCode). Тем не менее, я расширил свой класс с помощью UtteranceProgressListener, и это заставляет меня реализовать старый метод onError. Это всегда называется, поэтому что-то не так, но я не знаю, что.

Это потому, что другой onError(String id, int code) никогда не вызывается.

Я обновил код.


У меня есть функция, которая должна произносить слово на определенном языке при вызове функции.

До тех пор, пока пару дней назад в моем Sony Compact XZ2 все работало нормально, но теперь это происходит нерегулярно. Иногда слово произносится, а иногда нет. Команда textToSpeech.getEngines() возвращает com.google.android.tts

Например, для шведского языка в setLanguage я пробовал "sv" и "sv-SV" при создании объекта Locale. Это не помогло.

Я только что заметил, что когда я нажимаю кнопку, которая вызывает playWord(text) несколько раз (> 40), это работает, а иногда работает напрямую. Кажется, какая-то странная задержка.

Функция speakText вызывается из этой функции в моем Fragment:

private void playWord(){
    if (text2Speech.isReady()) {
        text2Speech.checkSpeaking();
        text2Speech.setLanguage(getAcronym(mTraining.getCurrentSrc()));
        text2Speech.speakText(front);
    } else {
        Toast.makeText(getContext(),"Speaker not ready yet", Toast.LENGTH_SHORT).show();
    }
}

Это класс, который обращается с речью. Я не получил никаких сообщений об ошибках. Просто кажется случайным, когда динамик работает.

public class Text2Speech extends UtteranceProgressListener {
    private Context mContext;
    private TextToSpeech textToSpeech;
    private boolean isReady = false;
    public Text2Speech(Context context, final String src){
        mContext = context;
        System.out.println("text2Speech created");
        textToSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.SUCCESS) {
                    isReady = true;
                    Locale locale = new Locale(src);
                    int ttsLang = textToSpeech.setLanguage(locale);
                    if (ttsLang == TextToSpeech.LANG_MISSING_DATA
                            || ttsLang == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Log.e("TTS", "The Language is not supported!");
                    } else {
                        Log.i("TTS", "Language Supported.");
                    }
                    Log.i("TTS", "Initialization success.");
                } else {
                    Toast.makeText(mContext, "TTS Initialization failed!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public boolean isReady(){
        return isReady;
    }
    public void checkSpeaking(){
        if (textToSpeech.isSpeaking()){
            textToSpeech.stop();
        }
    }

    public void showMessage(String msg){
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }
    public void speakText(String text){
        int speechStatus = textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
        switch (speechStatus){
            case TextToSpeech.ERROR_INVALID_REQUEST:
                showMessage("Invalid Request");
                break;
            case TextToSpeech.ERROR_NETWORK:
                showMessage("Network Error");
                break;
            case TextToSpeech.ERROR_NETWORK_TIMEOUT:
                showMessage("Network Timeout");
                break;
            case TextToSpeech.ERROR_NOT_INSTALLED_YET:
                showMessage("Error Not Yet Downloaded");
                break;
            case TextToSpeech.ERROR_OUTPUT:
                showMessage("Output Error");
                break;
            case TextToSpeech.ERROR_SERVICE:
                showMessage("Error of TTS service");
                break;
            case TextToSpeech.ERROR_SYNTHESIS:
                showMessage("Error synthesizing");
                break;
            case TextToSpeech.LANG_NOT_SUPPORTED:
                showMessage("Language nor supported");
                break;

        }
        if (speechStatus == TextToSpeech.ERROR) {
            Log.e("TTS", "Error in converting Text to Speech!");
        }
        System.out.println("speech status - text " + speechStatus + " - " + text);
    }

    public void setLanguage(String src){
        Locale locale = new Locale(src);
        int tts = textToSpeech.setLanguage(locale);
        System.out.println(tts + "  " + src);
        if (tts == TextToSpeech.LANG_MISSING_DATA
                || tts == TextToSpeech.LANG_NOT_SUPPORTED) {
            Toast.makeText(mContext, "Language not yet supported.", Toast.LENGTH_LONG).show();
        }
    }

    public void stop(){
        textToSpeech.stop();
        textToSpeech.shutdown();
    }

@Override
public void onStart(String utteranceId) {
    Log.e("START", "start speaking");
}

@Override
public void onDone(String utteranceId) {
    Log.e("DONE", "done speaking");
}

@Override
public void onError(String utteranceID){
    Log.e("Error", "Not infromative");
}

// This is not called!
@Override
public void onError(String utteranceId, int errorCode) {
    Log.e("Error", "Error speaking");
}
}

Вот сообщение об ошибке в Logcat:

NetworkSynthesizer: ExecutionException during NetworkFetchTask
    java.util.concurrent.ExecutionException: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
        at java.util.concurrent.FutureTask.report(FutureTask.java:123)
        at java.util.concurrent.FutureTask.get(FutureTask.java:207)
        at avf.a(PG:37)
        at avf.a(PG:154)
        at com.google.android.tts.service.GoogleTTSService.onSynthesizeText(PG:250)
        at android.speech.tts.TextToSpeechService$SynthesisSpeechItem.playImpl(TextToSpeechService.java:1033)
        at android.speech.tts.TextToSpeechService$SpeechItem.play(TextToSpeechService.java:819)
        at android.speech.tts.TextToSpeechService$SynthHandler$1.run(TextToSpeechService.java:583)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:280)
        at android.os.HandlerThread.run(HandlerThread.java:65)
     Caused by: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
        at cze.a(PG:58)
        at cze.a(PG:29)
        at dao.a(PG:21)
        at ave.a(PG:36)
        at ave.call(PG:80)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
2019-03-16 21:35:46.917 1356-5238/? E/ActivityManager: Sending non-protected broadcast com.sonymobile.intent.action.POWER_BACK_OFF_FACTOR_CHANGED from system 2179:com.android.phone/1001 pkg com.android.phone
    java.lang.Throwable
        at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:21814)
        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:22423)
        at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:22565)
        at android.app.IActivityManager$Stub.onTransact$broadcastIntent$(IActivityManager.java:10171)
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:167)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3416)
        at android.os.Binder.execTransact(Binder.java:731)
2019-03-16 21:35:46.917 12061-13318/? E/TTS.GoogleTTSServiceImp: Synthesis failure with error status code: -4
2019-03-16 21:35:46.918 12061-13318/? W/PlaybackSynthesisRequest: done() was called before start() call
2019-03-16 21:35:46.919 6468-6489/com.erikbylow.tailoreddictfire D/SPEECH: Error

Когда я включаю WiFi, он работает.

Предположение: неужели языки отсутствовали и не загружались, когда я не использовал WiFi? Когда я включил WiFi, языки скачивались?

Для меня эта ошибка: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric... похоже, что всегда был сетевой запрос, но после включения WiFi я мог использовать TextToSpeach в режиме полета.

С другой стороны, я пробовал это по-русски в режиме полета, который не работал. Я включил интернет без WiFi, потом все заработало. Снова включил WiFi и потом русский тоже работал. По крайней мере, это говорит о том, что нужно что-то скачать?

Я бы хотел выяснить, что является причиной проблемы и как ее решить, поскольку это приложение в Google Play. (Хотя у меня сейчас 0 активных пользователей рядом со мной ...):).

...