2012-11-18 37 views
2

我使用TextToSpeech有時會播放一些長文字,而且我注意到,如果文字長度超過4000個字符,它就不會播放,因爲Android 4.1.2Android TTS文字長度超過4k字符不能播放

我沒有收到任何錯誤,但文字不會播放。到現在爲止,我只能在Android 4.1.2(Samsung Galaxy Nexus,Nexus7)上重現這一點。

這是一個錯誤,只是在4.1.2或這是正常的(雖然我沒有找到關於這種行爲的任何文件)?

此外,我發現一個帖子:onUtteranceCompleted() lost if TTS received is too long這表明文本超過4000個字符的不同問題。

編輯:我試圖分裂成4K長塊我的字符串,並使用QUEUE_ADD其發送到TTS和我遇到另一個bug傳來:QUEUE_ADD不工作,而是刷新現有的隊列中,只有最後一個塊得到玩。

EDIT2:這是我的呼籲TTS

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

有什麼API調用傳遞字符串?也許Android的源代碼可以解釋更多 – sherpya

+0

編輯我的問題 –

回答

7

MAX_SPEECH_ITEM_CHAR_LENGTH = 4000 TtsService.java,對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而不是更新(我不知道什麼時候拆分),而你有相反的:)這有點奇怪

+0

這裏是代碼http://www.java2s.com/Open-Source/Android/App/eyes-free/com/google/tts/TTSService.java.htm – sherpya

+0

至少奇怪(這是沒有記錄)。並且QUEUE_ADD也不起作用...所以我不能在4.1以上播放更長的文本... –

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(); 
} 
+0

哥們我有10k +字符,所以tts只會在第一個4k工作,在完成4k之後,它想要開始下一個4k它必須做的。如何做到這一點,我不能讓你的代碼邏輯花花公子。 –

2

沒問題的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); 
} 
相關問題