web-dev-qa-db-fra.com

ProcessBuilder donne un "Aucun fichier ou répertoire" sur Mac tandis que Runtime (). Exec () fonctionne très bien

J'ai une application, fonctionnant sur Playframework, qui doit coder certains fichiers vidéo. j'ai utilisé

Process pr = Runtime.getRuntime().exec(execCode)

pour cela (et cela fonctionne parfaitement), mais comme j'ai besoin des deux, le flux de sortie et le flux d'erreur, j'essaie d'utiliser ProcessBuilder (comme cela est également recommandé).

Mais je n'arrive pas à le faire fonctionner (test sur un MacBook). Existe-t-il une différence fondamentale entre la méthode Runtime et ProcessBuilder?

Ceci est mon code pour ProcessBuilder (exactement le même code fonctionne lorsqu'il est remplacé par Runtime.getRuntime().exec())

    String execCode = "/opt/local/bin/ffmpeg -i file [...]"; 
    ProcessBuilder pb = new ProcessBuilder(execCode);
    pb.redirectErrorStream(true);
    pb.directory(new File("/Users/[...]/data/"));
    Process pr = pb.start();

Voici la sortie de la console:

11:00:18,277 ERROR ~ There was a problem with with processing MediaFile[13] with error Error during coding process: Cannot run program "/opt/local/bin/ffmpeg -i /Users/[...]/data/media/1/1/test.mov [...] /Users/[...]/data/media/1/13/encoded.mp3" (in directory "/Users/[...]/data"): error=2, No such file or directory
Java.lang.Exception: Error during coding process: Cannot run program "/opt/local/bin/ffmpeg -i /Users/Luuk/Documents/Java/idoms-server/data/media/1/1/test.mov -y -f mpegts -acodec libmp3lame -ar 48000 -b:a 64000 -vn -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate -1 -bufsize -1 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30  -g 30 -async 2 /Users/Luuk/Documents/Java/idoms-server/data/media/1/13/encoded.mp3" (in directory "/Users/Luuk/Documents/Java/idoms-server/data"): error=2, No such file or directory
    at logic.server.MediaCoder.encodeMediaFile(MediaCoder.Java:313)
    at logic.server.MediaCoder.doJob(MediaCoder.Java:54)
    at play.jobs.Job.doJobWithResult(Job.Java:50)
    at play.jobs.Job.call(Job.Java:146)
    at play.jobs.Job$1.call(Job.Java:66)
    at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:303)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:138)
    at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.Java:98)
    at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.Java:206)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.Java:886)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:908)
    at Java.lang.Thread.run(Thread.Java:680)
Caused by: Java.io.IOException: Cannot run program "/opt/local/bin/ffmpeg -i /Users/Luuk/Documents/Java/idoms-server/data/media/1/1/test.mov -y -f mpegts -acodec libmp3lame -ar 48000 -b:a 64000 -vn -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate -1 -bufsize -1 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30  -g 30 -async 2 /Users/Luuk/Documents/Java/idoms-server/data/media/1/13/encoded.mp3" (in directory "/Users/Luuk/Documents/Java/idoms-server/data"): error=2, No such file or directory
    at Java.lang.ProcessBuilder.start(ProcessBuilder.Java:460)
    at logic.server.MediaCoder.encodeMediaFile(MediaCoder.Java:189)
    ... 11 more
Caused by: Java.io.IOException: error=2, No such file or directory
    at Java.lang.UNIXProcess.forkAndExec(Native Method)
    at Java.lang.UNIXProcess.<init>(UNIXProcess.Java:53)
    at Java.lang.ProcessImpl.start(ProcessImpl.Java:91)
    at Java.lang.ProcessBuilder.start(ProcessBuilder.Java:453)
    ... 12 more
32
Luuk D. Jansen

Vous devez spécifier les arguments séparément Strings:

new ProcessBuilder("cmd", "arg1", "arg2", ...);

Le constructeur accepte String, varargs et List<String>.

Voir documentation ProcessBuilder .

58
Neet