我正在学习Java Sound API来捕获和回放音频。它与笔记本电脑的内置声卡工作得很好,这是一个“Realtek”。
另外,我有一个带音频适配器的USB耳机,这是一个“Plantronics”。一旦我插入“Plantronics”USB耳机,Java Sound API只能检测USB耳机的混音器,延迟超过1分钟。反之,如果拔掉USB耳机,Java Sound API只能延迟清除USB耳机的历史混音器。
以下是我用来检索音频设备和检测热插拔音频设备的源代码:
1)检索音频设备: 我使用音频设备名称而不是混音器索引来检测音频设备是由于热插拔USB耳机的混音器索引是每次插件或插件动态更改。
public static Mixer getMixer(final String mixerName,
final String mixerDesc) {
Mixer mixer = null;
if (mixerName != null) {
Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();
logger.trace("Mixer infos list size[" + mixerInfos.length + "]");
for (int i = 0; i < mixerInfos.length; i++) {
if (mixerInfos[i].getName().contains(mixerName)
&& (mixerDesc == null || mixerDesc.length() == 0
|| mixerInfos[i].getDescription().contains(mixerDesc))) {
mixer = AudioSystem.getMixer(mixerInfos[i]);
break;
}
}
}
return mixer;
}
2)检测热插拔音频设备:
private void doCheckMixerAvailability() {
while (true) {
Mixer newMixer = null;
if (mixerName != null && mixerDesc != null) {
newMixer = AudioUtil.getMixer(mixerName, mixerDesc);
}
if (newMixer != null) {
getLogger().trace("Get new Mixer based on mixerName[" + mixerName
+ "], mixerDesc[" + mixerDesc + "]");
}
// check current mixer and target line
if (mixer != null && targetLine != null) {
// if current mixer and target line are not NULL, check whether new mixer is NULL
if (newMixer == null) {
// reset members
mixer = null;
targetLine.stop();
targetLine.flush();
targetLine.close();
targetLine = null;
getLogger().trace("Audio port [" + this.getPortId() + "] with mixerName[" + mixerName
+ "], mixerDesc[" + mixerDesc + "] become NOT available");
// callback if listener is set
if (getAvailableListener() != null) {
getAvailableListener().availableChange(false, this.getClass(), this.getPortId());
getLogger().trace("clear targetLine with format [" + getAudioFormat()
+ "after mixerName[" + mixerName + "], mixerDesc["
+ mixerDesc + "] become NOT available");
}
}
} else {
// if current mixer is NULL or target line is NULL, check whether new mixer is not NULL
if (newMixer != null) {
// update members
mixer = newMixer;
// try to create target line
createTargetLine();
// check whether create target line succeeded
if (targetLine != null) {
getLogger().trace("Audio port [" + this.getPortId() + "] with mixerName[" + mixerName
+ "], mixerDesc[" + mixerDesc + "] become available");
// callback if listener is set
if (getAvailableListener() != null) {
getAvailableListener().availableChange(true, this.getClass(), this.getPortId());
getLogger().trace("create targetLine with format [" + getAudioFormat()
+ "after mixerName[" + mixerName + "], mixerDesc["
+ mixerDesc + "] become available");
}
} else {
// reset current mixer again
mixer = null;
}
}
} // end check current mixer and target line
try {
Thread.sleep(checkMixerIntervalMs);
} catch (InterruptedException e) {
getLogger().debug("CheckMixerAvailability thread interrupted");
}
}
}
就个人而言,我认为Java会在较低级别缓存混音器信息。如果假设是正确的,那么无论如何都不保留混音器信息缓存?如果没有,是否有其他方法可以通过Java或Java库有效地检测热插拔音频设备?
感谢您的亲切分享。