文字转语音中断
Text To Speech breaks
我正在使用这个代码说话
Sample 1:
speech.speak("Hello ABCD WELCOME ABCD", TextToSpeech.QUEUE_FLUSH,
null);
如果代码按照示例 1 中所示的顺序排列,则此代码没有问题。如果我将其分成两个字符串,如示例 2 中所示,它会破坏说话,因为它只说 hell 或 hello 然后说欢迎abcd.
Sample 2:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_FLUSH,
null);
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_FLUSH,
null);
我想要如果 speech.isSpeaking(),那么它应该等待完成 HELLO ABCD,完成后它应该说 WELCOME ABCD。
在 hashmap 或 arraylist 中使用字符串的替代方法。还有其他解决办法吗?
我以前没试过TextToSpeech
,但是看到你做的代码是一个接一个运行,第二个speech.speak()
值会超过运行第一个作为您设置的队列代码是 TextToSpeech.QUEUE_FLUSH。根据它的文档:
Queue mode where all entries in the playback queue (media to be played and text to be synthesized) are dropped and replaced by the new entry.
所以我觉得适合你用的是TextToSpeech.QUEUE_ADD:
Queue mode where the new entry is added at the end of the playback queue.
有几个选项。有些人有自己的注意事项。
首先,您可以使用 TextToSpeech.QUEUE_ADD
而不是 TextToSpeech.QUEUE_FLUSH
。
speech.speak("Hello ABCD", TextToSpeech.QUEUE_ADD, null);
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_ADD, null);
这会将任何新文本添加到队列中,但会在开始说出任何新文本之前完全说出已经存在的内容。如果您不经常向队列中添加新文本,这很好。否则队列可能会变得太满,而 TTS 引擎的通话速度不够快,无法跟上。
你可以使用 speech.isSpeaking()
但如何巧妙地使用它呢?循环等待不是很好的编程:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_FLUSH, null);
while (speech.isSpeaking()) {
// Freezes the application.
}
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_FLUSH, null);
这在后台线程中还可以,但最好完全忘记这个想法。
也可以使用 UtteranceProgressListener 在 "utterance" 完成时得到通知——基本上是在 speak()
方法调用中给出的文本被说出时。这可能是一种聪明的方式,只有在之前的文本完全说完之后才开始说出新的文本。
监听器可以添加为匿名内部 class:
speech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
// Speaking started.
}
@Override
public void onDone(String utteranceId) {
// Speaking stopped.
}
@Override
public void onError(String utteranceId) {
// There was an error.
}
});
监听器不是很有用,除非在 speak()
方法调用中给出 utteranceId
。否则您将无法确切知道说出了哪些文本以及接下来应该说出的内容。当然,您可以使用自己的一些成员变量来跟踪它,但是已经为您提供了一个内置机制:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_ADD, "hello");
现在这个 speak()
操作被识别为 "hello"。只有在 "Hello ABCD" 被说出来后,我们才能用这个来说 "Welcome ABCD":
speech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
// Speaking started.
}
@Override
public void onDone(String utteranceId) {
// Speaking stopped.
if (utteranceId.equals("hello")) {
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_ADD, "welcome");
}
}
@Override
public void onError(String utteranceId) {
// There was an error.
}
});
听者当然应该在说任何话之前设置好。
这是基本思想,您是否应该使用 UtteranceProgressListener
取决于您正在开发的应用程序类型。如果有很多 "utterances" 需要发言和监控,它确实会变得有点复杂。如果您发现 TTS 队列填满的问题,您可以研究这种方法。
当然,如果您的文本位于 ArrayList
中,并且您使用文本的索引作为话语 ID,并在听众中选择要说出的下一个文本,那么这当然可以以更智能的方式进行基于索引。
我正在使用这个代码说话
Sample 1:
speech.speak("Hello ABCD WELCOME ABCD", TextToSpeech.QUEUE_FLUSH,
null);
如果代码按照示例 1 中所示的顺序排列,则此代码没有问题。如果我将其分成两个字符串,如示例 2 中所示,它会破坏说话,因为它只说 hell 或 hello 然后说欢迎abcd.
Sample 2:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_FLUSH,
null);
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_FLUSH,
null);
我想要如果 speech.isSpeaking(),那么它应该等待完成 HELLO ABCD,完成后它应该说 WELCOME ABCD。
在 hashmap 或 arraylist 中使用字符串的替代方法。还有其他解决办法吗?
我以前没试过TextToSpeech
,但是看到你做的代码是一个接一个运行,第二个speech.speak()
值会超过运行第一个作为您设置的队列代码是 TextToSpeech.QUEUE_FLUSH。根据它的文档:
Queue mode where all entries in the playback queue (media to be played and text to be synthesized) are dropped and replaced by the new entry.
所以我觉得适合你用的是TextToSpeech.QUEUE_ADD:
Queue mode where the new entry is added at the end of the playback queue.
有几个选项。有些人有自己的注意事项。
首先,您可以使用 TextToSpeech.QUEUE_ADD
而不是 TextToSpeech.QUEUE_FLUSH
。
speech.speak("Hello ABCD", TextToSpeech.QUEUE_ADD, null);
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_ADD, null);
这会将任何新文本添加到队列中,但会在开始说出任何新文本之前完全说出已经存在的内容。如果您不经常向队列中添加新文本,这很好。否则队列可能会变得太满,而 TTS 引擎的通话速度不够快,无法跟上。
你可以使用 speech.isSpeaking()
但如何巧妙地使用它呢?循环等待不是很好的编程:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_FLUSH, null);
while (speech.isSpeaking()) {
// Freezes the application.
}
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_FLUSH, null);
这在后台线程中还可以,但最好完全忘记这个想法。
也可以使用 UtteranceProgressListener 在 "utterance" 完成时得到通知——基本上是在 speak()
方法调用中给出的文本被说出时。这可能是一种聪明的方式,只有在之前的文本完全说完之后才开始说出新的文本。
监听器可以添加为匿名内部 class:
speech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
// Speaking started.
}
@Override
public void onDone(String utteranceId) {
// Speaking stopped.
}
@Override
public void onError(String utteranceId) {
// There was an error.
}
});
监听器不是很有用,除非在 speak()
方法调用中给出 utteranceId
。否则您将无法确切知道说出了哪些文本以及接下来应该说出的内容。当然,您可以使用自己的一些成员变量来跟踪它,但是已经为您提供了一个内置机制:
speech.speak("Hello ABCD", TextToSpeech.QUEUE_ADD, "hello");
现在这个 speak()
操作被识别为 "hello"。只有在 "Hello ABCD" 被说出来后,我们才能用这个来说 "Welcome ABCD":
speech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
// Speaking started.
}
@Override
public void onDone(String utteranceId) {
// Speaking stopped.
if (utteranceId.equals("hello")) {
speech.speak("Welcome ABCD", TextToSpeech.QUEUE_ADD, "welcome");
}
}
@Override
public void onError(String utteranceId) {
// There was an error.
}
});
听者当然应该在说任何话之前设置好。
这是基本思想,您是否应该使用 UtteranceProgressListener
取决于您正在开发的应用程序类型。如果有很多 "utterances" 需要发言和监控,它确实会变得有点复杂。如果您发现 TTS 队列填满的问题,您可以研究这种方法。
当然,如果您的文本位于 ArrayList
中,并且您使用文本的索引作为话语 ID,并在听众中选择要说出的下一个文本,那么这当然可以以更智能的方式进行基于索引。