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.
OS | Java | ffprobe |
---|---|---|
macOS Mojave 10.14.6 | 1.8.0_181 | 4.1.4 |
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;
}
}
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 in
java.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