使用剪辑即时播放声音

时间:2016-07-27 06:46:24

标签: java javasound

我一直在学习如何播放声音,我有一个很好的方法,但有一个问题。我尝试播放声音,但在方法运行后它不会立即播放。

这是我的代码:

    new Thread(new Runnable(){
        public void run(){
            File audioFile = new File(soundMap.get(key));
            try {
                AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
                AudioFormat format = audioStream.getFormat();
                DataLine.Info info = new DataLine.Info(Clip.class, format);
                Clip audioClip = (Clip) AudioSystem.getLine(info);
                AudioListener listener = new AudioListener();
                audioClip.addLineListener(listener);
                audioClip.open(audioStream);
                audioClip.start();
                listener.waitUntilDone();
                audioClip.close();

            } catch (UnsupportedAudioFileException ex) {
                System.out.println("The specified audio file is not supported.");
                ex.printStackTrace();
            } catch (LineUnavailableException ex) {
                System.out.println("Audio line for playing back is unavailable.");
                ex.printStackTrace();
            } catch (IOException ex) {
                System.out.println("Error playing the audio file.");
                ex.printStackTrace();
            }
        }
    }).start();

所有AudioListener类都允许线程等到声音完成。

另一方面,我会将其用于游戏,因此必须多次播放特定声音,所以如果有办法解决这个问题,那将会有很大帮助。

1 个答案:

答案 0 :(得分:0)

评论几乎涵盖了一些内容,但我将总结几点。

1)使用Clip,您可以预先加载并保留内存中的对象。不要将open()和start()方法组合在一起。在整个文件加载到内存之前,start()方法不会运行。

2)您可以在运行start()方法之前使用setMicrosecondPosition(0)或setFramePosition(0)从头开始重播剪辑。

3)只要游戏正在运行,Clip就会在后台运行自己的线程。没有必要等到完成"。音频在守护程序线程上运行,与其他活动同时运行。与常规线程不同,如果没有其他运行,守护程序线程将允许自己关闭。但是当程序运行时,屏幕上有图形,动画等,声音应运行正常。

我建议制作一个" SoundHandler"类,并为您的不同游戏声音制作实例变量(剪辑),并在构造函数中打开它们。您还可以制作播放不同声音的方法。这对于简单游戏的第一次传球应该足够好了。下面的内容如下(省略异常处理):

class SoundHandler

    Clip gunshot;
    Clip explosion;

    public SoundHandler()
    {
        gunshot = loadGunshot();
        explosion = loadExplosion();
    }

    private Clip loadGunshot()
    {
        // code to make and open a Clip
    }

    public void playGunshot()
    {
        gunshot.setMicrosecondPosition(0);
        gunshot.start();
    }

    // et cetera
}

在你的主游戏线程中,你实例化SoundHandler的副本,并在需要发出声音时在游戏循环中引用。

soundHandler.playGunshot();