2013-01-13 74 views

回答

11

不,它不能。這裏的源代碼是根據代碼分支上的Adjusting master volume的答案改編的。該人士遍歷可用的線路,檢查他們是否有正確類型的控制,如果是的話,把他們連接到JSlider

import java.awt.*; 
import javax.swing.*; 
import javax.sound.sampled.*; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class SoundMixer { 

    public Component getGui() { 
     JPanel gui = new JPanel(new GridLayout(0,1)); 

     Mixer.Info[] mixers = AudioSystem.getMixerInfo(); 
     System.out.println(
       "There are " + mixers.length + " mixer info objects"); 
     for (Mixer.Info mixerInfo : mixers) { 
      System.out.println("mixer name: " + mixerInfo.getName()); 
      Mixer mixer = AudioSystem.getMixer(mixerInfo); 
      Line.Info[] lineInfos = mixer.getSourceLineInfo(); 
      for (Line.Info lineInfo : lineInfos) { 
       System.out.println(" Line.Info: " + lineInfo); 
       try { 
        Line line = mixer.getLine(lineInfo); 
        FloatControl volCtrl = (FloatControl)line.getControl(
          FloatControl.Type.MASTER_GAIN); 
        VolumeSlider vs = new VolumeSlider(volCtrl); 
        gui.add(new JLabel(volCtrl.toString())); 
        gui.add(vs.getVolume()); 
        System.out.println(
          " volCtrl.getValue() = " + volCtrl.getValue()); 
       } catch (LineUnavailableException e) { 
        e.printStackTrace(); 
       } catch (IllegalArgumentException iaEx) { 
        System.out.println(" " + iaEx); 
       } 
      } 
     } 

     return gui; 
    } 

    public static void main(String[] args) { 
     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       SoundMixer sm = new SoundMixer(); 
       Component c = sm.getGui(); 
       JOptionPane.showMessageDialog(null, c); 
      } 
     }; 
     // Swing GUIs should be created and updated on the EDT 
     // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html 
     SwingUtilities.invokeLater(r); 
    } 
} 

class VolumeSlider { 

    JSlider volume; 

    VolumeSlider(final FloatControl volumeControl) { 
     volume = new JSlider(
       (int) volumeControl.getMinimum() * 100, 
       (int) volumeControl.getMaximum() * 100, 
       (int) volumeControl.getValue() * 100); 
     ChangeListener listener = new ChangeListener() { 

      @Override 
      public void stateChanged(ChangeEvent e) { 
       float val = volume.getValue()/100f; 
       volumeControl.setValue(val); 
       System.out.println(
         "Setting volume of " + volumeControl.toString() + 
         " to " + val); 
      } 
     }; 
     volume.addChangeListener(listener); 
    } 

    public JSlider getVolume() { 
     return volume; 
    } 
} 

在這個Windows 7的機器,我得到兩個控件界面,無論是從「Java聲音音頻引擎」。對當前系統音量沒有任何影響。

run: 
There are 4 mixer info objects 
mixer name: Primary Sound Driver 
    Line.Info: interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes 
    java.lang.IllegalArgumentException: Unsupported control type: Master Gain 
    Line.Info: interface Clip supporting 8 audio formats, and buffers of at least 32 bytes 
    java.lang.IllegalArgumentException: Unsupported control type: Master Gain 
mixer name: Speakers (VIA High Definition Audio) 
    Line.Info: interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes 
    java.lang.IllegalArgumentException: Unsupported control type: Master Gain 
    Line.Info: interface Clip supporting 8 audio formats, and buffers of at least 32 bytes 
    java.lang.IllegalArgumentException: Unsupported control type: Master Gain 
mixer name: Java Sound Audio Engine 
    Line.Info: interface SourceDataLine supporting 8 audio formats 
    volCtrl.getValue() = 0.0 
    Line.Info: interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes 
    volCtrl.getValue() = 0.0 
mixer name: Port Speakers (VIA High Definition A 
Setting volume of Master Gain with current value: 0.0 dB (range: -80.0 - 13.9794) to 0.0 
Setting volume of Master Gain with current value: 0.0 dB (range: -80.0 - 13.9794) to -0.41 
Setting volume of Master Gain with current value: 0.0 dB (range: -80.0 - 13.9794) to -0.68 
... 

交換FloatControl.Type.MASTER_GAINFloatControl.Type.VOLUME看到..沒有控制。

+1

+1很好的例子 –

+0

所以你在這裏說的是它不是*可能的。這是一個JDK錯誤? – rogerdpack

+2

@rogerdpack JSE沒有要求控制系統音量,所以我想,不。但隨時可以打開Oracle的錯誤報告,並直接從製造商處獲得答案。 –

1

在初始化行後添加以下行。這是打開線路所必需的。

boolean opened = line.isOpen() || line instanceof Clip; 
if(!opened){ 
    System.out.println("Line is not open, trying to open it..."); 
    line.open(); 
    opened = true; 
} 
+0

不錯的一個。但是,雖然這裏顯示了兩個更多的FloatControl.Type.MASTER_GAIN *行,但它們都沒有影響系統音量。 *仍然爲0 FloatControl.Type.VOLUME –

+0

請檢查以下代碼。 –

0

試試這個吧不會讓你失望....我們可以相應地修改上面的例子。

import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.Line; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.Mixer; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JProgressBar; 

public class SoundMeter { 

JFrame j; 

public SoundMeter() { 
    j = new JFrame("SoundMeter"); 
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    j.setLayout(new BoxLayout(j.getContentPane(), BoxLayout.Y_AXIS)); 
    printMixersDetails(); 
    j.setVisible(true); 
} 
public void printMixersDetails(){ 
    javax.sound.sampled.Mixer.Info[] mixers = AudioSystem.getMixerInfo(); 
    System.out.println("There are " + mixers.length + " mixer info objects"); 
    for(int i=0;i<mixers.length;i++){ 
     Mixer.Info mixerInfo = mixers[i]; 
     System.out.println("Mixer Name:"+mixerInfo.getName()); 
     Mixer mixer = AudioSystem.getMixer(mixerInfo); 
     Line.Info[] lineinfos = mixer.getTargetLineInfo(); 
     for(Line.Info lineinfo : lineinfos){ 
      System.out.println("line:" + lineinfo); 
      try { 
       Line line = mixer.getLine(lineinfo); 
       line.open(); 
       if(line.isControlSupported(FloatControl.Type.VOLUME)){ 
        FloatControl control = (FloatControl) line.getControl(FloatControl.Type.VOLUME); 
        System.out.println("Volume:"+control.getValue()); 
        JProgressBar pb = new JProgressBar(); 
        // if you want to set the value for the volume 0.5 will be 50% 
        // 0.0 being 0% 
        // 1.0 being 100% 
        control.setValue((float) 0.5); 
        int value = (int) (control.getValue()*100); 
        pb.setValue(value); 
        j.add(new JLabel(lineinfo.toString())); 
        j.add(pb); 
        j.pack(); 
       } 
      } catch (LineUnavailableException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
public static void main(String[] args) { 
    new SoundMeter(); 
} 
} 
+0

此代碼將使系統音量達到由代碼控制的50%:control.setValue((float)0.5); –

+2

這似乎並沒有調整主音量對我來說(贏7) – rogerdpack

0

我正在使用VOLUME控制類型。此代碼適用於XP和WIN 7,但不適用於OSX。看我的例子:

import java.io.IOException; 

import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.Line; 
import javax.sound.sampled.Mixer; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class VolumeExample extends JPanel { 

/** 
* @return main sound control object 
* @throws Exception for any problem 
*/ 
private FloatControl getVolumeControl() throws Exception { 
    try { 
     Mixer.Info mixers[] = AudioSystem.getMixerInfo(); 
     for (Mixer.Info mixerInfo : mixers) { 
      Mixer mixer = AudioSystem.getMixer(mixerInfo); 
      mixer.open(); 

      //we check only target type lines, because we are looking for "SPEAKER target port" 
      for (Line.Info info : mixer.getTargetLineInfo()) { 
       if (info.toString().contains("SPEAKER")) { 
        Line line = mixer.getLine(info); 
        try { 
         line.open(); 
        } catch (IllegalArgumentException iae) {} 
        return (FloatControl) line.getControl(FloatControl.Type.VOLUME); 
       } 
      } 
     } 
    } catch (Exception ex) { 
     System.out.println("problem creating volume control object:"+ex); 
     throw ex; 
    } 
    throw new Exception("unknown problem creating volume control object"); 
} 

    VolumeExample() { 
     JSlider slider = new JSlider(); 
     add(slider); 

     //this is for setting the value 
     slider.addChangeListener(new ChangeListener() { 

      @Override 
      public void stateChanged(ChangeEvent e) { 
       JSlider src = (JSlider)e.getSource(); 
       //if (src.getValueIsAdjusting()) return; //optional 
       if (src.getValue() % 5 !=0) return; 
       float value = src.getValue()/100.0f; 
       try { 
        getVolumeControl().setValue(value); 
        //you can put a click play code here to have nice feedback when moving slider 
       } catch (Exception ex) { 
        System.out.println(ex); 
       } 
      } 
     }); 

     //and this is for getting the value 
     try { 
      slider.setValue((int) (getVolumeControl().getValue()*100.0f)); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 
} 
+2

上述代碼不會更改Windows 7上的主音量。 – Torque

0

我最近集中了同樣的問題。最後,我決定用C++編寫一個名爲VolumeChanger.exe的小程序,並從java中調用它。很棒。 wehre vcpath是通向你的exe文件(可能是realtive當然的),你可以從Java調用一個exe與

Process process = new ProcessBuilder(vcpath,"-u").start();

如果你有興趣我是如何使用這個工具查看我的muteFritz

如果你有興趣在整個源代碼,隨時下午我......

0

這是隻有在有效的解決方案OS X(我正在10.10):

import java.io.BufferedReader; 
import java.io.File; 
import java.io.InputStreamReader; 

public class MasterVolume 
{ 
    public void setMasterVolume(float value) 
    { 
     String command = "set volume " + value; 
     try 
     { 
      ProcessBuilder pb = new ProcessBuilder("osascript","-e",command); 
      pb.directory(new File("/usr/bin")); 
      System.out.println(command); 
      StringBuffer output = new StringBuffer(); 
      Process p = pb.start(); 
      p.waitFor(); 

      BufferedReader reader = 
        new BufferedReader(new InputStreamReader(p.getInputStream())); 

      String line; 
      while ((line = reader.readLine())!= null) 
      { 
       output.append(line + "\n"); 
      } 
      System.out.println(output); 
     } 
     catch(Exception e) 
     { 
      System.out.println(e); 
     } 
    } 
} 

你會調用該方法是這樣的:

MasterVolume.setMasterVolume(3.5f); 

由於範圍是.1到7.0,它將音量設置在50%

+0

鑑於它不使用Java聲音,我不明白這是如何回答這個問題問(這是非常具體的'使用Java聲音')。 –

+0

代碼是否會更改整個系統聲音值或用於音頻播放器幀中的某些特定媒體應用程序? – user390525

相關問題