【发布时间】:2014-11-25 11:04:30
【问题描述】:
我有一个名为 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
为了在 java 中检索此信息,我使用了 ProcessBuilder 和扫描仪,然后在结果正常后将 id 写入文件......但它不是:
Process proc = new ProcessBuilder("ffprobe.exe","-i", ... same arguments );
Scanner sc = new Scanner (proc.getInputStream()) // im 100% sure its not errorStream
while(sc.hasNext()){
System.out.println(sc.nextLine());
}
应用程序只是挂起,没有输出,我知道它挂起,因为进程仍在运行,扫描仪有下一个,但是,我不知道它为什么会这样做?如果我在 cmd 中执行相同的操作,我会好起来的结果和ofc我可以用“>”写入文件
我试过不带 -print_format 选项,它在错误流上以纯文本形式提供信息(我知道它的错误,因为我能够用 2> 而不是 >> 写入),我能够阅读java中的错误流,但它并不意味着解析cuz非常非常无组织。
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_format 肯定会输出到 outputstream。
我不是在寻求有关如何使用 FFprobe 的帮助,因为那不是这个地方的目的,我在问为什么我无法从 java 获取输出流,而如果我在 windows 中执行它肯定会输出。
我也尝试了 apache commons-exec,因为我知道 processbuilder 可能会很痛苦,它确实执行得很好,并在 System.in 中显示(黑色表示输入,红色表示错误),但使用 apache 获取流是我做不到的不明白,我试过这个example
我已经处理过的 xml 解析器,简单地说,我只需要从 java 执行第一个命令并读取输出,但由于某种原因它不起作用。
【问题讨论】:
-
您的 ffprobe 进程可能正在等待标准输入。解决此问题的最简单方法是在开始进程之前在 ProcessBuilder 上调用
redirectInput(ProcessBuilder.Redirect.INHERIT)。 -
@VGR,没用
标签: java parsing ffmpeg inputstream apache-commons