简体   繁体   English

Android 文字转语音开头语音失真

[英]Android text to speech voice distortion at the beginning

In Android app I have a text, which after the user press a button, it will be spoken by TTS:在 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);
    }

The stuff about TTS:关于 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");}

This worked for years without problems, the TTS read the text even if it was short, or more than 3999 characters.这多年来一直没有问题,TTS 阅读文本,即使它很短,或超过 3999 个字符。 Suddenly a few months ago (without any change from my side in application) when it starts to speak longer text, the first 3-4 words are distorted and hardly understandable in every text.几个月前突然(我这边的应用程序没有任何变化)当它开始说出更长的文本时,前 3-4 个单词在每个文本中都被扭曲并且几乎无法理解。

Looks like as it is doing something in the background while it is reading the text in the same time.看起来它在阅读文本的同时在后台做某事。

Not sure what happened, because I dod no change in my code and it worked till now.不确定发生了什么,因为我没有更改我的代码并且它一直有效到现在。

So now I tried to update all libraries and dependencies, but it didn't help.所以现在我尝试更新所有库和依赖项,但没有帮助。

The problem is only with the text, which is longer than 3999 chars.问题仅在于文本,它超过 3999 个字符。 The shorter text is working with no issues.较短的文本没有问题。

I also tried to put this condition outside of onClickListener, so the text is prepared first:我也尝试将这个条件放在 onClickListener 之外,所以先准备文本:

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

and then in onClickListener I just call the TTS twice:然后在 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);
    }

But I have the same issue, this solution didn't helped.但我有同样的问题,这个解决方案没有帮助。

I thought the issue is that I call immediately two ConvertTextToSpeech after each other, but even if I remove the second one, the problem is there.我认为问题是我立即调用了两个 ConvertTextToSpeech,但即使我删除了第二个,问题仍然存在。

So definitely, the problem is with the longer text, but I can't find the solution why it started to happen.所以肯定地,问题出在较长的文本上,但我找不到它开始发生的原因的解决方案。 I checked this on many devices, same issue everywhere.我在很多设备上检查过这个,到处都是同样的问题。

The only thing that helps is to create much smaller chunks of text:唯一有帮助的是创建更小的文本块:

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");}

However, this causes a noticeable pause between speaking the chunks, often also inside the word, so this is not a good solution.然而,这会导致在说出组块之间出现明显的停顿,通常也在单词内部,因此这不是一个好的解决方案。

Ok, so even if the max limit for google TTS is 3999 characters, for some reason it started to have issues also with ca.好的,所以即使谷歌 TTS 的最大限制是 3999 个字符,出于某种原因它也开始出现问题。 3000 characters. 3000 个字符。 Not sure why it happened, but it just happened without any code change on my side.不知道为什么会发生,但它只是在我这边没有任何代码更改的情况下发生。 Seems an issue related to google TTS.似乎是与 google TTS 相关的问题。

So, as in my case the text blocks are separated by a break line <br> , and I know each block has no more than 1000-2000 chars, I now splitted all my text like this:因此,在我的例子中,文本块由换行符<br>分隔,并且我知道每个块不超过 1000-2000 个字符,我现在将所有文本拆分如下:

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

So now this is working for any text with any length.所以现在这适用于任何长度的任何文本。 Problem solved.问题解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM