I am trying to speak out large amount of text using Android Text To Speech. I using default Google speech engine. Below is my code.
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();
}
}
But the issue here is, when there is a large chunk of text (lets say you have extracted text from a web page) the TTS fails to read it. If I remove most of the text, then it will read it. Why is this happening?
When I am about to read the large text, the LogCat however display something like this
10-11 07:26:05.566: D/dalvikvm(2638): GC_CONCURRENT freed 362K, 44% free 3597K/6312K, paused 17ms+8ms, total 93ms
In case someone might find this helpful. When you split the large text into strings, do not set the length of each string to the exact value of getMaxSpeechInputLength()
. Subtract the string length by 1. Otherwise, only the last chunk of string could be read by TTS.
int length = toSpeech.getMaxSpeechInputLength() - 1;
Iterable<String> chunks = Splitter.fixedLength(length).split(largeText);
Lists.newArrayList(chunks);
Use this code...Working for any file .. just send the string to speech function..
private void speech(String charSequence) {
int position ;
int sizeOfChar= charSequence.length();
String testStri= charSequence.substring(position,sizeOfChar);
int next = 20;
int pos =0;
while(true) {
String temp="";
Log.e("in loop", "" + pos);
try {
temp = testStri.substring(pos, next);
HashMap<String, String> params = new HashMap<String, String>();
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, temp);
engine.speak(temp, TextToSpeech.QUEUE_ADD, params);
pos = pos + 20;
next = next + 20;
} catch (Exception e) {
temp = testStri.substring(pos, testStri.length());
engine.speak(temp, TextToSpeech.QUEUE_ADD, null);
break;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With