有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java Sound API在播放音频文件后将其锁定

我正在尝试使用Javax。播放一个声音。wav文件。 一切正常,文件按预期播放,最后我关闭了剪辑,关闭了音频输入流。然而,在那之后,这个文件仍然被锁定(在使用中),我无法触摸它而不得到一个异常:java。尼奥。文件FileSystemException:正在发出警报。wav:该进程无法访问该文件,因为它正被另一个进程使用

下面是代码示例:

static private class SoundThread extends Thread implements LineListener {
    private boolean playCompleted;
    private int cycles;
    
    public SoundThread(int repeats) {
        cycles = repeats;
    }
    
    @Override
    public void run() {
        Clip clip;
        AudioInputStream inputStream;
        File soundFile = new File("alerting.wav");
        try {
            inputStream = AudioSystem.getAudioInputStream(soundFile);
            try {
                clip = AudioSystem.getClip();
                clip.addLineListener(this);
                clip.open(inputStream);
                while(cycles > 0) {
                    playCompleted = false;
                    clip.setFramePosition(0);
                    clip.start();
                    while(!playCompleted) {
                        Thread.sleep(1000);
                    }
                    Thread.sleep(audioRepeatTime * 1000);
                    cycles--;
                }
                //clip.drain();
                clip.close();
                inputStream.close();
                System.out.println("All closed");
                try {
                    this.finalize();
                } catch (Throwable ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (Exception ex) {
                Main.syslog(Level.WARNING, "E1001 could not play alert sound", ex);
            } finally {
                inputStream.close();
            }
        } catch (UnsupportedAudioFileException ex) {
            Main.syslog(Level.WARNING, "E1001 could not play alert sound", ex);
        } catch (IOException ex) {
            Main.syslog(Level.WARNING, "E1001 could not play alert sound", ex);
        }
    }

    @Override
    public void update(LineEvent event) {
        LineEvent.Type type = event.getType();
        
        System.out.println("Event: " + type);
        if(type == LineEvent.Type.STOP) {
            playCompleted = true;
        } else if (type == LineEvent.Type.CLOSE) {
            System.out.println("listener closed");
        }
    }
}

public static void PlayAlertSound() {
    if(enableAudio) {
        SoundThread st = new SoundThread(audioLoops);
        st.start();
    }
} 

public static void PlayAlertSound(int repeats) {
    if(enableAudio) {
        SoundThread st = new SoundThread(repeats);
        st.start();
    }
} 

在Java线程列表中,我看到“Java声音事件调度器”正在运行。我想这就是文件被锁定的原因。 知道我该怎么解决吗?谢谢


共 (1) 个答案

  1. # 1 楼答案

    Clip的API声明:

    Note that some lines, once closed, cannot be reopened. Attempts to reopen such a line will always result in a LineUnavailableException.

    我将提出几个额外的建议

    加载音频资源的更好方法是使用class.getResource方法,而不是使用File。此方法返回一个URL,然后可以将其作为参数传递给AudioSystem.getAudioInputStream方法

    我不清楚你想做什么,但我也建议你对代码做一些进一步的修改。在同一个方法中初始化和播放Clip通常不会完成,因为这违背了Clip的预期用途。A Clip是指可以存储在内存中的声音。因此,将Clip作为一个实例变量。然后,将加载并打开Clip的代码放在它自己的方法中。并将调用startloop的代码放在一个或多个单独的方法中,并且不要在播放结束时关闭Clip,除非您确定以后不会再播放它

    如果使用clip.loop,就不必费心处理侦听器和计算迭代次数