2011-11-01 115 views
4

我正在运行一个签名的applet,它需要为用户提供选择输入和输出音频设备的能力(类似于Skype提供的)。在Applet中列出输入和输出音频设备

我借用其他thread下面的代码:

import javax.sound.sampled.*; 
public class SoundAudit { 
    public static void main(String[] args) { try { 
    System.out.println("OS: "+System.getProperty("os.name")+" "+ 
     System.getProperty("os.version")+"/"+ 
     System.getProperty("os.arch")+"\nJava: "+ 
     System.getProperty("java.version")+" ("+ 
     System.getProperty("java.vendor")+")\n"); 
     for (Mixer.Info thisMixerInfo : AudioSystem.getMixerInfo()) { 
     System.out.println("Mixer: "+thisMixerInfo.getDescription()+ 
      " ["+thisMixerInfo.getName()+"]"); 
     Mixer thisMixer = AudioSystem.getMixer(thisMixerInfo); 
     for (Line.Info thisLineInfo:thisMixer.getSourceLineInfo()) { 
      if (thisLineInfo.getLineClass().getName().equals(
       "javax.sound.sampled.Port")) { 
       Line thisLine = thisMixer.getLine(thisLineInfo); 
       thisLine.open(); 
       System.out.println(" Source Port: " 
       +thisLineInfo.toString()); 
       for (Control thisControl : thisLine.getControls()) { 
       System.out.println(AnalyzeControl(thisControl));} 
       thisLine.close();}} 
     for (Line.Info thisLineInfo:thisMixer.getTargetLineInfo()) { 
      if (thisLineInfo.getLineClass().getName().equals(
      "javax.sound.sampled.Port")) { 
      Line thisLine = thisMixer.getLine(thisLineInfo); 
      thisLine.open(); 
      System.out.println(" Target Port: " 
       +thisLineInfo.toString()); 
      for (Control thisControl : thisLine.getControls()) { 
       System.out.println(AnalyzeControl(thisControl));} 
      thisLine.close();}}} 
    } catch (Exception e) {e.printStackTrace();}} 
    public static String AnalyzeControl(Control thisControl) { 
    String type = thisControl.getType().toString(); 
    if (thisControl instanceof BooleanControl) { 
     return " Control: "+type+" (boolean)"; } 
    if (thisControl instanceof CompoundControl) { 
     System.out.println(" Control: "+type+ 
     " (compound - values below)"); 
     String toReturn = ""; 
     for (Control children: 
     ((CompoundControl)thisControl).getMemberControls()) { 
     toReturn+=" "+AnalyzeControl(children)+"\n";} 
     return toReturn.substring(0, toReturn.length()-1);} 
    if (thisControl instanceof EnumControl) { 
     return " Control:"+type+" (enum: "+thisControl.toString()+")";} 
    if (thisControl instanceof FloatControl) { 
     return " Control: "+type+" (float: from "+ 
     ((FloatControl) thisControl).getMinimum()+" to "+ 
     ((FloatControl) thisControl).getMaximum()+")";} 
    return " Control: unknown type";} 
} 

但我得到什么:

Mixer: Software mixer and synthesizer [Java Sound Audio Engine] 
Mixer: No details available [Microphone (Pink Front)] 

我期待得到我的设备的真实列表(我的喜好面板显示了3个输出设备和1个麦克风)。我在Mac OS X 10.6.7上运行。

有没有其他方法可以从Java获取该信息?

回答

3

多年来,它一直是OS X的Java实现的一个非常不幸的限制,BTW特别针对该平台,“Java声音音频引擎”是唯一可编程的输出音频li东北。因此,无论您发送到此行,即从您制作的任何Java应用程序中发出的任何内容,都将始终路由到OS X中默认输出的设置,通常是内置扬声器。所以JSAE只是用于“默认音频输出”的Java术语。根据我们的理解 - 可悲的是 - 最新版本仍然如此。

为什么不幸?因为它甚至可以有效地禁用谦逊的音频路由。我们每天都在处理这些问题,并要求增加各种复杂性。有解决方法,但通过第三方应用程序SoundFlower和HiJack Pro。例如www.soundPimp.com。

1

也许你可以修改和使用它。以下代码用于在我的两个Applets上选择音频输出设备。我只对输出线感兴趣,而不是端口或输入线。第一部分列出Menubar下拉菜单中选项组中的选项。第二部分根据选定的选项设置混合器变量。

private void createMenuBars(){ 
    JMenuBar menuBar = new JMenuBar(); 
    menuBar.setBounds(0, 0, 60, 20); 

    JMenu optionMenu = new JMenu("Options"); 
    JMenuItem pickMixers = new JMenuItem("Select a Playback Path"); 
    optionMenu.add(pickMixers); 
    optionMenu.addSeparator(); 

    ButtonGroup mixerSelections = new ButtonGroup(); 

    addMixerOption("default sound system", mixerSelections, optionMenu, true); 

    AudioFormat audioFmt = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
     44100, 16, 2, 4, 44100, false); 
    Mixer.Info[] mixers = AudioSystem.getMixerInfo(); 
    for (Mixer.Info info : mixers) 
    { 
     Mixer mixer = AudioSystem.getMixer(info); 

     try 
     { 
//   System.out.println(info); 
      Info sdlLineInfo = new DataLine.Info(SourceDataLine.class, audioFmt); 

      // test if line is assignable 
      @SuppressWarnings("unused") 
      SourceDataLine sdl = (SourceDataLine) mixer.getLine(sdlLineInfo); 

      // if successful, add to list 
      addMixerOption(info.getName() + " <> " + info.getDescription(), 
       mixerSelections, optionMenu, false); 
     } 
     catch (LineUnavailableException e) 
     { 
      //e.printStackTrace(); 
      System.out.println("Mixer rejected, Line Unavailable: " + info); 
     } 
     catch (IllegalArgumentException e) 
     { 
      //e.printStackTrace(); 
      System.out.println("Mixer rejected, Illegal Argument: " + info); 
     }   
    } 

    menuBar.add(optionMenu); 
    add(menuBar,0); 
} 

private void addMixerOption(String optionName, ButtonGroup bg, 
    JMenu menu, boolean isSelected 
{ 
    JRadioButtonMenuItem newOption = new JRadioButtonMenuItem(optionName); 
    bg.add(newOption); 
    newOption.setSelected(isSelected); 
    menu.add(newOption); 
    newOption.addActionListener(new OptionListener()); 
    newOption.setActionCommand(optionName); 
} 

这里是分别被选择的选项,当混合器变量获取设置。

public class OptionListener implements ActionListener 
{ 
    @Override 
    public void actionPerformed(ActionEvent arg0) 
    { 
     String optionName = arg0.getActionCommand(); 
     Boolean defaultMixer = true; 

     Mixer.Info[] mixers = AudioSystem.getMixerInfo(); 
     for (Mixer.Info info : mixers) 
     { 
      if (optionName.equals(info.getName()+" <> "+info.getDescription())) 
      { 
       System.out.println("Option selected > " + info.getName()); 
       System.out.println(" description > " + info.getDescription()); 
       System.out.println("   class > " + info.getClass()); 

       appMixer = AudioSystem.getMixer(info); 
       System.out.println(appMixer); 
       defaultMixer = false; 
      } 
     } 
     if (defaultMixer) 
     { 
      System.out.println("Using default mixer, whatever that is..."); 
      appMixer = null; 
     } 
    } 
} 

控制台消息过多。 我http://hexara.com/VSL/JTheremin.htm

+0

菲尔,谢谢你,但是你的代码和我的代码一样(就列出的设备而言)。我的Mac上有3个输出设备,但java声音API只列出了:“Java Sound Audio Engine”。这也是您的小应用程序首选项中的唯一选项。 –

+0

@Jhonny - 抱歉听到这没有更多的帮助。您是否看到了Option选项中的选项和被“拒绝”并在控制台上列出的选项?还没找到东西?拖动。 –

+0

是的,我得到了:混频器拒绝,非法参数:麦克风(粉红色后方),版本未知版本。但没有列出的输出设备。 –

1

这可能是要么在JVM不支持获取在OS X或您的设备,这个信息可能不支持使用此功能。我会做两件事情:

  • 不同的JVM尝试不同的OS
  • 尝试

我在linux上运行的代码,我正确地得到了所有的细节:

OS: Linux 2.6.38-12-generic/amd64 
Java: 1.6.0_22 (Sun Microsystems Inc.) 

Mixer: the ear-candy mixer [PulseAudio Mixer] 
Mixer: Direct Audio Device: default, default, default [default [default]] 
Mixer: Direct Audio Device: HDA Intel, ALC662 rev1 Analog, ALC662 rev1 Analog [Intel [plughw:0,0]] 
Mixer: Direct Audio Device: Plantronics Headset, USB Audio, USB Audio [Headset [plughw:1,0]] 
Mixer: Direct Audio Device: USB Device 0x46d:0x8b2, USB Audio, USB Audio [U0x46d0x8b2 [plughw:2,0]] 
Mixer: HDA Intel, Realtek ALC662 rev1 [Port Intel [hw:0]] 
    Source Port: Mic Boost source port 
    Control: Mic Boost (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
    Source Port: Capture source port 
    Control: Capture (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Select (boolean) 
    Source Port: Capture source port 
    Control: Capture (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Select (boolean) 
    Target Port: Master target port 
    Control: Master (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: Headphone target port 
    Control: Headphone (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: Speaker target port 
    Control: Speaker (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: PCM target port 
    Control: PCM (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: Line target port 
    Control: Line (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: Mic target port 
    Control: Mic (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
    Target Port: Mic Boost target port 
    Control: Mic Boost (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
Mixer: Plantronics Headset, USB Mixer [Port Headset [hw:1]] 
    Source Port: Bass source port 
    Control: Bass (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
    Source Port: Treble source port 
    Control: Treble (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
    Source Port: Mic source port 
    Control: Mic (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Select (boolean) 
    Target Port: Bass target port 
    Control: Bass (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
    Target Port: Treble target port 
    Control: Treble (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
    Target Port: PCM target port 
    Control: PCM (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Balance (float: from -1.0 to 1.0) 
     Control: Mute (boolean) 
Mixer: USB Device 0x46d:0x8b2, USB Mixer [Port U0x46d0x8b2 [hw:2]] 
    Source Port: Mic source port 
    Control: Mic (compound - values below) 
     Control: Volume (float: from 0.0 to 1.0) 
     Control: Select (boolean) 
+1

是的,这个问题只发生在Mac Os上。基本上,如果有一个适用于Mac和Win的api/native API。 –

+0

您使用的是最新的Oracle JVM吗?如果这不起作用,那么它一定是甲骨文无法实​​施它的严重原因。无论如何有一个desciption如何使用本机代码访问mac上的硬件:http://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Intro/AH_Intro.html –

+1

我使用默认随Mac OS X一起提供。我不能要求用户升级他们的JVM。 –