【问题标题】:Java Sound API locks audio file after playing itJava Sound API 在播放后锁定音频文件
【发布时间】:2020-12-18 09:07:17
【问题描述】:

我正在尝试使用 Javax.sound 播放 .wav 文件。 一切正常,文件按预期播放,最后我关闭剪辑并关闭 AudioInputStream。但是,在那之后文件保持锁定(正在使用),我无法触摸它而不会出现异常:java.nio.file.FileSystemException: alerting.wav: The process cannot access the file because it is being used by another process.

代码示例如下:

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 Sound Event Dispatcher”正在运行。我认为这是保持文件锁定的原因。 知道如何解决这个问题吗?谢谢

【问题讨论】:

    标签: java audio javasound


    【解决方案1】:

    Clip 状态的 API:

    请注意,有些线路一旦关闭就无法重新打开。尝试去 重新打开这样一行总是会导致LineUnavailableException

    我将提出一些额外的建议。

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

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

    如果你使用clip.loop,你就不必费心监听器和计算迭代次数。

    【讨论】:

    • 感谢您的回答。我在播放声音方面没有任何问题,效果很好。我的问题是当我不播放声音并且所有东西都关闭时,文件仍然被系统锁定,无法修改或删除。我只是希望能够在其他一些对话框窗口中加载不同的 .wav 表单计算机并将其保存为与初始文件相同的名称。尽管我关闭了它,但看起来 AudioInputStream 仍然锁定了文件。我也尝试使用 Media 和 MediaPlayer 但同样的事情发生了。
    • 可能文件命令正在等待。尝试改用 URL。我刚刚注意到您正在“声音线程”中做所有事情。很少需要处理声音——每次播放声音时都会启动新线程。对不起,我帮不上忙,但你做事的方式让我很困惑。我认为简化将大大有助于解决您的问题。也许尝试制作一个简单的剪辑,调用它,播放它,让它被垃圾收集,然后看看你是否可以加载文件。我知道我过去曾多次加载文件 wav 文件,但总是使用它们自己的 AudioInputStreams。
    • 这是一个非常复杂的程序的一部分,它不是一个声音播放器。这就是我使用线程的原因。该程序必须运行并完成它的工作,有时它必须在某些可配置的时间间隔内以编程的次数播放声音,而无需保留整个程序。但是,我尝试只播放一次没有线程的声音。一旦文件被播放,它就变成“正在被其他进程使用”并且不能再被触摸。谢谢
    • 这和这个话题一样:stackoverflow.com/questions/11316289/… 从来没有得到正确的答案
    猜你喜欢
    • 2011-12-15
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多