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

问题描述

我正在尝试使用Javax.sound播放.wav文件。 一切正常,文件按预期播放,最后关闭剪辑并关闭AudioInputStream。但是,此后文件仍处于锁定状态(使用中),并且在没有异常的情况下我无法触摸它:java.nio.file.FileSystemException:alerting.wav:该进程无法访问该文件,因为该文件正在被另一个进程使用。 / p>

下面是代码示例:

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,ex);
        } catch (IOException ex) {
            Main.syslog(Level.WARNING,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 Sound Event Dispatcher”正在运行。我认为这是使文件锁定的原因。 知道如何解决这个问题吗?谢谢

解决方法

剪辑的API状态:

请注意,某些行一旦关闭,便无法重新打开。尝试去 重新打开这样的行将始终导致LineUnavailableException

我将提出一些其他建议。

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

我不清楚您要做什么,但是我还建议对您的代码做一些进一步的更改。通常不会用相同的方法初始化和播放Clip,因为它违背了Clip的预期用途。 Clip用于保留在内存中的声音。因此,将Clip设置为实例变量。然后,以自己的方法放置加载并打开Clip的代码。并将调用startloop的代码放在一个或多个单独的方法中,除非确定您永远不会使用,否则不要在播放结束时关闭Clip再次播放。

如果使用clip.loop,则不必打扰侦听器并计算迭代次数。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...