Android TTS文本超过4k字符不播放

时间:2012-11-18 12:51:50

标签: android text-to-speech android-4.2-jelly-bean

我有时使用TextToSpeech播放一些长文本,我注意到Android 4.1.2因为文本超过4000个字符,所以它不会播放。

我没有收到任何错误,但文字不会播放。到目前为止,我只能在Android 4.1.2(三星Galaxy Nexus,Nexus7)上重现这一点。

这是4.1.2中的错误还是正常的(虽然我没有找到有关此行为的任何文档)?

此外,我发现了一个帖子:onUtteranceCompleted() lost if TTS received is too long表示文本超过4000个字符的不同问题。

编辑:我尝试将我的字符串拆分为4k长度的块,然后使用TTS将其发送到QUEUE_ADD,我遇到了另一个bug:{ {1}}不起作用,而是刷新现有队列,只播放最后一个块。

EDIT2 :这是我对QUEUE_ADD

的电话
TTS

3 个答案:

答案 0 :(得分:8)

TtsService.java中的

MAX_SPEECH_ITEM_CHAR_LENGTH = 4000,在4.1上我看到代码中有警告:

    @Override
    public boolean isValid() {
        if (mText == null) {
            Log.wtf(TAG, "Got null text");
            return false;
        }
        if (mText.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH) {
            Log.w(TAG, "Text too long: " + mText.length() + " chars");
            return false;
        }
        return true;
    }

看起来像2.3分割文本而不是,所以你的代码应该在android< 4.1而不是更新(我不知道什么时候拆分),相反你有相反的:)这有点奇怪

答案 1 :(得分:3)

4.4.2没问题......我把这样的字符串分开了......

//textToSpeech can only cope with Strings with < 4000 characters
int dividerLimit = 3900;
if(textForReading.length() >= dividerLimit) {
    int textLength = textForReading.length();
    ArrayList<String> texts = new ArrayList<String>();
    int count = textLength / dividerLimit + ((textLength % dividerLimit == 0) ? 0 : 1);
    int start = 0;
    int end = textForReading.indexOf(" ", dividerLimit);
    for(int i = 1; i<=count; i++) {
        texts.add(textForReading.substring(start, end));
        start = end;
        if((start + dividerLimit) < textLength) {
            end = textForReading.indexOf(" ", start + dividerLimit);
        } else {
            end = textLength;
        }
    }
    for(int i=0; i<texts.size(); i++) {
        textToSpeech.speak(texts.get(i), TextToSpeech.QUEUE_ADD, null);
    }
} else {
    textToSpeech.speak(textForReading, TextToSpeech.QUEUE_FLUSH, null);
}

答案 2 :(得分:2)

我的解决方案是使用onUtteranceCompleted(String utteranceId)知道第一个块何时完成,然后将下一个块提供给TextToSpeech,直到它们全部完成。

@Override
public void onInit(int status) { //On TTS init
    //guava Splitter
    mChunks=Lists.newLinkedList(Splitter.fixedLength(3999).split(mExtractedText));
    mTTS.setOnUtteranceCompletedListener(this);
    playNextChunk();
}

private void playNextChunk(){
    HashMap<String, String> params = new HashMap<String, String>();
    params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, ""+mChunks.size());
    mTTS.speak(mChunks.poll(), TextToSpeech.QUEUE_FLUSH, params);
}

@Override
public void onUtteranceCompleted(String utteranceId) {
    playNextChunk();
}