Java runtime.exec process hangs - java

So basically my program creates a process of ffplay(program based on ffmpeg that plays audio and video), but it hangs(have to force kill the program, loading wheel of death, etc.) about 15 seconds into playing. What is also interesting is that I call it with -autoexit which should kill the program at the end of the audio or video, but it doesn't close.
import java.lang.Runtime;
import java.lang.Process;
import java.io.IOException;
public class FFPlay
{
Process proc;
public FFPlay(String fileToPlay, String fileName)
{
try
{
String[] command = {"/Users/myusername/Documents/Java Projects/SwingTest/ffplay", "-window_title", fileName, "-x", "500", "-y", "500", "-autoexit", fileToPlay};
proc = Runtime.getRuntime().exec(command);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
So what am I doing wrong? Is this a bad method for executing binaries? I don't know much about the Runtime and Process classes to begin with.
Edit: Method that calls the above class
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
{
int index = songList.locationToIndex(e.getPoint());
FFPlay player = new FFPlay(songList.getModel().getElementAt(index).toString(),songList.getModel().getElementAt(index).getName());
}
}

Related

Return to main after thread has ended

I am currently messing around with facial recognition and try to capture photos form my webcam. I am adapting this tutorial to automatically name and save the taken picture. Note that this Code is called from the main() the funtion it self is implemented in another class. Up and until I stop the thread with interrupt() it works. Afterwards the picture is frozen in the GUI and the system doesn't seem to return into the class where I operate over my GUI.
To make myself clear: I want to capture a picture from my webcam and replace the former stream from my webcam with said earlier captured picture. Up and until I capture the picture and interrupt the thread the code works. Aftwards it is stuck.
I experiemented with pulling the Thread into the ActionListener of the CaptureButton but that failed because the main GUI element was not accessible which is courious given that it is defined as public.
It does however throw in the course of compilation some warnings - tho I must admit that I have no clue what they mean:
[ WARN:0] global C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap_msmf.cpp (376) `anonymous-namespace'::SourceReaderCB::OnReadSample videoio(MSMF): OnReadSample() is called with error status: -1072873821
[ WARN:0] global C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap_msmf.cpp (388) `anonymous-namespace'::SourceReaderCB::OnReadSample videoio(MSMF): async ReadSample() call is failed with error status: -1072873821
[ WARN:1] global C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap_msmf.cpp (1021) CvCapture_MSMF::grabFrame videoio(MSMF): can't grab frame. Error: -1072873821
Exception in thread "Thread-0" CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.5.2) C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\imgcodecs\src\loadsave.cpp:896: error: (-215:Assertion failed) !image.empty() in function 'cv::imencode'
]
at org.opencv.imgcodecs.Imgcodecs.imencode_1(Native Method)
at org.opencv.imgcodecs.Imgcodecs.imencode(Imgcodecs.java:510)
at GUI.FaceRecognition.startCamera(FaceRecognition.java:129)
at main$1$1.run(main.java:19)
at java.base/java.lang.Thread.run(Thread.java:834)
[ WARN:2] global C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Thread vorbei
I have written my code rather amateurish of that I am sure and I reckon I could use something like callable() but am unsure who to use that. I also do not know how to replicate my problem outside of chucking my entire project around the internet but I can however provide the code of my modifications:
for the funtion itself
public boolean startCamera(){
capture= new VideoCapture(0);
image=new Mat();
byte[] imageData;
ImageIcon icon;
String name = null;
boolean echo = false;
while(true){
capture.read(image);
final MatOfByte buf=new MatOfByte();
Imgcodecs.imencode(".png", image,buf);
imageData= buf.toArray();
icon=new ImageIcon(imageData);
Feed.setIcon(icon);
if(trigger==true){
name="Recognition";
Imgcodecs.imwrite("src/"+name+".png",image);
trigger=false; //Auslöser zurücksetzten
}
File kamera=new File("src/Recognition.png");
if(kamera.exists()==true){
//capture.release();
/*try {
Kamera=ImageIO.read(this.getClass().getResourceAsStream("/Recognition.png"));
} catch (IOException e) {
e.printStackTrace();
}*/
return echo=true;
}
}
}
for the main()
import java.awt.*;
import java.io.File;
import java.lang.String;
import GUI.*;
import org.opencv.core.Core;
public class main {
public static void main(String[] args){
FaceRecognition Fenster=new FaceRecognition();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
//FaceRecognition Fenster=new FaceRecognition();
new Thread (new Runnable() {
#Override
public void run() {
Fenster.startCamera();
}
}).start();
//File kamera=new File(("src/Recognition.png"));
}
});
if(Fenster.startCamera()==true){
Thread.currentThread().interrupt();
System.out.println("Thread vorbei");
}
}
}
Please point out where I went wrong or what goes wrong.
Edit:
I have mean while heeded #pveentjers advice and reformed my code (see below). Yet in my main() the IDE proposes to make startCamera static which will not work because startCamera can not be static (or rather elements of it can't). Is there any way to move around this?
the startCamera function
public class startCamera implements Runnable{
private CountDownLatch end;
public startCamera(CountDownLatch one){
this.end=one;
}
#Override public void run(){
try {
capture= new VideoCapture(0);
image=new Mat();
byte[] imageData;
ImageIcon icon;
String name = null;
while(true){
capture.read(image);
final MatOfByte buf=new MatOfByte();
Imgcodecs.imencode(".png", image,buf);
imageData= buf.toArray();
icon=new ImageIcon(imageData);
Feed.setIcon(icon);
if(trigger==true){
name="Recognition";
Imgcodecs.imwrite("src/"+name+".png",image);
trigger=false; //Auslöser zurücksetzten
}
File kamera=new File("src/Recognition.png");
if(kamera.exists()==true){
capture.release();
end.countDown();
/*try {
Kamera=ImageIO.read(this.getClass().getResourceAsStream("/Recognition.png"));
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
}
catch (Exception exception){
}
}
the reformed main()
import java.awt.*;
import java.io.File;
import java.lang.String;
import java.util.concurrent.CountDownLatch;
import GUI.*;
import GUI.FaceRecognition.startCamera;
import org.opencv.core.Core;
public class main {
public static void main(String[] args){
FaceRecognition Fenster=new FaceRecognition();
CountDownLatch mark=new CountDownLatch(1);
startCamera startCamera=new startCamera(mark);
try {
mark.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Might be that I don't the wood for the trees but this the first time I am working with threads.

Java: Console stops working when using javazoom

When I start playing music by javazoom library, console stops answer. I can write anything, but no response.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.advanced.AdvancedPlayer;
public class Main {
public static void men(int i) {
try {
FileInputStream fis = new FileInputStream("Filename.WAV");
AdvancedPlayer player = new AdvancedPlayer(fis);
player.play();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(JavaLayerException e) {
e.printStackTrace();
}
}
public static Scanner scn = new Scanner(System.in);
public static void main(String[] args) {
while(true) {
int i = scn.nextInt();
if(i == 1) {
men(i);
}
if(i == 5) {
System.out.println("i am here");
}
}
}
}
Is there solution? Or javazoom can't play audio and do other things?
I'm not clear what you mean by "console stops answer" and "Javazoom can't play audio and do other things."
You can execute the javazoom play command in its own thread. While that thread runs concurrently, your program will be free to execute other tasks.
Do you know how to create and launch a thread? Here is Oracle's tutorial Processes and Threads.

Execute command displaying console window and also get handle of the process

I am trying to run a command from Java that will start a process that runs for several minutes. I need to just trigger the command and get the process handle and continue with other operations in a loop. At regular intervals, I will have to monitor that the process is still active.
I also need the console window to display to show the output of the process for the user.
Currently, I have tried methods from both Runtime and ProcessBuilder classes to run my command but neither of them has helped me achieve my objective.
Sample code:
//Changing the directory and running Maven exec: java command on the POM file in that directory.
String cmd = "cd C:/Test & mvn exec:java";
String finalCmd = "cmd /c \""+ cmd +"\"";
Process process = Runtime.getRuntime().exec(finalCmd);
Thread.sleep(10);
boolean alive = process.isAlive();
The value of variable alive is True, but I don't see the process got started. When the program execution is complete, only then the process starts and I am not sure why that happens.
Also to display the console window, I found from google that I need to use the below command:
String finalCmd = "cmd /c start cmd.exe /c \"" + cmd + "\"";
However, with this, the process starts immediately but I do not get the process handle as I find the alive variable shows false.
Does someone know how this objective can be achieved? I am ok if it's not possible to do both at the same time but at least I need to get the process execution to start and get the handle to monitor the process state later in my code.
Couple of things that are happening incorrectly here:
We need to pass our command as string tokens to the exec() command
We need to wait for the process to exit with process.waitFor() instead of sleeping, this will block the current thread so if you don't want that you need to execute this in another thread or use an ExecutorService.
Advisable to check the output value of waitFor() to see if our command executed properly (value of 0) or not (any other value,
typically a positive 1 in case of unsuccessful execution)
Optionally (to see the output) we need to redirect the standard OUT and ERR somewhere, say print it to console(), though you could put it to a file some GUI window etc.
So at a minimum the following code should work:
Process process = Runtime.getRuntime().exec(new String[] {"cmd", "/c", "cd", "C:\\dev", "&&", "dir"});
int outputVal = process.waitFor();
boolean alive = process.isAlive();
System.out.format("alive %s, outputVal: %d\n",alive, outputVal);
Further suggestions:
use ProcessBuilder instead of runTime.exec(), it allows more control
and is the recommended way since JDK 1.5
read the inputStream
So the code will look some thing like this:
List<String> cmdList = Arrays.asList("cmd", "/c", "cd", "C:\\dev", "&&", "dir");
ProcessBuilder pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true); //redirect STD ERR to STD OUT
Process process = pb.start();
try (final BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("std-out-line: " + line);
}
}
int outputVal = process.waitFor();
System.out.format("outputVal: %d\n", outputVal);
Since waitFor() is a blocking call, you can execute this in a separate thread or using an executorService. Sample code here:
final StringBuffer outputSb = new StringBuffer();
ExecutorService executorService = null;
try {
executorService = Executors.newSingleThreadExecutor();
final Future<Integer> future = executorService.submit(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
try (final BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line = null;
while ((line = br.readLine()) != null) {
outputSb.append("std-out-line: ");
outputSb.append(line);
outputSb.append('\n');
}
}
int exitValue = process.waitFor();
System.out.format("exitValue: %d\n", exitValue);
return exitValue;
}
});
while (!future.isDone()) {
System.out.println("Waiting for command to finish doing something else..");
Thread.sleep(1 * 1000);
}
int exitValue = future.get();
System.out.println("Output: " + outputSb);
} finally {
executorService.shutdown();
}
Here's a solution that uses WMIC.
public static void main( String[] args ) throws Exception {
// Vars
Process process;
String output;
// Execution
process = Runtime.getRuntime().exec("cmd /c wmic process call create calc.exe | findstr ProcessId");
output = readTrimmedOutput(process.getInputStream());
System.out.println("Output from command: " + output);
// Basic string manipulation to get process id
String str_proc_id = output.split(" = ")[1].replace(";","");
System.out.println("ProcessId is: " + str_proc_id);
// Some thread delay that you can comment/uncomment for testing if running or not
Thread.sleep(5000);
// Finding if process is still running
process = Runtime.getRuntime().exec("cmd /c wmic process get processid | findstr " + str_proc_id);
output = readTrimmedOutput(process.getInputStream());
boolean isRunning = output.contains(str_proc_id);
System.out.println("Is process still running? " + isRunning);
}
private static String readTrimmedOutput(InputStream is) throws Exception {
BufferedReader breader = new BufferedReader(new InputStreamReader(is));
String line = breader.readLine();
return line != null ? line.trim() : "";
}
Sample output
Output from command: ProcessId = 6480;
ProcessId is: 6480
Is process still running? true
For showing/displaying cmd console change some lines to:
// Execution
String your_command = "cmd.exe /c \"dir\"";
process = Runtime.getRuntime().exec("cmd /c wmic process call create \"" + your_command + "\" | findstr ProcessId");
References:
https://msdn.microsoft.com/en-us/library/aa394531(v=vs.85).aspx
https://www.computerhope.com/wmic.htm
since I didn't quite understand what you really need,i brought a comprehensive example of openning cmd from a java class (for instance class A) and starting a process of another java class (class B) and doing some operation from class B while class B is informing class A of whether it is processing yet or not. so the whole thing is to excecute class B from command promt that class A started and sending information from class B to A to notify it that it's still running.
in my example i took Main class as class A and myProcess class as class B.
as you can see in code below the Main class is Opening cmd and is executing myProcess class then myProcess class is sending a information about the process through the socket that was created in Main class
//imports
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
//class
public class Main
{
//fields
//methods
public static void main(String[] args) throws Exception
{
Runtime run = Runtime.getRuntime();
String new_dir = "C:\\Users\\Parsa\\Desktop\\New folder (2)";//imagine the directory of myProcess.class is in this folder
startServer();
run.exec("cmd.exe /c cd \""+new_dir+"\" & start cmd.exe /k \"java myProcess\"");
}
public static void startServer()
{
Thread myThread = new Thread()
{
#Override
public void run()
{
ServerSocket ss;// creating an open port for receiving data from network
try {
ss = new ServerSocket(60010);//open port number 60010--> it can really be anything that is empty
Socket s = ss.accept();//Listens for a connection to be made to this socket and accepts it
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));//get the inputstream and change it to a buffered reader in order to get a string from remote network
String line = null;
while ((line = in.readLine()) != null) //read the input
{
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
myThread.start();
}
}
myProcess class:
by the way you need to compile the myProcess class manually by command prompt and excecute myProcess.class file from Main class
and the myProcess class is
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
public class myProcess extends Thread
{
//field
//methods
public static void main(String[] args) throws Exception
{
System.out.println("myProcess has started");
startSender();
}
public static void startSender()
{
Thread myThread = new Thread()
{
#Override
public void run()
{
try
{
Socket s = new Socket("localhost", 60010);
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
for(int i = 0 ; i<10 ; i++)
{
out.write("Process in running");
out.newLine();
out.flush();
Thread.sleep(200);
}
out.close();
//do whatever here
System.out.println("myProcess output");
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
myThread.start();
if(!myThread.isAlive())
{
System.out.println("myProcess has finished");
}
}
}
since i didn't exactly understand what you wanted ,this is probably not exactly what you want, but... it will definitely help you if you manipulate the code.
I believe that you need to launch you application as the process and not the CMD and then launch a child process of the CMD. It is the same as in Linux.
The CMD that you launched is alive=true but when you started java from that CMD is another process which is a child of the CMD but it will not return you the expected results.
HTH,
Gal
PS. you might want to take a look at https://commons.apache.org/proper/commons-exec/ which is superior in functionality to Java in my opinion.

Disabling a menu item in Eclipse during startup

I am developing an Eclipse plugin. I need to check if the nvcc is present at start-up, and if not, then disable a particular menu item. Here is my code till now:
package Startup;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.eclipse.ui.IStartup;
public class StartCheck implements IStartup {
public void earlyStartup() {
// This method checks for presence of nvcc when Eclipse starts-up.
String command="nvcc -version";
Runtime run = Runtime.getRuntime();
Process pr;
try {
pr = run.exec(command);
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
//print-out the nvcc version
System.out.println(buf.readLine());
}catch (IOException e) {
//disable all buttons since no further task can be done, prompt user to install nvcc.
System.out.println("nvcc not present, freezing the energy estimation plugin...");
disableMenu();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void disableMenu(){
}
}
As you can see, the disable menu method does not contain anything. Can someone please help me with this? I have to basically disable a particular menu item if an IOException occurs in the above code.
Thanks!

Exception with Freetts when using kevin or mbrola

I am trying to run a program using freetts. I am able to compile the program however I am not able to use kevin or mbrola voices I get the follwing output message at the end
System property "mbrola.base" is undefined. Will not use MBROLA voices.
LINE UNAVAILABLE: Format is pcm_signed 16000.0 Hz 16 bits 1 channel big endian
import javax.speech.*;
import javax.speech.synthesis.*;
import java.util.*;
class freetts {
public static void main(String[] args) {
try{
Calendar calendar = new GregorianCalendar();
String sayTime = "It is " + calendar.get(Calendar.HOUR) + " " + calendar.get(Calendar.MINUTE) + " " + (calendar.get(Calendar.AM_PM)==0 ? "AM":"PM");
Synthesizer synth = Central.createSynthesizer(null);
synth.allocate();
synth.resume();
synth.speakPlainText(sayTime, null);
synth.waitEngineState(Synthesizer.QUEUE_EMPTY);
synth.deallocate();
}
catch(Exception e){
e.printStackTrace();
}
}
}
It seems that "To enable FreeTTS support for MBROLA, merely copy mbrola/mbrola.jar to lib/mbrola.jar. Then, whenever you run any FreeTTS application, specify the "mbrola.base" directory as a system property:
java -Dmbrola.base=/home/jim/mbrola -jar bin/FreeTTSHelloWorld.jar mbrola_us1"
I found this at:
http://freetts.sourceforge.net/mbrola/README.html
http://workorhobby.blogspot.com/2011/02/java-audio-freetts-line-unavailable.html
A big thanks to the author.
A program based on FreeTTS, the free text-to-speech engine for Java, was getting occasional errors
"LINE UNAVAILABLE: Format is ..."
Turns out there is no Java Exception or other mechanism to detect this error that occurs inside the FreeTTS library. All you get is the message on System.out, so there is no good way to react programatically.
Workaround: Configure the FreeTTS audio player to attempt accessing the audio device more than once until it succeeds. In this example, a short delay of 0.1 seconds is used to not miss an opportunity to grab the audio device; we keep trying for 30 seconds:
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.openFailDelayMs", "100");
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.totalOpenFailDelayMs", "30000");
If the audio device is permanently used by another program, there is of course no way to get access. Under Linux, this command will display the ID of the process that is currently holding the audio device, so you can then try to get rid of the offending program:
/sbin/fuser /dev/dsp
The second phrase has nothing to do with mbrola, but with a horrendous java linux sound bug that is still not fixed.
Check the third post here:
https://forums.oracle.com/forums/thread.jspa?threadID=2206163
That is happening because freetts "trusts" the sourcedataline, instead of doing the workaround on that post. The bug is in the jdk, but can be worked around by finding where in freetts that is happening and inserting the workaround & recompiling.
Here is a testcase
package util.speech;
import java.util.Iterator;
import java.util.Locale;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class VoiceTest {
public VoiceTest() {
}
#BeforeClass
public static void setUpClass() throws Exception {
}
#AfterClass
public static void tearDownClass() throws Exception {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
#Test
public void testDataLineAvailableAndBuggyInJDK() throws LineUnavailableException {
boolean failedSimpleGetLine = false;
AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
//ok, at least it says so
throw e;
}
try {
//if this fails the jdk is very buggy, since it just told us
//the line was available
line.open(format);
} catch (LineUnavailableException e) {
failedSimpleGetLine = true;
} finally {
if (line.isOpen()) {
line.close();
}
}
//now if this is true, test if it's possible to get a valid sourcedataline
//or the only bug is adquiring a sourcedataline doesn't throw a lineunavailable
//exception before open
Assume.assumeTrue(failedSimpleGetLine);
line = getSourceDataLine(format);
if (line == null) {
return;
}
try {
line.open(format);
} catch (LineUnavailableException e) {
//ok then it is consistent, and there is only one bug
fail("Line Unavailable after being adquired");
} finally {
if (line.isOpen()) {
line.close();
}
}
fail("line available after first test not managing to adquire it");
}
private SourceDataLine getSourceDataLine(AudioFormat format) {
try {
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
SourceDataLine dataline = null;
try {
Mixer mixer = AudioSystem.getMixer(mi);
dataline = (SourceDataLine) mixer.getLine(info);
dataline.open(format);
dataline.start();
return dataline;
} catch (Exception e) {
}
if (dataline != null) {
try {
dataline.close();
} catch (Exception e) {
}
}
}
} catch (Exception e) {
}
return null;
}
}
I know i am posting it little late, but this may help someone. I tried with both kevin and mbrola, and it worked for me. Please find the code below.
package com.mani.texttospeech;
import java.beans.PropertyVetoException;
import java.util.Locale;
import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
/**
*
* #author Manindar
*/
public class SpeechUtils {
SynthesizerModeDesc desc;
Synthesizer synthesizer;
Voice voice;
public void init(String voiceName) throws EngineException, AudioException, EngineStateError, PropertyVetoException {
if (desc == null) {
System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
desc = new SynthesizerModeDesc(Locale.US);
Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");
synthesizer = Central.createSynthesizer(desc);
synthesizer.allocate();
synthesizer.resume();
SynthesizerModeDesc smd = (SynthesizerModeDesc) synthesizer.getEngineModeDesc();
Voice[] voices = smd.getVoices();
for (Voice voice1 : voices) {
if (voice1.getName().equals(voiceName)) {
voice = voice1;
break;
}
}
synthesizer.getSynthesizerProperties().setVoice(voice);
}
}
public void terminate() throws EngineException, EngineStateError {
synthesizer.deallocate();
}
public void doSpeak(String speakText) throws EngineException, AudioException, IllegalArgumentException, InterruptedException {
synthesizer.speakPlainText(speakText, null);
synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
}
public static void main(String[] args) throws Exception {
SpeechUtils su = new SpeechUtils();
su.init("kevin16");
// su.init("kevin");
// su.init("mbrola_us1");
// su.init("mbrola_us2");
// su.init("mbrola_us3");
// high quality
su.doSpeak("Hi this is Manindar. Welcome to audio world.");
su.terminate();
}
}
And add the below dependencies to your pom.xml file.
<dependencies>
<dependency>
<groupId>net.sf.sociaal</groupId>
<artifactId>freetts</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
Hope this will be helpful.

Categories