[Java] Geben Sie in stdin of Process ein

Was ich machen wollte

Mit ffmpeg (ffprobe) können Sie die in stdin (pipe: 0) eingegebenen Dateiinformationen wie folgt prüfen.

cat a.mp4 | ffprobe -hide_banner -v error -print_format json -show_streams -i pipe:0

Aus diesem Grund wollte ich "ffprobe" verarbeiten, ohne die von vorne gepostete "Multipart File" mit "Spring Boot" als Datei zu speichern.

Umgebung

OS Java ffprobe
macOS Mojave 10.14.6 1.8.0_181 4.1.4

Weise

In etwa können Sie dies folgendermaßen tun (ich denke, dass Sie das Problem später in stdin of Process eingeben können).

Sie können den Dateiinhalt übergeben, indem Sie an "OutputStream" von "Process" schreiben. Ich verwende org.apache.tika.io.IOUtils, aber da ich nur die Ausgabe des Verarbeitungsergebnisses in InputStream in eine Zeichenfolge konvertiere, denke ich, dass ich sie selbst implementieren oder eine Bibliothek installieren kann. Ich werde.

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",
            //Geben Sie keine Konfigurationsoptionen oder Bibliotheksversionen aus
            "-hide_banner",
            //Zeigen Sie nur den Inhalt von ffprobe an
            "-v", "error",
            //Ausgabe in JSON
            "-print_format", "json",
            //In einer Datei enthaltene Video- / Audioinformationen als Array ausgeben
            "-show_streams",
            //Verarbeiten Sie die in die Pipe eingegebenen Informationen
            "-i", "pipe:0"
    );

    Process process = null;

    try {
        process = new ProcessBuilder(commands).start();

        //Schreiben Sie an stdin
        OutputStream os = process.getOutputStream();
        os.write(multipartFile.getBytes());
        os.flush();
        os.close(); //Es gab ein Muster, das nicht enden würde, wenn es nicht vor waitFor geschlossen wurde

        //Wenn es nach 5 Sekunden Wartezeit nicht beendet wird, wird der Vorgang beendet und null zurückgegeben.
        boolean result = process.waitFor(5, TimeUnit.SECONDS);
        if (!result) {
            process = null;
            return null;
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    } finally {
        //Selbst wenn es sich um eine IOException Broken-Pipe handelt, kann sie entfernt werden. Kehren Sie also mit finally zurück
        if (process != null) {
            try {
                //Wenn der Prozess nicht null ist, geben Sie die Standardausgabe als Zeichenfolge zurück
                return IOUtils.toString(process.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

Problem

Als ich versuchte, die Datei auf diese Weise zu verarbeiten, hatte die mp4- und wmv-Datei das Phänomen, dass sie zu "java.io.IOException: Broken Pipe" wurde, und ich konnte den Vorgang im normalen System nicht abschließen. (Auch wenn das Muster "Broken Pipe" ist, kann das gleiche Ergebnis wie das durch Angabe der Datei ausgeführte Prüfergebnis erzielt werden.) Dieses Problem schien abhängig von der Erweiterung unabhängig von der Dateigröße usw. aufzutreten.

Da die Untersuchung eingestellt wurde, ist die Ursache unbekannt, aber es scheint, dass die Reaktion je nach Datei wie folgt unterschiedlich ist.

--Process schließt OutputStream zum richtigen Zeitpunkt --OutputStream wird nicht geschlossen und wartet auf das Schreiben. Daher wird es nicht beendet, es sei denn, es wird von der Java-Seite geschlossen. --OutputStream wird zu einem abnormalen Zeitpunkt geschlossen, was zu java.io.IOException: Broken Pipe führt

Die ersten beiden schließen den Prozess innerhalb des normalen Systems, aber am Ende scheint es, dass der Prozess außerhalb des normalen Systems durchgeführt werden muss.

Darüber hinaus scheint es viele Probleme zu geben, dass das Verarbeitungsergebnis für die von stdin geschriebenen Inhalte seltsam ist. Ich denke, es ist besser, es als leise Datei zu speichern und dann zu verarbeiten.

Recommended Posts

[Java] Geben Sie in stdin of Process ein
Shell zum Beenden von Java-Prozessen
Eingabe in die Java-Konsole
Geschichte von paiza.jp [Java Standard Input Solution]
[java] Zusammenfassung des Umgangs mit char
[Java] [Maven3] Zusammenfassung der Verwendung von Maven3
Ausgabe des Buches "Einführung in Java"
Erfassung von Eingabeinhalten mit Scanner (Java)
Java-Pufferprozess
Java-Überprüfungsprozess
[Java] Einführung in Java
Einführung in Java
[Java] Übersicht über Java
Verwenden Sie jenv, um mehrere Java-Versionen zu aktivieren
[java] Zusammenfassung des Umgangs mit Zeichenketten
Dinge, die Sie beim Schreiben von Java beachten sollten
[Java] Zusammenfassung, wie Lambda-Ausdrücke weggelassen werden
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
[Einführung in Java] Grundlagen der Java-Arithmetik (für Anfänger)
Java Willkommen im Sumpf der zweidimensionalen Arrays
[Java] So erhalten Sie die URL der Übergangsquelle
Abgelaufene Java-Sammlung
Voraussichtliche Funktionen von Java
[Java] Bedeutung der serialVersionUID
Änderungen von Java 8 zu Java 11
Summe von Java_1 bis 100
Wie schreibe ich Scala aus der Perspektive von Java
[Java] Arten von Kommentaren und wie man sie schreibt
[Java Silver] Zusammenfassung der Punkte im Zusammenhang mit Lambda-Ausdrücken
NIO.2 Überprüfung von Java
Wie kann ich IBM Mainframe-Dateien in Java eingeben / ausgeben?
Bewertung von Java Shilber
Initialisierung von for Versuchen Sie, das Java-Problem in TypeScript 5-4 zu ändern
[Java] Stellen Sie eine Verbindung zu MySQL her
Java - Vereinigung von Kommentaren
[Java] So erhalten Sie den Maximalwert von HashMap
[java.io] Zusammenfassung der Java-String-Eingabe (InputStream, Reader, Scanner)
Zusammenfassung der Kenntnisse, die zum Bestehen von Java SE8 Silver erforderlich sind
Kotlins Verbesserungen an Java
Geschichte der Java-Annotationen
Stand April 2018 So installieren Sie Java 8 auf einem Mac
Java (Verdienste des Polymorphismus)
Ich war süchtig nach getXxxx von ResultSet, weil es ein primitiver Typ ist (Java)
Von Java zu Ruby !!
Zusammenfassung der Java-Kommunikations-API (1) Verwendung von Socket
Einführung in Java für Anfänger Grundkenntnisse der Java-Sprache ①
Zusammenfassung der Java-Kommunikations-API (3) Verwendung von SocketChannel
Zusammenfassung der Java-Kommunikations-API (2) Verwendung von HttpUrlConnection
Zusammenfassung der Implementierung von Standardargumenten in Java
Java: Verwenden Sie Stream, um den Inhalt einer Sammlung zu sortieren
NIO Bewertung von Java
Einführung in den Java-Befehl
[Java] Dinge, die Sie bei der Ausgabe von FizzBuzz beachten sollten
[Java] Drei Funktionen von Java
Ausführen des WebCamCapture-Beispiels von NyARToolkit für Java
Zusammenfassung der Java-Unterstützung 2018