Java 执行exe并读取OutputStream
我有一个名为FFprobe的程序,它探测媒体(文件/实时流…)并以不同格式输出结果,例如: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.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);
}
}