9

Java SoundはFloatControl、さまざまなサウンドライン機能のインスタンスと、MASTER_GAINVOLUMEコントロールタイプの両方を提供します。

これらのコントロールを使用して、システムボリュームを変更できますか?

4

6 に答える 6

11

いいえ、できません。これは、coderanchでのマスターボリュームの調整に対する回答から適合したソースです。ソースは使用可能な行を繰り返し、それらが正しいタイプのコントロールを持っているかどうかをチェックし、そうであれば、それらをに接続されたGUIに配置します。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;
    }
}

このWindows7マシンでは、「JavaSoundAudioEngine」から2つのコントロールを取得します。どちらも現在のシステムボリュームには影響しません。

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てください..コントロールなし。

于 2013-01-13T07:47:13.513 に答える
1

Lineが初期化された直後に次の行を追加します。これは、回線を開くために必要です。

boolean opened = line.isOpen() || line instanceof Clip;
if(!opened){
    System.out.println("Line is not open, trying to open it...");
    line.open();
    opened = true;
}
于 2013-04-18T06:48:06.857 に答える
1

これを試してみてください。失望することはありません。それに応じて上の例を変更できます。

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();
}
}
于 2013-04-18T15:43:41.550 に答える
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);
        }
    }
}
于 2013-05-15T17:47:47.400 に答える
0

私は最近同じ問題に焦点を合わせていました。結局、VolumeChanger.exeという小さなプログラムをC ++で作成し、これをJavaから呼び出すことにしました。よく働く。Javaからexeを呼び出すことができます

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

wehre vcpathは、exeファイルへのパスです(もちろん現実的かもしれません)。

このツールの使用方法に興味がある場合は、muteFritzにアクセスしてください。

ソースコード全体に興味がある場合は、PMまでお気軽に...

于 2013-12-26T18:47:17.550 に答える
0

これはOSXでのみ機能するソリューションです(私は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%に設定します。

于 2015-02-06T11:39:29.373 に答える