当前位置: 动力学知识库 > 问答 > 编程问答 >

audio - Java application hangs on AudioClip.stop()

问题描述:

I'm writing a videogame and I want to stop the music when a player loses or quits (to the main menu).

Here's my code:

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);

}

}

Whenever I call Music.stopMusic(), the game hangs for a few seconds then continues.

网友答案:

From what i gather form your description, you are pressing a stop button on your GUI and this calls Music.stopMusic(). The result is that the audio clip stops playing, but you are still waiting 3 seconds before you GUI becomes responsive.

This is because the call you are making in Music.stopMusic() makes native calls to I/O resources, and this should not be called in the EDT. You should look at running up a worker thread to do this:

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

Or look to using a SwingWorker.

Interestingly, though I am not sure which implementation of Clip is returned, but a quick look at MixerClip shows a call to a native library, and then perhaps the smoking gun in your predicament- a 3 second wait for a callback!

// 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) { }
    }
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: