首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >-f使用(管道) "... -i -| ffmpeg ffmpeg - ...“执行ffmpeg命令就这么挂了

-f使用(管道) "... -i -| ffmpeg ffmpeg - ...“执行ffmpeg命令就这么挂了
EN

Stack Overflow用户
提问于 2019-03-14 03:30:40
回答 2查看 1.3K关注 0票数 7

我不能让它运行,因为java只是在等待ffmpeg。但是ffmpeg没有给出输入,也没有给出错误流。它只是运行,但什么也不做。

"System.out.println("command:..“insert into bash )的输出运行得很好,因为expected.So语法没有任何问题。

这是代码。

代码语言:javascript
复制
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
            }

    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

所以这里有一个建议:

代码语言:javascript
复制
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());
        // ...
    }
}
票数 5
EN

Stack Overflow用户

发布于 2019-03-18 04:55:22

在我看来,您正在阻塞正在关闭的stderr流。如果ffmpeg在退出之前没有关闭它的stderr (我并不期望它会这样做),那么你的程序就会死锁。

请改用带有pb.redirectErrorStream(true);java.lang.ProcessBuilder

在与waitFor();线程不同的线程上读取进程输出也是一个好主意,否则会有死锁的风险。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55149887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档