È ansible utilizzare Java Sound per controllare il volume del sistema?

Java Sound offre istanze FloatControl per varie funzionalità della linea audio e un tipo di controllo MASTER_GAIN e VOLUME .

Questi controlli possono essere utilizzati per modificare il volume del sistema?

No non può. Ecco la fonte adattata da una risposta a Regolazione del volume principale su coderanch. L’origine itera le linee disponibili, controlla se hanno il controllo del tipo giusto e, in tal caso, le inserisce in una GUI collegata a un 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; } } 

Su questa macchina Windows 7 ottengo due controlli, entrambi dal “Java Sound Audio Engine”. Né ha alcun effetto sul volume di sistema corrente.

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

Scambia FloatControl.Type.MASTER_GAIN per FloatControl.Type.VOLUME per vedere .. nessun controllo.

aggiungi la riga seguente subito dopo l’inizializzazione di Line. questo è necessario per aprire la linea.

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

prova questo non ti deluderà …. possiamo modificare di conseguenza l’esempio superiore.

 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 

Sto usando il tipo di controllo VOLUME . Questo codice funziona per me per XP e WIN 7, ma non per OSX. Vedi il mio esempio:

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

Recentemente ho focalizzato lo stesso problema. Alla fine ho deciso di scrivere un piccolo programma chiamato VolumeChanger.exe in C ++ e chiamarlo da java. Funziona alla grande. Puoi chiamare un exe di java con

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

wehre vcpath è il percorso verso il tuo file exe (potrebbe essere certamente realtive).

Se sei interessato a come ho usato questo strumento, visita me su muteFritz

Se sei interessato a tutto il codice sorgente, non esitare a parlarmi di me …

Ecco una soluzione che funziona SOLO su OS X (I am running 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); } } } 

Chiameresti il ​​metodo in questo modo:

 MasterVolume.setMasterVolume(3.5f); 

Quale regolerebbe il volume al 50% poiché l’intervallo è da .1 a 7.0