【发布时间】:2021-10-17 18:06:45
【问题描述】:
我希望能够调查系统支持的可用AudioFormat 类型,以便从一系列选项中选择合适的类型,使用帧速率和通道的首选值和备用值。
AudioSystem 不支持直接查询支持的音频格式,但我可以从Mixer 获得可用的SourceDataLine 列表。而SourceDataLine 继承了一个DataLine.Info 内部调用,它有一个返回可用格式的方法:getFormats ()。
所以我的主要问题是:有没有办法从 Java 音频系统中获取一组受支持的 AudioFormat 对象?
失败:有没有办法从Mixer 中获取支持的AudioFormat 对象数组?
如果失败了:是否可以从 SourceDataLine 获取 DataLine.Info 对象?
理想情况下,我想做一些类似的事情:
public void exec () {
Mixer.Info [] mixerInfoList = AudioSystem.getMixerInfo ();
for (Mixer.Info mixerInfo : mixerInfoList) {
System.out.println (mixerInfo.getDescription ());
Mixer mixer = AudioSystem.getMixer (mixerInfo);
Line.Info [] lineInfoList = mixer.getSourceLineInfo ();
for (Line.Info rawLineInfo : lineInfoList) {
System.out.println (" " + rawLineInfo.toString ());
DataLine.Info lineInfo = (DataLine.Info) rawLineInfo;
AudioFormat [] formats = lineInfo.getFormats ();
for (AudioFormat fmt : formats) {
System.out.println (" " + fmt.toString ());
}
}
}
}
但这在DataLine.Info lineInfo = (DataLine.Info) rawLineInfo; 行上失败了,因为rawLineInfo 显然是一个依赖于实现的对象,而不是DataLineInfo 的实例。
mixer.getSourceLineInfo () 没有返回DataLine.Info 的数组,这确实令人非常失望。没有理由不能,因为可以肯定地知道相关行是SourceDataLine 的实现,因此必须支持AudioFormat。
在接受的答案中使用@gpasch(感谢heaps buddy)提供的信息,这是我的最终解决方案。函数isDesirable 仅识别我感兴趣的音频格式。AudioFormatKey 类是一个包装器,它为distinct() 转换提供equals() 的实现,为sorted() 转换提供compareTo()。
public void exec () {
System.out.println ("Available formats (stream):");
Arrays.stream (AudioSystem.getSourceLineInfo (new Line.Info (SourceDataLine.class)))
.filter (info -> info instanceof DataLine.Info)
.map (info -> (DataLine.Info) info)
.flatMap (dlinfo -> Arrays.stream (dlinfo.getFormats ()))
.filter (this::isDesirable)
.map (AudioFormatKey::new)
.distinct ()
.sorted ()
.map (AudioFormatKey::getFormat)
.forEach (format -> System.out.println (" " + format));
}
【问题讨论】:
标签: java audioformat