Probleme beim Ausführen des FFmpeg-Befehls in Java-Code unter Linux

8

Ich habe Probleme bei der Ausführung dieses Befehls ffmpeg in meinem Java-Code:

%Vor%

Ich habe die getRuntime() Methode benutzt, aber das funktioniert nicht für mich. Auch wenn ich einfach den " entferne, funktioniert es immer noch nicht. Wenn ich einfach die äquivalente Zeichenfolge im Terminal kopiere, funktioniert es.

%Vor%

Mit dieser Methode:

%Vor%

Dies funktioniert auch nicht, und das Drucken des Exit-Wertes zeigt dies:

%Vor%

Wenn ich proc.waitFor(); vor dem Ausdruck des Exit-Wertes verschiebe, ist es 1 .

Was ist das Problem? Warum läuft es nicht in Java-Code?

    
Tina J 07.08.2017, 19:37
quelle

3 Antworten

8

Es gibt ein Problem in Ihrem Code. Verwenden Sie zuerst den Thread zum Streamen und den Fehler des inneren Prozesses zur Konsole

Erstellen Sie eine Pipe-Stream-Klasse wie:

%Vor%

Passen Sie dann den Laufzeitteil an:

%Vor%

Es zeigt den Befehl an, der ausgeführt wird, die Protokolle und möglicherweise der Fehler.

Sie können kopieren den Befehl einfügen, um auf einem Terminal zu überprüfen, was bei Bedarf passiert.

EDIT: Das ist sehr lustig. Ihr Code enthielt ein Escape-Zeichen und es ist kein Zeichen in Ihrem Code sichtbar. Ich sah sie, wenn ich die Codezeile kopiere. Kopieren Sie die folgende Zeile in Ihren Code, um den Fehler zu entfernen:

%Vor%     
wargre 11.08.2017, 15:40
quelle
3

Mehrere Probleme zu beheben (die meisten werden von anderen Antworten einzeln angesprochen, mit verschiedenen Erklärungsgraden, aber Sie müssen alle beheben):

  • Sie müssen Argumente an ffmpeg genau so übergeben, wie die Shell es tun würde. Das bedeutet, dass Sie entweder einen Befehl als String-Array mit einzelnen Argumenten erstellen müssen oder, um es einfacher zu machen (und identisch mit Shell-Verhalten) Argumente: Fügen Sie ein Paar \" um das große Filterargument hinzu. Dann sollten Sie in der Lage sein, den Befehl an runCommand genau zu übergeben, während Sie ihn in eine Shell schreiben.
  • aber java kann diese Anführungszeichen nicht analysieren (*) und Argumente isolieren, die an ffmpeg übergeben werden, aber /bin/sh kann das für Sie tun: Umbrechen Sie Ihren Befehl mit /bin/sh -c ... (dafür verwende ich ProcessBuilder unten)
  • Sie müssen die Ausgabe konsumieren, oder Ihr Prozess blockiert möglicherweise ewig. ProcessBuilder zur Rettung: Redirect stderr to stdout , um nur einen einzigen Stream zu konsumieren, dann redirect stdout wohin du willst (unten erben ich vom übergeordneten Prozess, also geht es zur Ausgabe von java Prozess selbst.
  • Sie müssen warten, bis der Prozess abgeschlossen ist, bevor Sie den Exit-Wert erhalten (unten verwende ich waitFor() , das so lange wie nötig wartet, aber es gibt andere Optionen)
  • [Hinzugefügt nach @wargre gefangen] nicht zu stehlen, aber aus Gründen der Vollständigkeit müssen Sie sicherstellen, dass der Befehl nicht mit unsichtbaren Zeichen infiziert ist;) Zum Beispiel waren Sie tatsächlich Übergabe -fi......lter_complex (Punkte in hex sind e2 80 8c e2 80 8b ), aber in Ihrem Befehl sind mehr verstreut.

Also:

%Vor%

(*) Wenn Sie in einer Shell a b drucken möchten, tun Sie echo "a b" , aber in Java funktioniert das nicht:

%Vor%

Was es tut, wird naiv um die Leerzeichen verteilt und es werden 2 Argumente statt 1 an echo : "a dann b" übergeben. Nicht was du willst.

Alternative: Argumente einzeln übergeben.

%Vor%     
Hugues M. 11.08.2017 19:07
quelle
1

Es scheint so, als ob Sie die Argumente um das Argument für -filter_complex -Parameter verpasst haben. Java wird ungefähr so ​​laufen:

%Vor%

Es funktioniert nicht, da ; das Ende des Befehls in bash bedeutet. Setzen Sie die Anführungszeichen in Java-Code zurück, sollten Sie den Befehl korrigieren (stellen Sie sicher, dass Sie sie ordnungsgemäß umgehen).

%Vor%     
Vladimir 11.08.2017 17:52
quelle

Tags und Links