>

인터넷에서 mp3 데이터의 입력 스트림을 재생하기 위해 JLayer를 사용하고 있습니다. 출력 음량을 어떻게 변경합니까?

이 코드를 사용하여 재생하고 있습니다 :

URL u = new URL(s);
URLConnection conn = u.openConnection();  
conn.setConnectTimeout(Searcher.timeoutms);  
conn.setReadTimeout(Searcher.timeoutms);
bitstream = new Bitstream(conn.getInputStream()/*new FileInputStream(quick_file)*/);
System.out.println(bitstream);
decoder = new Decoder();
decoder.setEqualizer(equalizer);
audio = FactoryRegistry.systemRegistry().createAudioDevice();
audio.open(decoder);
for(int i = quick_positions[0]; i > 0; i--){
    Header h = bitstream.readFrame();
    if (h == null){
        return;
    }
bitstream.closeFrame();


  • 답변 # 1

    이것은 받아 들일 수없는 해킹이라고 생각할 수 있지만, 내가 작성한 MP3 플레이어에서 작동했습니다. JLayer 클래스 중 하나에 작은 코드를 추가해야합니다.

    javazoom.jl.player.JavaSoundAudioDevice에 다음 메소드를 추가하십시오.

    public void setLineGain(float gain)
    {
        if (source != null)
        {
            FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN);
            float newGain = Math.min(Math.max(gain, volControl.getMinimum()), volControl.getMaximum());
            volControl.setValue(newGain);
        }
    }
    
    

    이 새로운 방법을 사용하면 이와 같은 코드로 볼륨을 변경할 수 있습니다.

    if (audio instanceof JavaSoundAudioDevice)
    {
        JavaSoundAudioDevice jsAudio = (JavaSoundAudioDevice) audio;
        jsAudio.setLineGain(yourGainGoesHere);
    }
    
    

  • 답변 # 2

    PC의 스피커 볼륨을 조정하는 다른 방법 (JLayer가 아닌)은 Sun/Oracle에서 제공하는 javax.sound.sampled 패키지의 클래스를 사용하는 것입니다.

    내 컴퓨터에서는 SPEAKER가 유일하게 지원되는 출력 대상이었습니다.

    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.FloatControl;
    import javax.sound.sampled.Line.Info;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.Port;
    public class SoundVolumeDemo 
    {
        public static void main(String[] args) 
    {        
        Info source = Port.Info.SPEAKER;
        //        source = Port.Info.LINE_OUT;
        //        source = Port.Info.HEADPHONE;
            if (AudioSystem.isLineSupported(source)) 
            {
                try 
                {
                    Port outline = (Port) AudioSystem.getLine(source);
                    outline.open();                
                    FloatControl volumeControl = (FloatControl) outline.getControl(FloatControl.Type.VOLUME);                
                    System.out.println("       volume: " + volumeControl.getValue() );
                    float v = 0.33F;
                    volumeControl.setValue(v);
                    System.out.println("   new volume: " + volumeControl.getValue() );
                    v = 0.73F;
                    volumeControl.setValue(v); 
                    System.out.println("newest volume: " + volumeControl.getValue() );
                } 
                catch (LineUnavailableException ex) 
                {
                    System.err.println("source not supported");
                    ex.printStackTrace();
                }            
            }
        } 
     }
    
    

    이 앱에서 볼륨을 조절하는 방법입니다 :

    http://onebeartoe.com/media-players/randomjuke/filesystem/java-web-start/swing/index.jsp

    MS Windows OS 시스템에서만 작동 한 경험이 있습니다.

  • 답변 # 3

    이퀄라이저의 모든 대역을 조정하려는 볼륨에 맞게 조정하십시오. 어쩌면 EQFunction을 사용할 수도 있습니까?

    public class ChangeVolumeFunction extends EQFunction {
        public double volume = 1.0;
        public void setVolume(double volume) { this.volume = volume; }
        public float getBand(int band) { return (float) (Math.log(volume) / Math.log(2) * 6.0); }
    }
    
    

  • 답변 # 4

    ChrisH의 답변으로 나만의 버전을 만들었지 만 JLayer의 소스 코드를 변경하는 대신 리플렉션을 통해 수행했습니다.

    Class<JavaSoundAudioDevice> clazz = JavaSoundAudioDevice.class;
    Field[] fields = clazz.getDeclaredFields();
    try{
        SourceDataLine source = null;
            for(Field field : fields) {
                if("source".equals(field.getName())) {
                    field.setAccessible(true);
                    source = (SourceDataLine) field.get(device);
                    field.setAccessible(false);
                    FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN);
                    if (volControl != null) {
                         float newGain = Math.min(Math.max(gain, volControl.getMinimum()), volControl.getMaximum());
                         volControl.setValue(newGain);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    

    조잡하지만, 작동합니다

  • 이전 Swift Markup 언어에서 "예제"와 같이 기본 렌더링 된 제목의 이름을 바꿉니다
  • 다음 JSON ARRAY 데이터를 Android의 서버에 게시하는 방법