Avec ffmpeg (ffprobe), vous pouvez sonder les informations de fichier entrées dans stdin (pipe: 0) comme suit.
cat a.mp4 | ffprobe -hide_banner -v error -print_format json -show_streams -i pipe:0
En profitant de cela, je voulais traiter ffprobe
sans enregistrer le fichier multipart
POSTed depuis l'avant avec Spring Boot
comme fichier.
OS | Java | ffprobe |
---|---|---|
macOS Mojave 10.14.6 | 1.8.0_181 | 4.1.4 |
En gros, vous pouvez le faire de la manière suivante (je pense que vous pouvez entrer le problème dans stdin de Process plus tard).
Vous pouvez transmettre le contenu du fichier en écrivant dans ʻOutput Stream de
Process. J'utilise ʻorg.apache.tika.io.IOUtils
, mais comme je ne convertis que le résultat du traitement en ʻInputStream` en une chaîne de caractères, je pense que je peux l'implémenter moi-même ou installer une bibliothèque. Je vais.
import org.apache.tika.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
public static String probeMultipartFile(MultipartFile multipartFile) {
List<String> commands = Arrays.asList(
"ffprobe",
//Ne pas afficher les options de configuration ou les versions de bibliothèque
"-hide_banner",
//Afficher uniquement le contenu de ffprobe
"-v", "error",
//Sortie en JSON
"-print_format", "json",
//Sortie des informations vidéo / audio contenues dans un fichier sous forme de tableau
"-show_streams",
//Traiter les informations saisies dans le tuyau
"-i", "pipe:0"
);
Process process = null;
try {
process = new ProcessBuilder(commands).start();
//Ecrire à stdin
OutputStream os = process.getOutputStream();
os.write(multipartFile.getBytes());
os.flush();
os.close(); //Il y avait un modèle qui ne se terminerait que s'il était fermé avant d'attendre
//S'il ne se termine pas après avoir attendu 5 secondes, il termine le processus et renvoie null.
boolean result = process.waitFor(5, TimeUnit.SECONDS);
if (!result) {
process = null;
return null;
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
//Même si c'est IOException Broken pipe, il peut être supprimé, donc retournez avec
if (process != null) {
try {
//Si process n'est pas nul, retourne avec la sortie standard sous forme de chaîne
return IOUtils.toString(process.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
Lorsque j'ai essayé de traiter le fichier de cette manière, le phénomène que le fichier mp4 ou wmv que j'avais avait java.io.IOException: tuyau cassé
s'est produit et le traitement n'a pas pu être terminé dans le système normal. (Même si le modèle est Broken pipe, le même résultat que le résultat de la sonde exécuté en spécifiant le fichier peut être obtenu).
Ce problème semble se produire en fonction de l'extension, quelle que soit la taille du fichier, etc.
L'enquête étant interrompue, la cause est inconnue, mais il semble que la réaction diffère selon le dossier comme suit.
--Process
ferme ʻOutputStream au bon moment --ʻOutputStream
ne se ferme pas et attend l'écriture, donc il ne se terminera pas à moins qu'il ne soit fermé du côté Java
--ʻOutputStreamest fermé à un moment anormal, ce qui entraîne
java.io.IOException: tuyau cassé`
Les deux premiers ferment le processus à l'intérieur du système normal, mais à la fin, il semble que le processus doit être fait en dehors du système normal.
En plus de cela, il semble qu'il y ait de nombreux problèmes que le résultat du traitement du contenu écrit à partir de stdin soit étrange, donc je pense qu'il est préférable de l'enregistrer en tant que fichier silencieux, puis de le traiter.
Recommended Posts