Reputation: 121
I can not figure out how to start a Process in Java for recording a live stream with ffmpeg.
I've tried several solutions, but my current code looks like this (simplified):
public void startDownload() {
String[] processArgs = new String[] {
"ffmpeg",
"-i",
"https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8",
"-c",
"copy",
"-bsf:a",
"aac_adtstoasc",
"C:\\temp\\test.mp4"
};
ProcessBuilder processBuilder = new ProcessBuilder(processArgs);
try {
process = processBuilder.start();
process.wairFor(); // Do I need this? Actually the stream is running forever until I stop it manually.
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) { // this blocks forever
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is, that something blocks the process from starting. In this example the br.readLine()
blocks it forever and I can not get any output from the process.
But after killing the jar / stopping launch config in Intellij, the process begins to work and I have to kill it via task manager.
Running a process that is not recording a live stream like just executing ffmpeg
works by the way.
I'm using Windows, JDK 14, IntelliJ.
Upvotes: 2
Views: 1822
Reputation: 121
I could figure it out by myself.
You have to pipe both the input stream and output stream to a BufferedReader
and you need to read all its lines.
My code currently looks like this:
public void startDownload() {
String[] processArgs = new String[] {
"ffmpeg",
"-i",
"https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8",
"-c",
"copy",
"-bsf:a",
"aac_adtstoasc",
"C:\\temp\\test.mp4"
};
ProcessBuilder processBuilder = new ProcessBuilder(processArgs);
process = processBuilder.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = "";
String newLineCharacter = System.getProperty("line.separator");
boolean isOutReady = false;
boolean isErrorReady = false;
boolean isErrorOut = true;
boolean isErrorError = true;
boolean isPrintToConsole = false;
while (process.isAlive()) {
do {
isOutReady = stdInput.ready();
isErrorOut = true;
isErrorError = true;
if (isOutReady) {
line = stdInput.readLine();
isErrorOut = false;
if (isPrintToConsole) {
System.out.println(line + newLineCharacter);
}
}
isErrorReady = stdError.ready();
if (isErrorReady) {
line = stdError.readLine();
isErrorError = false;
if (isPrintToConsole) {
System.out.println("ERROR: " + line + newLineCharacter);
}
}
if (!process.isAlive()) {
if (isPrintToConsole) {
System.out.println("Process DIE: " + line + newLineCharacter);
}
line = null;
isErrorError = false;
process.waitFor();
}
} while (line != null);
process.waitFor(100, TimeUnit.MILLISECONDS);
}
}
Upvotes: 2