【问题标题】:Android TTS text longer than 4k chars not playing超过 4k 字符的 Android TTS 文本无法播放
【发布时间】:2012-11-18 12:51:50
【问题描述】:

我有时使用TextToSpeech 播放一些长文本,我注意到由于Android 4.1.2 如果文本长度超过4000 个字符,它不会播放。

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

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

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

编辑: 我尝试将我的字符串拆分为 4k 长度的块,然后使用 QUEUE_ADD 将其发送到 TTS,我遇到了另一个 bugQUEUE_ADD 不起作用,相反,它会刷新现有队列,并且只播放最后一个块。

EDIT2:这是我给TTS的电话

mTTS.speak(longText, TextToSpeech.QUEUE_FLUSH, null);

【问题讨论】:

  • 传递字符串的 api 调用是什么?或许android源码可以解释更多

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


【解决方案1】:

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

【讨论】:

【解决方案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();
}

【讨论】:

  • 老兄,我有 10k+ 个字符,所以 tts 只能在第一个 4k 上工作,在完成 4k 后,它想开始下一个 4k,就像它必须做的那样。怎么做。我无法得到你的代码逻辑老兄。
【解决方案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);
}

【讨论】:

    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 2023-03-13
    • 2013-10-19
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多