Как узнать, когда закончится TTS?
Я реализую приложение Interactive Voice Response на Android. Я хотел бы знать, как определить, когда tts.speak()
Функция завершила разговор, поэтому я могу вызвать функцию распознавания речи.
8 ответов
public class TTSActivity extends Activity implements OnInitListener, OnUtteranceCompletedListener, ... {
private TextToSpeech mTts;
...........
private void speak(String text) {
if(text != null) {
HashMap<String, String> myHashAlarm = new HashMap<String, String>();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "SOME MESSAGE");
mTts.speak(text, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
}
}
// Fired after TTS initialization
public void onInit(int status) {
if(status == TextToSpeech.SUCCESS) {
mTts.setOnUtteranceCompletedListener(this);
}
}
// It's callback
public void onUtteranceCompleted(String utteranceId) {
Log.i(TAG, utteranceId); //utteranceId == "SOME MESSAGE"
}
...........
}
Прочитайте хороший учебник
Начиная с уровня API 15 метод setOnUtteranceCompletedListener устарел. Вместо этого используйте setOnUtteranceProgressListener.
Я нашел фрагмент кода ( здесь), который позволил мне легко узнать, когда закончится преобразование текста в речь:
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onDone(String utteranceId) {
// Log.d("MainActivity", "TTS finished");
}
@Override
public void onError(String utteranceId) {
}
@Override
public void onStart(String utteranceId) {
}
});
} else {
Log.e("MainActivity", "Initilization Failed!");
}
}
Чтобы узнать, когда TTS закончится, вы должны позвонить в setOnUtteranceProgressListener
который имеет 3 метода обратного вызова onStart
,onDone
а также onError
затем включите идентификатор высказывания в метод речи
Фрагмент кода
textToSpeech=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
int result=textToSpeech.setLanguage(Locale.ENGLISH);
if (result==TextToSpeech.LANG_MISSING_DATA||result==TextToSpeech.LANG_NOT_SUPPORTED){
Log.i("TextToSpeech","Language Not Supported");
}
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
Log.i("TextToSpeech","On Start");
}
@Override
public void onDone(String utteranceId) {
Log.i("TextToSpeech","On Done");
}
@Override
public void onError(String utteranceId) {
Log.i("TextToSpeech","On Error");
}
});
}else {
Log.i("TextToSpeech","Initialization Failed");
}
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,null,TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
}
Я заметил, что есть люди, имеющие проблемы с использованием TextToSpeech, чтобы спросить, что решение для вас
Как узнать, когда закончится TTS? без использования setOnUtteranceCompletedListener
public void isTTSSpeaking(){
final Handler h =new Handler();
Runnable r = new Runnable() {
public void run() {
if (!tts.isSpeaking()) {
onTTSSpeechFinished();
}
h.postDelayed(this, 1000);
}
};
h.postDelayed(r, 1000);
}
Попробуйте следующий код, который показывает тост после завершения TTS. Замените тост своими собственными действиями.
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener{
private boolean initialized;
private String queuedText;
private String TAG = "TTS";
private TextToSpeech tts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this /* context */, this /* listener */);
tts.setOnUtteranceProgressListener(mProgressListener);
speak("hello world");
}
public void speak(String text) {
if (!initialized) {
queuedText = text;
return;
}
queuedText = null;
setTtsListener(); // no longer creates a new UtteranceProgressListener each time
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private void setTtsListener() {
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
initialized = true;
tts.setLanguage(Locale.ENGLISH);
if (queuedText != null) {
speak(queuedText);
}
}
}
private abstract class runnable implements Runnable {
}
private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
} // Do nothing
@Override
public void onError(String utteranceId) {
} // Do nothing.
@Override
public void onDone(String utteranceId) {
new Thread()
{
public void run()
{
MainActivity.this.runOnUiThread(new runnable()
{
public void run()
{
Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();
}
});
}
}.start();
}
}; }
используйте этот прослушиватель:
textToSpeech.setOnUtteranceProgressListener(
object : UtteranceProgressListener() {
override fun onStart(utteranceId: String?) {
Handler(Looper.getMainLooper()).post {
//if you want update ui you should use handler
}
}
override fun onDone(utteranceId: String?) {
Handler(Looper.getMainLooper()).post {
//if you want update ui you should use handler
}
}
@Deprecated("Deprecated in Java")
override fun onError(utteranceId: String?) {
Handler(Looper.getMainLooper()).post {
//if you want update ui you should use handler
}
}
}
)
С помощью этого кода я решил проблему. Я хотел, чтобы кнопка «Пуск» горела, пока кто-то говорил. Может быть, это поможет кому-то.
public void _tts_speak_lenght() {
t2 = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (TTS.isSpeaking()) {
isSpeaking = true;
}
else {
if (!TTS.isSpeaking()) {
t2.cancel();
isSpeaking = false;
imgBtn_startReader.setImageResource(R.drawable.ic_start_off);
}
}
}
});
}
};
_timer.scheduleAtFixedRate(t2, (int)(0), (int)(100));
}
Использовать SpeakableListener, когда текст, чтобы говорить.
private volatile boolean finished;
private SpeakableListener listener = new SpeakableListener() {
@Override
public void markerReached(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void speakableCancelled(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void speakableEnded(SpeakableEvent arg0) {
TestSpeaker.this.finished = true;
}
@Override
public void speakablePaused(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void speakableResumed(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void speakableStarted(SpeakableEvent arg0) {
TestSpeaker.this.finished = false;
}
@Override
public void topOfQueue(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void wordStarted(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
};
/** Speak the following string. */
public void sayIt(String str) {
System.out.print(" " + str + " ");
/* The the synthesizer to speak. */
synthesizer.speakPlainText(str, listener);