连接麦克风后Java Sound刷新行列表

标签 java audio javasound

我有一个简单的捕获/回放 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.

最佳答案

以原始帖子为灵感,我想出了这个方法来检测麦克风何时丢失或获得。它会检测(在我的系统上)何时插入或拔下 USB 麦克风。我从后台线程循环中调用它。原来的方法对我不起作用,因为笔记本电脑上有一个内置麦克风,所以我需要检测第二个麦克风的添加。

...
//call this once somewhere to turn the caching period down for faster detection
    try
    {
        //try to set the caching period, defaults to something like 55 seconds
        com.sun.media.sound.JDK13Services.setCachingPeriod(5);
    }
    catch( Exception e)
    {
        System.err.println("exception attempting to call com.sun.media.sound.JDK13Services.setCachingPeriod->" + e);
    }
...

private int lastNumMics = -1;
private synchronized void micCheck()
{
    Line.Info[] lineInfoArray = AudioSystem.getSourceLineInfo(Port.Info.MICROPHONE);
    int numMics = lineInfoArray == null ? 0 : lineInfoArray.length;
    if( lastNumMics > -1 )
    {
        if( numMics < lastNumMics )
        {
            //MICROPHONE_LOST
        }
        else if( numMics > lastNumMics )
        {
            //MICROPHONE_GAINED
        }
    }
    lastNumMics = numMics;
}

关于连接麦克风后Java Sound刷新行列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9874713/

相关文章:

macos - AppleScript for Mavericks 中的语法错误

javascript - 将 javascript 音频移动到 jquery

java - 无法访问主目录 : Permission denied java. lang.IllegalArgumentException: 没有匹配接口(interface) SourceDataLine 的行

java - 按钮的 ActionListener

java - 如何读取输入的每一行并按排序顺序输出?

c++ - IMMDevice::Activate 缺少接口(interface)的返回代码

java - JAAD 阻止其他供应商工作

java - 如何从视频文件中提取音频并将其作为JavaSound AudioInputStream?

java - SQL异常 : Login failed for user ' ' JAVA

java - 热敏打印机java