[Java] Entrez dans le stdin du processus

Ce que je voulais faire

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.

environnement

OS Java ffprobe
macOS Mojave 10.14.6 1.8.0_181 4.1.4

manière

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;
    }
}

problème

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înejava.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

[Java] Entrez dans le stdin du processus
Shell pour tuer les processus Java
Entrée dans la console Java
Histoire de paiza.jp [solution d'entrée standard Java]
[java] Résumé de la gestion des caractères
[Java] [Maven3] Résumé de l'utilisation de Maven3
Sortie du livre "Introduction à Java"
Acquisition du contenu d'entrée à l'aide de Scanner (Java)
Processus de mise en mémoire tampon Java
Processus de vérification Java
[Java] Introduction à Java
Introduction à Java
[Java] Présentation de Java
Utilisez jenv pour activer plusieurs versions de Java
[java] Résumé de la gestion des chaînes de caractères
Points à prendre en compte lors de l'écriture de Java
[Java] Résumé de la façon d'omettre les expressions lambda
Comment afficher le résultat du remplissage du formulaire
[Introduction à Java] Bases de l'arithmétique Java (pour les débutants)
Java Bienvenue dans le marais des tableaux bidimensionnels
[Java] Comment obtenir l'URL de la source de transition
Collection expirée de java
Caractéristiques prévues de Java
[Java] Importance de serialVersionUID
Changements de Java 8 à Java 11
Somme de Java_1 à 100
Comment écrire Scala du point de vue de Java
[Java] Types de commentaires et comment les rédiger
[Java Silver] Résumé des points liés aux expressions lambda
NIO.2 examen de Java
Comment entrer / sortir des fichiers mainframe IBM en Java?
Avis sur Java Shilber
Initialisation de for Essayez de changer le problème Java en TypeScript 5-4
[Java] Connectez-vous à MySQL
java --Unification des commentaires
[Java] Comment obtenir la valeur maximale de HashMap
[java.io] Résumé de l'entrée de chaîne Java (InputStream, Reader, Scanner)
Résumé des connaissances requises pour réussir Java SE8 Silver
Améliorations de Kotlin à Java
Histoire des annotations Java
À partir d'avril 2018 Comment installer Java 8 sur Mac
java (mérites du polymorphisme)
J'étais accro à getXxxx de ResultSet car c'est un type primitif (Java)
De Java à Ruby !!
Résumé de l'API de communication Java (1) Comment utiliser Socket
Introduction à Java pour les débutants Connaissance de base du langage Java ①
Résumé de l'API de communication Java (3) Comment utiliser SocketChannel
Résumé de l'API de communication Java (2) Comment utiliser HttpUrlConnection
Résumé de la mise en œuvre des arguments par défaut en Java
Java: utilisez Stream pour trier le contenu d'une collection
Examen NIO de Java
Introduction à la commande java
[Java] Éléments à prendre en compte lors de la sortie de FizzBuzz
[Java] Trois fonctionnalités de Java
Comment exécuter l'exemple WebCamCapture de NyARToolkit pour Java
Résumé du support Java 2018