【发布时间】:2012-03-26 15:10:51
【问题描述】:
我有一个简单的捕获/播放 Swing 应用程序,它必须检测计算机是否没有连接适当的麦克风并警告用户。经过大量的摆弄,我找到了唯一能让我检测到新连接或移除的麦克风的解决方案:
com.sun.media.sound.JDK13Services.setCachingPeriod(0);
private static boolean isMicrophoneAvailable() {
try {
if (!AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
log.debug("NO MICROPHONE FOUND");
return false;
} else {
log.debug("MICROPHONE FOUND");
return true;
}
} catch (IllegalArgumentException e) {
log.debug("INCONSISTENT");
}
return false;
}
这样在后台线程中调用:
new Thread() {
public void run() {
while(!thisFrame.isClosed()){
if(isMicrophoneAvailable() == true){
//OK
}else{
//WARN
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
问题在于,尽管使用所描述的方法可以正确检测到设备,但基础线路列表并未刷新。也就是在程序启动时,稍后附加设备时,尝试录制声音时会抛出以下异常:
java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported.
有什么方法可以刷新 AudioSystem 的行列表吗?也许类似于一开始使用的JDK13Services 解决方法以避免缓存?
更新:引发异常的代码:
AudioFormat format = formatControls.getDefaultFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format, line.getBufferSize());
} catch (LineUnavailableException ex) {
shutDown("No audio input device available. Please make sure that a microphone is attached to your computer");
return;
} catch (Exception ex) {
log.error(ex.toString());
shutDown(ex.toString());
return;
}
以及异常本身:
java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported.
【问题讨论】:
-
有趣的问题,+1。只是检查一下,您确实意识到在
com.sun包中使用类的脆弱性,对吧?即使在它存在的 JRE 中,它也可能在下一个版本中被删除/移动/重命名。 -
确实,我确实意识到这至少是一种不好的做法,但这确实是我最后的手段。我想它可以被认为是一个 Java Sound 实现缺陷。
-
众多之一。 JavaSound 对于它旨在支持的有限范围的东西很有用,但 Sun 从未真正进一步开发它。