Запись прямой трансляции с использованием ffmpeg в качестве процесса в Java - PullRequest
0 голосов
/ 25 мая 2020

Я не могу понять, как запустить процесс в Java для записи живого потока с помощью ffmpeg.

Я пробовал несколько решений, но мой текущий код выглядит так (упрощенно):

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();
    }
}

Проблема в том, что что-то блокирует запуск процесса. В этом примере br.readLine() блокирует его навсегда, и я не могу получить какой-либо вывод из процесса.

Но после уничтожения конфигурации запуска jar / остановки в Intellij процесс начинает работать, и я должен его убить с помощью диспетчера задач.

Запуск процесса, который не записывает прямой поток, например, просто выполнение ffmpeg, кстати, работает

Я использую Windows, JDK 14, IntelliJ.

1 Ответ

0 голосов
/ 27 мая 2020

Я мог бы разобраться сам. Вам нужно направить поток ввода и вывода на BufferedReader, и вам нужно прочитать все его строки.

Мой код в настоящее время выглядит так:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...