Closed. This question needs debugging details。它当前不接受答案。












想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。

去年关闭。



Improve this question




我正在写一个电子游戏,我想在播放器丢失或退出时停止播放音乐(进入主菜单)。

这是我的代码:
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()时,游戏就会挂起几秒钟,然后继续。

最佳答案

从我收集到的描述中,您正在按GUI上的停止按钮,这称为Music.stopMusic()。结果是音频片段停止播放,但是您仍在等待3秒钟,GUI才会响应。

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

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

或期待使用SwingWorker

有趣的是,尽管我不确定返回的是哪种Clip实现,但是快速浏览 MixerClip 会显示对本地库的调用,然后可能是困境中的吸烟者-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) { }
    }
}

10-08 00:35