Android文本到语音语音失真的开始

vof42yt1  于 2023-02-02  发布在  Android
关注(0)|答案(1)|浏览(160)

在Android应用程序中,我有一个文本,用户按下按钮后,它将由TTS说:

import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;

                       final Button speech = findViewById(R.id.speech);
                        speech.setOnClickListener(speech1 -> {
    
                            if (!isPackageInstalled("com.google.android.tts")) {
                                showMsgSnack(getString(R.string.noTTS));
                            } else {
                                Boolean speak = checkSpeak();
    
                                if (!speak) {
                                    speech.setCompoundDrawablesWithIntrinsicBounds(R.drawable.stop, 0, 0, 0);
                                    if (history.length() > 3999) {
                                        String var = history.substring(0, 3999);
                                        ConvertTextToSpeech(var, "test");
                                        String var2 = history.substring(3999);
                                        ConvertTextToSpeech(var2, "test");
                                    } else {
                                        ConvertTextToSpeech(history, "test");
                                    }
                                    saveSpeak(true);
                                } else {
                                    speech.setCompoundDrawablesWithIntrinsicBounds(R.drawable.play, 0, 0, 0);
                                    tts.stop();
                                    saveSpeak(false);
                                }
                            }
                        });
    
    private void ConvertTextToSpeech(String history, String par) {
        String readableText = fromHtml(history).toString(); //remove HTML tags -> do not read <br>
        Bundle params = new Bundle();
        params.putString(KEY_PARAM_UTTERANCE_ID, "");
        tts.speak(readableText, TextToSpeech.QUEUE_ADD, params, par);
    }

关于TTS的东西:

if ((isPackageInstalled("com.google.android.tts"))) {
tts=new TextToSpeech(SingleitemView.this, status -> {
    if(status == TextToSpeech.SUCCESS){
        if (isLangAvailable(this,tts,locale)) {tts.setLanguage(locale);}
        else {tts.setLanguage(new Locale("en"));}

       tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
            @Override
            public void onDone(String utteranceId) {
                // Log.d("Speak", "TTS finished");
                if (utteranceId.equals("test")) {
                saveSpeak(false);
                runOnUiThread(() -> {
                    Button view2 = findViewById(R.id.speech);
                    view2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.play, 0, 0, 0);
                });
                }
            }

            @Override
            public void onError(String utteranceId) {
            }

            @Override
            public void onStart(String utteranceId) {
            }
        });

    }
},"com.google.android.tts");}

这工作了多年没有问题,TTS阅读文本,即使它很短,或超过3999个字符.突然几个月前(没有任何变化,从我这边的应用程序),当它开始说较长的文本,前3-4个单词是扭曲的,几乎无法理解的每一个文本.
看起来就像它在后台做一些事情,而它在同一时间阅读文本。
不知道发生了什么事,因为我没有改变我的代码,它一直工作到现在。
所以现在我尝试更新所有的库和依赖项,但是没有用。
问题只出在文本上,它的长度超过3999个字符。较短的文本没有问题。
我还尝试将此条件放在onClickListener之外,因此首先准备文本:

if (history.length() > 3999) {
String var = fromHtml(history.substring(0, 3999)).toString(); 
String var2 = fromHtml(history.substring(3999)).toString();                                                                                }

然后在onClickListener中调用TTS两次

ConvertTextToSpeech(var, "test");
ConvertTextToSpeech(var2, "test");

private void ConvertTextToSpeech(String history, String par) {
        Bundle params = new Bundle();
        params.putString(KEY_PARAM_UTTERANCE_ID, "");
        tts.speak(history, TextToSpeech.QUEUE_ADD, params, par);
    }

但我有同样的问题,这个解决方案没有帮助。
我以为问题是我在彼此之后立即调用两个ConvertTextToSpeech,但即使我删除了第二个,问题也存在。
所以可以肯定的是,问题是与较长的文本,但我找不到解决方案,为什么它开始发生。我检查了许多设备,同样的问题无处不在。
唯一有用的方法是创建更小的文本块:

for (int a=1; a <= history.length(); a+=100) {
if((history.length() - (a + 100)) > 0) {ConvertTextToSpeech(history.substring(a, a+100), "test");}
else {ConvertTextToSpeech(history.substring(a), "test");}

然而,这会导致在说语块之间出现明显的停顿,通常也会在单词内部出现停顿,所以这不是一个好的解决方案。

jm81lzqq

jm81lzqq1#

好吧,所以即使谷歌TTS的最大限制是3999个字符,由于某种原因,它开始有问题,也与约3000个字符。不知道为什么会发生,但它只是发生了没有任何代码更改对我来说。似乎是一个问题有关谷歌TTS。
因此,在我的例子中,文本块由一个分隔线<br>分隔,并且我知道每个块不超过1000-2000个字符,我现在这样拆分所有文本:

String[] parts = history.split("<br>");
for(String part: parts) {ConvertTextToSpeech(part, "test");}

所以现在这对任何长度的文本都有效。问题解决了。

相关问题