J'ai des problèmes lors de l'exécution de cette commande ffmpeg
dans mon code java:
ffmpeg -i sample.mp4 -i ad.mp4 -filter_complex "[0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out]" -map "[out]" output.mp4
J'ai utilisé la méthode getRuntime()
ci-dessous, mais cela ne fonctionne pas pour moi. Même si je supprime simplement le "
, cela ne fonctionne toujours pas. Lorsque je copie-collez simplement la chaîne équivalente dans le terminal, cela fonctionne.
String c1=" -i "+dir+"sample.mp4 "+"-i "+dir+"ad.mp4 -filter_complex [0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out] -map [out] "+dir+"output.mp4";
RunCommand("ffmpeg"+c1);
En utilisant cette méthode:
private static void RunCommand(String command) throws InterruptedException {
try {
// Execute command
Process proc = Runtime.getRuntime().exec(command);
System.out.println(proc.exitValue());
// Get output stream to write from it
// Read the output
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null) {
System.out.print(line + "\n");
// System.out.println(ads.get(0));
}
proc.waitFor();
} catch (IOException e) {
}
}
Celui-ci ne fonctionne pas non plus, et l'impression de la valeur de sortie montre ceci:
Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited
at java.lang.UNIXProcess.exitValue(UNIXProcess.java:423)
at parser.Parser.RunCommand(Parser.java:106)
at parser.Parser.commandGenerator2(Parser.java:79)
at parser.Parser.main(Parser.java:44)
Si je déplace le proc.waitFor();
avant d'imprimer la valeur de sortie, c'est 1
.
Quel est le problème? Pourquoi il ne fonctionne pas en code Java?
2 réponses
Il y a un problème sur votre code, tout d'abord, utilisez le thread pour diffuser et l'erreur du processus interne vers la console
Créez une classe de flux de tuyaux comme:
class PipeStream extends Thread {
InputStream is;
OutputStream os;
public PipeStream(InputStream is, OutputStream os) {
this.is = is;
this.os = os;
}
public void run() {
byte[] buffer=new byte[1024];
int len;
try {
while ((len=is.read(buffer))>=0){
os.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Puis adaptez la partie runtime à:
System.out.println("Launching command: "+command);
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", command);
Process proc=pb.start();
PipeStream out=new PipeStream(proc.getInputStream(), System.out);
PipeStream err=new PipeStream(proc.getErrorStream(), System.err);
out.start();
err.start();
proc.waitFor();
System.out.println("Exit value is: "+proc.exitValue());
Il affichera la commande qui sera exécutée, les journaux et potentiellement l'erreur.
Vous pourrez copier-coller la commande pour vérifier sur un terminal ce qui se passe si nécessaire.
EDIT: C'est très drôle. Votre code manquait de caractère d'échappement ET il n'y a pas de caractère visible dans votre code. Je les ai vus quand j'ai copié coller la ligne de code. Copiez collez la ligne suivante dans votre code, cela supprimera l'erreur:
String command="ffmpeg -i "+dir+"sample.mp4 -i "+dir+"ad.mp4 -filter_complex '[0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out]' -map '[out]' "+dir+"output.mp4";
Il semble que vous ayez manqué des guillemets autour de l'argument du paramètre -filter_complex
. Java exécutera quelque chose comme ceci:
ffmpeg -i ./sample.mp4 -i ./ad.mp4 -filter_complex [0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out] -map [out] output.mp4
Cela ne fonctionne pas puisque ;
signifie la fin de la commande dans bash. Remettre des guillemets dans le code java devrait corriger la commande (assurez-vous de les échapper correctement).
String c1=" -i "+dir+"sample.mp4 "+"-i "+dir+"ad.mp4 -filter_complex \"[0:v]trim=0:15,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=20:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out]\" -map [out] "+dir+"output.mp4";
RunCommand("ffmpeg"+c1);
De nouvelles questions
java
Java est un langage de programmation de haut niveau. Utilisez cette balise lorsque vous rencontrez des problèmes pour utiliser ou comprendre la langue elle-même. Cette balise est rarement utilisée seule et est le plus souvent utilisée en conjonction avec [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] et [maven].