Java应用程序挂起在AudioClip.stop()上

时间:2012-08-20 22:35:07

标签: java audio

我正在写一个视频游戏,我想在玩家输掉或退出时停止音乐(到主菜单)。

这是我的代码:

public class Music{
    private static Clip clip;
    private static AudioInputStream stream;

    private static void loadMusic(){
        if(clip != null) return;
        try {
            AudioFormat format;
            DataLine.Info info;
            stream = AudioSystem.getAudioInputStream(Music.class.getResource("/resources/music/music.wav"));
            format = stream.getFormat();
            info = new DataLine.Info(Clip.class, format);
            clip = (Clip) AudioSystem.getLine(info);
            clip.open(stream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void playMusic(boolean loop){
        loadMusic();
        if(clip == null) return;
        if(loop) clip.loop(Clip.LOOP_CONTINUOUSLY);
        else clip.start();
    }

    public static void stopMusic(){
        clip.stop();
        clip.setMicrosecondPosition(0);
    }
}

每当我调用Music.stopMusic()时,游戏会挂起几秒钟然后继续。

1 个答案:

答案 0 :(得分:2)

从我收集的描述中,您按下GUI上的停止按钮,然后调用Music.stopMusic()。结果是音频片段停止播放,但您仍然在GUI响应之前等待3秒钟。

这是因为您在Music.stopMusic()中进行的调用会对I / O资源进行本机调用,而这不应在EDT中调用。您应该查看运行工作线程来执行此操作:

Thread t = new Thread(new Runnable() { 
     public void run() {
         Music.stop();
     }
});
t.start();

或者期待使用SwingWorker

有趣的是,虽然我不确定返回Clip的哪个实现,但是快速查看MixerClip会显示对本机库的调用,然后可能是您的困境中的冒烟 - a 3秒等待回电!

// stop the sample.  this invalidates the sample voice id.
nStop(id);

// wait for the callback
synchronized(lock) {
    if (id!=0) {
    try {
        //long time=System.currentTimeMillis();
        lock.wait(3000);
        //if (System.currentTimeMillis()-time > 2500) {
        //System.out.println(" WAITING TIMED OUT!"); System.out.flush();
        //id=0;
        //}
    } catch (InterruptedException e) { }
    }
}