Java 执行exe并读取OutputStream

Java 执行exe并读取OutputStream,java,parsing,ffmpeg,inputstream,apache-commons,Java,Parsing,Ffmpeg,Inputstream,Apache Commons,我有一个名为FFprobe的程序,它探测媒体(文件/实时流…)并以不同格式输出结果,例如: ffprobe.exe -i test.ts -print_format xml -show_programs 给出此输出: <?xml version="1.0" encoding="UTF-8"?> <ffprobe> <programs> <program program_id="1201" program_num="120

我有一个名为FFprobe的程序,它探测媒体(文件/实时流…)并以不同格式输出结果,例如:

ffprobe.exe -i test.ts -print_format xml -show_programs
给出此输出:

    <?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
    <programs>
        <program program_id="1201" program_num="1201" nb_streams="2" pmt_pid="1000" pcr_pid="2011" start_pts="45394227044" start_time="45394.227044">
            <tag key="service_name" value="Arabica TV"/>
            <tag key="service_provider" value="Nilesat"/>
            <streams>
                <stream index="10" codec_name="mpeg2video" codec_long_name="MPEG-2 video" profile="Main" codec_type="video" codec_time_base="1/50" codec_tag_string="[2][0][0][0]" codec_tag="0x0002" width="720" height="576" has_b_frames="1" sample_aspect_ratio="16:15" display_aspect_ratio="4:3" pix_fmt="yuv420p" level="8" timecode="08:28:54:09" id="0x7db" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/90000" start_pts="4085542516" start_time="45394.916844" max_bit_rate="2348000">
                    <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
                </stream>
                <stream index="4" codec_name="mp2" codec_long_name="MP2 (MPEG audio layer 2)" codec_type="audio" codec_time_base="1/48000" codec_tag_string="[0][0][0][0]" codec_tag="0x0000" sample_fmt="s16p" sample_rate="48000" channels="2" channel_layout="stereo" bits_per_sample="0" id="0xbcf" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/90000" start_pts="4085480434" start_time="45394.227044" bit_rate="384000">
                    <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
                </stream>
            </streams>
        </program> 
... more programs 
应用程序只是挂起,没有输出,我知道它挂起,因为进程仍在运行,扫描仪还有下一个,但是,我不知道为什么它会这样做?如果我在cmd中执行相同的命令,我会得到很好的结果,ofc我可以用“>”写入文件

我尝试过使用-print_format选项,它在错误流上以纯文本形式提供信息(我知道它的错误,因为我可以用2>而不是>>),我可以用java读取错误流,但它不是用来解析错误流的,因为它没有组织

   Input #0, mpegts, from 'PBR_REC_20140426094852_486.ts':
  Duration: 00:13:34.30, start: 7791.344722, bitrate: 42154 kb/s
  Program 1201 
    Metadata:
      service_name    : Arabica TV
      service_provider: Nilesat
    Stream #0:19[0x7db]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], max. 2348 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:3[0xbcf]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
  Program 1202 
    Metadata:
      service_name    : NBN
      service_provider: NILESAT
    Stream #0:10[0x7d1]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], max. 2600 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:11[0xbba](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 125 kb/s
  Program 1203 
    Metadata:
      service_name    : Heya TV
      service_provider: NILESAT
    Stream #0:5[0x7d2]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv), 720x576 [SAR 16:15 DAR 4:3], max. 2600 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:6[0xbbc](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 125 kb/s
  Program 1204  ... more programs
现在它可能看起来是有组织的,并且“可以解析”,我实际上做了一个解析器,在某种程度上可以工作,但有时它不会坚持这种结构并破坏整个解析,这就是为什么我需要一个xml/json

-print_格式确保输出到outputstream

我不是在寻求关于如何使用FFprobe的帮助,因为这不是这个地方的目的,我是在问为什么我不能从java获取输出流,而如果我在windows中执行,它肯定会输出

我还尝试了ApacheCommonsExec,因为我知道processbuilder可能会很麻烦,它确实执行得很好,并显示在System.in中(黑色表示输入,红色表示错误),但是用apache获取流是我不理解的,我尝试了这个


我已经处理过的xml解析器,简单地说,我只需要从java执行第一个命令并读取输出,但由于某些原因,它不起作用。

我通常使用此实用程序方法的变体:

public static void runProcess(ProcessBuilder pb) throws IOException {
    pb.redirectErrorStream(true);
    Process p = pb.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

即使您不想打印错误流,您也需要使用它,否则它将阻塞进程。在这种情况下,您需要在单独的线程中使用它,并且只打印来自主线程的输入流。

您的ffprobe进程可能正在等待标准输入。解决此问题的最简单方法是在启动进程之前,在您的ProcessBuilder上调用
redirectInput(ProcessBuilder.Redirect.INHERIT)
。@VGR,这不起作用。我尝试一下,但这与我所做的有何不同?它确实起作用,但输出错误和输入流(混淆),你能解释一下它和我做的有什么不同吗,基本上你用的是BufferedReader,我用的是scanner@vlatkozelka如果重定向错误流,您的版本是否工作?即使您不想打印错误流,您也需要使用它,否则它将阻塞进程。在这种情况下,您需要在一个单独的线程中使用它,并且只打印来自主线程的输入流!在读取inputstream时,我启动了一个新线程来使用错误流,它工作得很好:)我想使用错误是必须的,我不知道。。。你能编辑一下你的答案吗?只是为了其他人
public static void runProcess(ProcessBuilder pb) throws IOException {
    pb.redirectErrorStream(true);
    Process p = pb.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}