我不能让它运行,因为java只是在等待ffmpeg。但是ffmpeg没有给出输入,也没有给出错误流。它只是运行,但什么也不做。
"System.out.println("command:..“insert into bash )的输出运行得很好,因为expected.So语法没有任何问题。
这是代码。
package mypackage;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
/**
*
* @author test
*/
public class ffmpeg_hang {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException, InterruptedException {
String INPUT_FILE="/path/to/media";
String FFMPEG_PATH="/path/to/ffmpegFolder/";
for(int i=0;(i+4)<40;i+=4){
String[] ffmpeg_pipe = new String[]{
FFMPEG_PATH + "ffmpeg_4.1.1",
"-ss",(i+""),"-t", "4",
"-i", INPUT_FILE,
"-ac", "1", "-acodec", "pcm_s16le", "-ar", "16000",
"-f","nut","-","|",
FFMPEG_PATH + "ffmpeg_4.1.1",
"-i","-",
"-lavfi", "showspectrumpic=s=128x75:legend=disabled:saturation=0:stop=8000",
"-f","image2pipe","pipe:1"};
System.out.println("command: "+String.join(" ", ffmpeg_pipe));
Process p;
//ffmpe wav->pipe->spectrogra->pipe->java
p = Runtime.getRuntime().exec(ffmpeg_pipe);
StringBuilder Boxbuffer = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = "";
while ((line = reader.readLine()) != null) {
Boxbuffer.append(line);
}
System.out.println("ffmpeg errors->> "+Boxbuffer.toString());
p.waitFor();
BufferedImage image = ImageIO.read(p.getInputStream());
//do stuff with image
}
}
}发布于 2019-03-18 08:22:17
当以这种方式直接在命令中传递时,管道将不会被解释,它只是命令开头的第一个ffmpeg的另一个参数。考虑使用/bin/sh -c "command1 | command2"作为包装器(假设非Windows OS...)。
考虑将-nostdin添加到第一个ffmpeg命令中,以避免number of issues在您不期望的时候尝试读取标准输入(显然不是在第二个命令中)。
考虑使用String.format来构建带有变量的复杂字符串。
考虑使用ProcessBuilder来更轻松地创建进程。在这里,我重定向错误,以便它们最终到达您的java进程stderr,这样您就可以在不使用线程的情况下读取子进程的stdout。See alternatives
所以这里有一个建议:
public static void main(String[] args) throws IOException, InterruptedException {
String INPUT_FILE = "/path/to/media";
String FFMPEG_PATH = "/path/to/ffmpegFolder";
for (int i = 0; (i + 4) < 40; i += 4) {
String command1 = String.format(
"%s/ffmpeg_4.1.1 -nostdin -ss %d -t 4 -i '%s' -ac 1 -acodec pcm_s16le -ar 16000 -f nut -",
FFMPEG_PATH, i, INPUT_FILE);
String command2 = String.format(
"%s/ffmpeg_4.1.1 -i - -lavfi showspectrumpic=s=128x75:legend=disabled:saturation=0:stop=8000",
FFMPEG_PATH);
Process process = new ProcessBuilder("sh", "-c", command1 + " | " + command2)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.start();
BufferedImage image = ImageIO.read(process.getInputStream());
// ...
}
}发布于 2019-03-18 04:55:22
在我看来,您正在阻塞正在关闭的stderr流。如果ffmpeg在退出之前没有关闭它的stderr (我并不期望它会这样做),那么你的程序就会死锁。
请改用带有pb.redirectErrorStream(true);的java.lang.ProcessBuilder。
在与waitFor();线程不同的线程上读取进程输出也是一个好主意,否则会有死锁的风险。
https://stackoverflow.com/questions/55149887
复制相似问题