Tengo una aplicación de captura/reproducción Swing simple que tiene que detectar si no hay un micrófono apropiado conectado a la computadora y advertir al usuario. Después de una gran cantidad de volverse locos que he encontrado la única solución que me ha permitido detectar el micrófono recién instalado o extraído:Actualización de sonido Java Lista de líneas después de conectar un micrófono
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;
}
llamada en el subproceso de fondo de esta manera:
new Thread() {
public void run() {
while(!thisFrame.isClosed()){
if(isMicrophoneAvailable() == true){
//OK
}else{
//WARN
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
El problema es que aunque el dispositivo se detecta correctamente utilizando el método descrito, la lista de Líneas subyacentes no se actualiza. Es decir, cuando se inicia el programa, y el dispositivo se adjunta más adelante, la siguiente excepción se produce cuando se intenta grabar sonido:
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.
¿Hay alguna manera de obtener la lista de líneas de AudioSystem refrescado? ¿Tal vez algo similar a la solución alternativa JDK13Services
utilizada al principio para evitar el almacenamiento en caché?
ACTUALIZACIÓN: El código que genera una excepción:
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;
}
y la excepción en sí:
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.
Interesante pregunta, +1. Sin embargo, para comprobarlo, te das cuenta de la fragilidad de usar una clase en los paquetes 'com.sun', ¿verdad? Incluso en los JRE donde existe, podría ser eliminado/movido/renombrado en la próxima versión. –
De hecho, me doy cuenta de que esto es al menos una mala práctica, pero fue realmente mi último recurso. Supongo que se puede considerar como un error de implementación de Java Sound. –
Una de muchas. JavaSound es bueno para la gama limitada de cosas que pretende soportar, pero Sun nunca lo desarrolló realmente más. –