Javafx:如何在动画文本上进行文本到语音转换;我已经在文本上应用了打字机效果以制作动画文本,现在我希望它能按键入的单词逐字朗读。附言使用“ FreeTTS是语音合成引擎”的文本到语音iam
这是我的项目的代码段
public void AnimattedTextToSpeech()
{
// Text to Speech
Voice voice;
VoiceManager vm=VoiceManager.getInstance();
voice=vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str="Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
但是它正在打字时说每个字符。但是我希望它一个字一个字地讲。
答案 0 :(得分:2)
这有效,但似乎您需要在其他线程上运行语音。
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* @author blj0011
*/
public class FreeTTTS extends Application
{
@Override
public void start(Stage primaryStage)
{
TextArea textArea = new TextArea();
// Text to Speech
Voice voice;
VoiceManager vm = VoiceManager.getInstance();
voice = vm.getVoice("kevin16");
voice.allocate();
// TypeWritter Effect to the text
String str = "Welcome! This is the Lesson number one";
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
AtomicInteger startIndex = new AtomicInteger();
AtomicInteger endIndex = new AtomicInteger();
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() >= str.length()) {
timeline.stop();
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
textArea.appendText(Character.toString(str.charAt(i.get())));
if (str.charAt(i.get()) == ' ') {
if (endIndex.get() == 0) {
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
else {
startIndex.set(endIndex.get());
endIndex.set(i.get());
String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
System.out.println(word);
voice.speak(word);
}
}
i.set(i.get() + 1);
}
});
//voice.speak(str);
StackPane root = new StackPane(textArea);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
//voice.speak("Hello World");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
答案 1 :(得分:0)
我想您应该将文本分成字符串,并在为每个字符串启动TypeWritter效果时启动TTS。 像这样:
String str1 = "Welcome! This is the Lesson number one";
String[] temp = str1.split(" ");
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
for (String str : temp) {
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
if (i.get() > str.length()) {
timeline.stop();
} else {
textArea.setText(str.substring(0, i.get()));
i.set(i.get() + 1);
textArea.requestFocus();
textArea.end();
}
});
voice.speak(str);
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}