Работа с аудиоплеером на Java

#java #swing

#java #swing

Вопрос:

В моем приложении swing я использую класс для воспроизведения звука при щелчке мыши. Проблема, с которой я сталкиваюсь, заключается в том, что когда я вызываю класс, звук воспроизводится один раз, и когда внезапно нажимается другая кнопка, звук не воспроизводится. Я пытался ввести задержку в свой код, но идентификатор по-прежнему работает не так, как я ожидал. Это как-то связано с потоками?? Я не силен в потоках, поэтому, пожалуйста, скажите мне, как это сделать. Код, который я использую, выглядит следующим образом,

 package utilities;  
import java.applet.AudioClip;  
import java.io.File;  
import java.io.IOException;  
import java.io.InputStream;   
import java.net.URL;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
import sun.audio.AudioData;  
import sun.audio.AudioPlayer;  
import sun.audio.AudioStream;  
import sun.audio.ContinuousAudioDataStream;  
public class Tone {`  

    File wavFile = new File("sounds/Windows Default.wav");
    URL urlClick = Tone.class.getResource("/sounds/WindowsDefault.wav");
    AudioClip sound;
    public void sound() {
        AudioStream as = null;
        try {

            InputStream in = this.getClass().getResourceAsStream("/sounds/WindowsDefault.wav");
            as = new AudioStream(in);
            AudioData data = as.getData();
// Create ContinuousAudioDataStream.
ContinuousAudioDataStream cas = new ContinuousAudioDataStream (data);
            //System.out.println(as.getLength());
            AudioPlayer.player.start(cas);

            //System.out.println(urlClick);
                //sound = Applet.newAudioClip(urlClick);
        //this.wait(1000);
           for(int i =0;i<100000;i  ){
               double k = Math.pow(i, 5);
               if(i==99999){
                   AudioPlayer.player.stop(cas);
                   return;
               }
           }
           // sound.play();
            String relativeDirectory = System.getProperty("user.dir");
            System.out.println(relativeDirectory);

        } catch (IOException ex) {
            Logger.getLogger(Tone.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                as.close();
            } catch (IOException ex) {
                Logger.getLogger(Tone.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }

    public static void main(String[] args) {
Tone tone = new Tone();
tone.sound();
System.out.println("done");

    }
}
  

—РЕДАКТИРОВАТЬ—
Причина, по которой я использовал continuousaudiostream, заключается в том, что звук вообще не воспроизводился, когда я использую это, чтобы услышать какой-нибудь звук. Даже когда я использовал AudioStream, проблема была там..

Комментарии:

1. Используйте javax.sound.sampled.Clip или непосредственно AudioInputStream вместо того, чтобы углубляться в sun.* классы.

2. когда вы вызываете метод напрямую (вне вашего апплета), можете ли вы заставить звук воспроизводиться два раза?

3. нет, даже когда я вызываю метод напрямую, я иногда не слышу звук.. когда я говорю напрямую, я вызываю из main ()

Ответ №1:

1) Лучше не использовать скрытые классы / api — как вы уже прочитали по ссылке, которую вы получили в своем другом вопросе 🙂

2) остановите / закройте уже запущенный звук перед запуском / повторным открытием снова, в общедоступном api что-то вроде:

 Clip clip;

private void doPlay(final String url) {
    try {
        stopPlay();
        AudioInputStream inputStream = AudioSystem
                .getAudioInputStream(getClass().getResourceAsStream(url));
        clip = AudioSystem.getClip();
        clip.open(inputStream);
        clip.start();
    } catch (Exception e) {
        stopPlay();
        System.err.println(e.getMessage());
    }
}

private void stopPlay() {
    if (clip != null) {
        clip.stop();
        clip.close();
        clip = null;
    }
}
  

(Примечание: полностью закрыт только для иллюстрации, доработайте логику, чтобы загрузить один раз, а затем остановить / запустить снова)

Комментарии:

1. я не хочу останавливаться и начинать. на самом деле я просто хочу воспроизводить звук щелчка не более секунды. итак, для каждого клика я хочу воспроизвести это один раз. есть ли какой-либо способ, подобный тому, как после запуска звука при генерации события click следующее событие click не будет снова вызывать метод sound () для воспроизведения . wav-файл?? я так не думаю .. объясните мне, если я был неправ..

2. @Deepak: «на самом деле я просто хочу воспроизводить звук щелчка не более секунды». Изучите Clip.isRunning() , Clip.isActive() LineListener и javax.swing.Timer . Вы обязательно найдете ответ, используя какую-нибудь комбинацию из них.

Ответ №2:

Похоже, что ContinuousAudioDataStream сбрасывается только после достижения конца файла, так что, возможно, второе нажатие кнопки произошло до того, как это произошло. Может быть, попробовать сбросить поток