O Java Sound pode ser usado para controlar o volume do sistema?

O Java Sound oferece instâncias FloatControl para várias funcionalidades de linha de som e um tipo de controle MASTER_GAIN & VOLUME .

Esses controles podem ser usados ​​para alterar o volume do sistema?

Não, eu não posso. Aqui está uma fonte adaptada de uma resposta para Ajustar o volume principal no coderanch. A fonte repete as linhas disponíveis, verifica se elas têm um controle do tipo correto e, em caso afirmativo, as coloca em uma GUI conectada a um 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; } } 

Nesta máquina com Windows 7 eu recebo dois controles, ambos do “Java Sound Audio Engine”. Nenhum dos dois efeitos afeta o volume atual do sistema.

 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 ... 

Troque FloatControl.Type.MASTER_GAIN para FloatControl.Type.VOLUME para ver .. sem controles.

adicione a seguinte linha logo após a linha ser inicializada. isso é necessário para abrir a linha.

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

tente isso não vai desapontá-lo …. podemos modificar exemplo superior em conformidade.

 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 

Eu estou usando o tipo de controle VOLUME . Este código funciona para mim no XP e no WIN 7, mas não no OSX. Veja meu exemplo:

 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); } } } 

Eu estava recentemente focando o mesmo problema. No final, decidi escrever um pequeno programa chamado VolumeChanger.exe em C ++ e chamar isso de java. Funciona bem. Você pode chamar um exe de java com

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

wehre vcpath é o caminho para o seu arquivo exe (pode ser realista, claro).

Se você está interessado em como eu usei essa ferramenta, me visite no muteFritz

Se você está interessado em todo o código-fonte sinta-se livre para mim PM …

Aqui está uma solução que funciona apenas no OS X (eu estou executando 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); } } } 

Você chamaria o método assim:

 MasterVolume.setMasterVolume(3.5f); 

Qual seria definir o volume em 50% desde que o intervalo é 0,1 a 7,0