我正在尝试使用Android文字转语音来说出大量文字。我使用默认的Google语音引擎。下面是我的代码。
public class Talk extends Activity implements TextToSpeech.OnInitListener { private ImageView playBtn; private EditText textField; private TextToSpeech tts; private boolean isSpeaking = false; private String finalText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_talk); //Intialize the instance variables playBtn = (ImageView)findViewById(R.id.playBtn); textField = (EditText)findViewById(R.id.textField); //Resister the listeners playBtn.setOnClickListener(new PlayBtnAction()); //Other things tts = new TextToSpeech(this,this); //Get the web page text if called from Share-Via if (Intent.ACTION_SEND.equals(getIntent().getAction())) { new GetWebText().execute(""); } } //This class will execute the text from web pages private class GetWebText extends AsyncTask<String,Void,String> { @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub String text = getIntent().getStringExtra(Intent.EXTRA_TEXT); String websiteText = ""; try { //Create a URL for the desired page URL url = new URL(text); // Read all the text returned by the server BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); String str; StringBuffer strBuffer = new StringBuffer(""); while ((str = in.readLine()) != null) { strBuffer.append(str+"\n"+"\n"); } in.close(); String html = strBuffer.toString(); Document doc = Jsoup.parse(html); websiteText = doc.body().text(); // "An example link" //Toast.makeText(this, websiteText, Toast.LENGTH_LONG).show(); } catch(Exception e) { Log.e("web_error", "Error in getting web text",e); } return websiteText; } @Override protected void onPostExecute(String result) { textField.setText(result); } } } //Class to speak the text private class PlayBtnAction implements OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub if(!isSpeaking) { isSpeaking = true; //speak(textField.getText().toString()); finalText = textField.getText().toString(); new SpeakTheText().execute(finalText); isSpeaking = false; } else { isSpeaking = false; tts.stop(); } } } @Override public void onInit(int status) { // TODO Auto-generated method stub if(status==TextToSpeech.SUCCESS) { int result = tts.setLanguage(Locale.UK); if(result==TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Toast.makeText(this, "Language Not Supported", Toast.LENGTH_LONG).show(); } } } //This class will speak the text private class SpeakTheText extends AsyncTask<String,Void,String> { @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub tts.speak(params[0], TextToSpeech.QUEUE_FLUSH, null); return null; } } @Override public void onDestroy() { if(tts!=null) { tts.stop(); tts.shutdown(); } super.onDestroy(); } }
但是这里的问题是,当有大量文本(假设您已从网页中提取文本)时,TTS无法读取它。如果我删除了大部分文本,它将读取它。为什么会这样呢?
当我要阅读大文本时,LogCat会显示如下内容
10-11 07:26:05.566: D/dalvikvm(2638): GC_CONCURRENT freed 362K, 44% free 3597K/6312K, paused 17ms+8ms, total 93ms
字符串长度不得超过docs中预定义的长度:
参量 text 要说的文字字符串。不得超过getMaxSpeechInputLength()个字符。
参量
text 要说的文字字符串。不得超过getMaxSpeechInputLength()个字符。
getMaxSpeechInputLength()每个设备的返回值可能会有所不同,但根据AOSP来源( 高达 4000) :
getMaxSpeechInputLength()
/** * Limit of length of input string passed to speak and synthesizeToFile. * * @see #speak * @see #synthesizeToFile */ public static int getMaxSpeechInputLength() { return 4000; }
尽量不要超过该限制:将输入文本的长度与该值进行比较,并在必要时分成多个部分。