Serbroda
Serbroda

Reputation: 121

Record live stream using ffmpeg as Process in Java

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

Answers (1)

Serbroda
Serbroda

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

Related Questions