Как запустить команду ffmpeg в Java в MacOS с помощью ProcessBuilder - PullRequest
0 голосов
/ 03 августа 2020

Я пишу программу на Java, которая использует ffmpeg, чтобы «разрезать» видео на несколько частей и снова сшить их вместе. У меня все работает относительно плавно в Windows, но я не могу заставить ffmpeg работать в Ma c или в Linux, если на то пошло. Я сосредоточился на ma c прямо сейчас. Я думал, что это может быть проблема с разрешениями, но когда я запускаю его с помощью sudo, я получаю сообщение об ошибке (после ввода пароля:

sudo: ffmpeg: command not found

, когда я запускаю его без sudo, я получаю:

java.io.IOException: Cannot run program "ffmpeg": error=2, No such file or directory

Я думаю, это может быть потому, что пакет ffmpeg на машине Ma c был загружен с помощью homebrew, а ffmpeg хранится в / usr / local / Cellar / ffmpeg вместо папки по умолчанию, где бы он ни находился. Это может не быть проблемой, потому что я удалил ffmpeg и повторно загрузил его с помощью homebrew. Возможно, он также находился в папке по умолчанию в моих первых тестах. Было бы здорово понять это. Большинство из моей семьи использует Ma c (не я), и я действительно хочу поделиться с ними своей работой. Вот почему я решил закодировать это в Java. О, и я действительно попытался использовать каталог для двоичного файла в команда. Вот код:

    //snips out all the clips from the main video
    public void snip() throws IOException, InterruptedException {
        
        for(int i = 0; i < snippets.size(); i++) {
            //ffmpeg -i 20sec.mp4 -ss 0:0:1 -to 0:0:5 -c copy foobar.mp4
            String newFile = "foobar" + String.valueOf(i) + ".mp4";
            
            //THIS WORKS
            if(OS.isWindows()) {
                ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg", "-i", videoName, "-ss",
                        snippets.get(i).getStartTime(), "-to", snippets.get(i).getEndTime(), newFile);
                            
                Process process = processBuilder.inheritIO().start();
                process.waitFor();
                System.out.println("Win Snip " + i + "\n");
            }
            
            else if (OS.isMac()) {
                //FFMPEG LOCATION: /usr/local/Cellar/ffmpeg
                //THE ERROR: sudo: ffmpeg: command not found
                //ERROR W/OUT SUDO: java.io.IOException: Cannot run program "ffmpeg": error=2, No such file or directory
                ProcessBuilder processBuilder = new ProcessBuilder("sudo", "-S", "ffmpeg", "-f", videoName, "-ss",
                        snippets.get(i).getStartTime(), "-to", snippets.get(i).getEndTime(), newFile);
                
                Process process = processBuilder.inheritIO().start();
                process.waitFor();
                System.out.println("Mac Snip " + i + "\n");
            }
            
            else if (OS.isUnix()) {
                System.out.println("Your operating system is not supported");
                //TODO
                //need to figure out if deb/red hat/whatever are different
            }
            
            else if (OS.isSolaris()) {
                System.out.println("Your operating system is not supported yet");
                //TODO probably won't do
            }
            
            else {
                 System.out.println("Your operating system is not supported");
            }
            //add to the list of files to be concat later
            filesToStitch.add(newFile);
            filesToDelete.add(newFile);
            
        }
        //System.out.println(stitchFiles);
    }

Ответы [ 3 ]

0 голосов
/ 04 августа 2020

Java не найдет исполняемый файл для запуска, если он не находится в вашем PATH или вы не используете полный путь к исполняемому файлу. Добавьте это, чтобы увидеть, какой PATH установлен на.

System.out.println("PATH="+System.getenv("PATH"));

Если вы хотите вызвать «ffmpeg», то он должен быть где-то на указанном выше пути (исправьте, изменив путь к пусковой установке вашего приложения) или измените свой вызов на абсолютный:

File exe = new File("/usr/local/Cellar/ffmpeg"); // or whereever
System.out.println("exe exists="+exe.exists());
ProcessBuilder processBuilder = new ProcessBuilder(exe.toString(), "-f", videoName, "-ss", snippets.get(i).getStartTime(), "-to", snippets.get(i).getEndTime(), newFile);

Вам не нужно вызывать «sudo», если «ffmpeg» работает как обычная учетная запись пользователя.

0 голосов
/ 05 августа 2020

Выслушав всех, кто говорил мне, что это проблема с путем к файлу, я решил дважды проверить, что у меня правильный каталог. Я этого не сделал. Я видел файл "ffmpeg" в папке homebrew, но обнаружил, что могу ввести:

type ffmpeg

в терминал, чтобы найти путь к файлу. Оказывается, на самом деле он находился в каталоге usr / local / bin / ffmpeg. Все, что мне нужно было сделать, это добавить его в свой код

ProcessBuilder processBuilder = new ProcessBuilder("usr/local/bin/ffmpeg", "-f", videoName, "-ss", snippets.get(i).getStartTime(), "-to", snippets.get(i).getEndTime(), newFile);

Я чувствую себя полным идиотом.

0 голосов
/ 04 августа 2020

Поскольку Ma c OS основана на UNIX, вам нужно поставить "./" перед именем исполняемого файла, если местоположение не находится в настроенном пути (т.е. переменная среды $ PATH). Мы надеемся, что изменение "ffmpeg" на "./ffmpeg" должно сработать (при условии, что он действительно находится в рабочем каталоге - вы также можете изменить рабочий каталог, вызвав directory () в ProcessBuilder, если необходимо).

...