[Java] Input to stdin of Process

What I wanted to do

With ffmpeg (ffprobe), you can probe the file information entered in stdin (pipe: 0) as follows.

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

Taking advantage of this, I wanted to process ffprobe without saving the Multipart File POSTed from the front by Spring Boot as a file.

environment

OS Java ffprobe
macOS Mojave 10.14.6 1.8.0_181 4.1.4

manner

Roughly, you can do it in the following way (I think that you can enter the problem in stdin of Process later).

You can pass the file contents by writing to ʻOutputStream of Process. I am using ʻorg.apache.tika.io.IOUtils, but since I am only converting the processing result output to ʻInputStream` to a character string, I think that I can implement it by myself or install a library. I will.

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",
            //Do not output configure options or library versions
            "-hide_banner",
            //Display only the contents of ffprobe
            "-v", "error",
            //Output in JSON
            "-print_format", "json",
            //Output video / audio information contained in a file as an array
            "-show_streams",
            //Process the information entered in the pipe
            "-i", "pipe:0"
    );

    Process process = null;

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

        //Write to stdin
        OutputStream os = process.getOutputStream();
        os.write(multipartFile.getBytes());
        os.flush();
        os.close(); //There was a pattern that would not end unless it was closed before waitFor

        //Wait 5 seconds and if it doesn't finish, finish the process and return null
        boolean result = process.waitFor(5, TimeUnit.SECONDS);
        if (!result) {
            process = null;
            return null;
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    } finally {
        //Even if it is IOException Broken pipe, it may be removed, so return with finally
        if (process != null) {
            try {
                //If process is not null, return with standard output as a string
                return IOUtils.toString(process.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

problem

When I tried to process the file in this way, the phenomenon that the mp4 or wmv file I had had java.io.IOException: Broken pipe occurred, and the process could not be completed in the normal system. (Even if the pattern is Broken pipe, the same result as the probe result executed by specifying the file can be obtained). This problem seemed to occur depending on the extension regardless of the file size etc.

Since the investigation has been discontinued, the cause is unknown, but it seems that the reaction differs depending on the file as follows.

--Process closes ʻOutputStream at the right time --ʻOutputStream does not close and waits for writing, so it will not end unless it is closed from the Java side --ʻOutputStreamis closed at an abnormal timing, resulting injava.io.IOException: Broken pipe`

The first two close the process inside the normal system, but at the end it seems that the process must be done outside the normal system.

In addition to this, it seems that there are many problems that the processing result for the content written from stdin is strange, so I think that it is better to save it as a file quietly and then process it.

Recommended Posts

[Java] Input to stdin of Process
Shell to kill Java process
Input to the Java console
Story of paiza.jp [Java standard input solution]
[java] Summary of how to handle char
[Java] [Maven3] Summary of how to use Maven3
Output of the book "Introduction to Java"
Acquisition of input contents using Scanner (Java)
The process of introducing Vuetify to Rails
Java buffering process
Java check process
[Java] Introduction to Java
Introduction to java
[Java] Overview of Java
Use jenv to enable multiple versions of Java
[java] Summary of how to handle character strings
Things to be aware of when writing Java
[Java] How to get and output standard input
[Java] Summary of how to abbreviate lambda expressions
[Java / Spring Boot] Spring security ④ --Implementation of login process
How to display the result of form input
[Java] How to get the authority of the folder
[Introduction to Java] Basics of java arithmetic (for beginners)
Java Welcome to the Swamp of 2D Arrays
[Java] How to get the URL of the transition source
Expired collection of java
[Java] How to use compareTo method of Date class
Predicted Features of Java
[Java] Significance of serialVersionUID
Changes from Java 8 to Java 11
Sum from Java_1 to 100
How to write Scala from the perspective of Java
[Java] Types of comments and how to write them
[Java Silver] Summary of points related to lambda expressions
NIO.2 review of java
How to input / output IBM mainframe files in Java?
Review of java Shilber
Initialization of for Try to make Java problem TypeScript 5-4
[Java] Connect to MySQL
java --Unification of comments
[Java] How to get the maximum value of HashMap
[java.io] Summary of Java string input (InputStream, Reader, Scanner)
Summary of knowledge required to pass Java SE8 Silver
Kotlin's improvements to Java
History of Java annotation
As of April 2018 How to get Java 8 on Mac
java (merits of polymorphism)
GetXxxx of ResultSet was addicted to primitive type (Java)
From Java to Ruby !!
Summary of Java communication API (1) How to use Socket
Introduction to Java for beginners Basic knowledge of Java language ①
Summary of Java communication API (3) How to use SocketChannel
Summary of Java communication API (2) How to use HttpUrlConnection
Summary of how to implement default arguments in Java
Java: Use Stream to sort the contents of the collection
NIO review of java
Introduction to java command
[Java] Things to be aware of when outputting FizzBuzz
[Java] Three features of Java
How to execute WebCamCapture sample of NyARToolkit for Java
Summary of Java support 2018