无法在Android中执行文本到语音的转换

时间:2019-03-04 13:53:20

标签: java android text-to-speech

当我设置tts.speak时,使用s字符串变量可以很好地工作。但是,当我使用通过函数调用传递的文本时,它不起作用。这两个字符串变量完全相同

private void speek(final String text){
    tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if(status == TextToSpeech.SUCCESS){
                int isTTs = tts.setLanguage(Locale.ENGLISH);
                if(isTTs == TextToSpeech.LANG_MISSING_DATA || isTTs == TextToSpeech.LANG_NOT_SUPPORTED){
                    System.out.println("-----------------------------       ++   not working    " + isTTs);
                    System.out.println("-----------------------------       ++   " + TextToSpeech.LANG_MISSING_DATA + "     " + TextToSpeech.LANG_NOT_SUPPORTED);
                }else{
                    System.out.println("-----------------------------       ++   working yay    " + text);
                    tts.setPitch(0.9f);
                    tts.setSpeechRate(0.8f);
                    // if i use the variable s it works
                    String t = "Chapter 1 ...";
                    tts.speak(t, TextToSpeech.QUEUE_ADD, null);
                    // howevet this does not
                    tts.speak(text, TextToSpeech.QUEUE_ADD, null);
                }
            }
        }
    });

}

TextToSpeech tts;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_read_novel);
    // call async task
    new getPage().execute(b.getString("link"));

}


private class getPage extends AsyncTask<String, String, String> {
    @Override
    protected String doInBackground(String... urls) {}

    @Override
    protected void onPostExecute(String result) {
        // call speak function and pass string to be spoken
        speek(result);
    }
}

3 个答案:

答案 0 :(得分:3)

没有您的日志或对函数的调用,我们无法真正找出问题所在。

我的第一个猜测是text可能为null(如果您在日志中没有看到NPE,则为空),从而触发speak方法中的异常或生成空白语音。添加一个空检查,一个空检查,并查看该调用是否具有您的speek函数的正确签名。

在这种情况下,onPostExecute中的参数可能为空。

您可能还需要检查this documentation,以查看是否还有其他限制。

答案 1 :(得分:1)

首先,您可以在调用text方法以检查传递给该方法的值之前尝试打印speak()

我们不知道您的doInBackground()方法的内容,但是也许您在传递错误的值?在您的doInBackground()方法中,您应该返回将传递给onPostExecute()的值。

urls中的

doInBackground是Java varargs机制,因此urls[0]是传递给execute()的第一个参数。

执行时:

new getPage().execute("aaa", "bbb", "ccc");

doInBackground中:

  • urls[0] => "aaa"
  • urls[1] => "bbb"
  • urls[2] => "ccc"

您可以尝试返回第一个参数(因此urls[0]):

@Override
protected String doInBackground(String... urls) {
    // return value from parmeters
    return urls[0];
}

答案 2 :(得分:-5)

原来的问题是,如果您的字符串包含4000个以上的字符,则可以传递给文本到语音引擎的最大char大小约为4000个

// this will not work 
tts.speak(text, TextToSpeech.QUEUE_ADD, null);

为了使其工作,添加一个setOnUtteranceProgressListener并使用onDone()遍历字符串

// working code
int char_count = 3000;
int start = 0;
int end = char_count;
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "UniqueID");
tts.speak(text.substring(start, end), TextToSpeech.QUEUE_ADD, map);

tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                        @Override
                        public void onStart(String s) {}

                        @Override
                        public void onDone(String s) {
                            start = end;
                            end+= char_count;
                            end = text.indexOf(" ", end);

                            if(end >= text.length() || end == -1){
                                end = text.length();
                            }if(start >= text.length()){
                                System.out.println("end of text");
                            }else {
                                speek();
                            }

                        }

                        @Override
                        public void onError(String s) {}
                    });