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 楼答案
Clip的API声明:
我将提出几个额外的建议
加载音频资源的更好方法是使用
class.getResource
方法,而不是使用File
。此方法返回一个URL
,然后可以将其作为参数传递给AudioSystem.getAudioInputStream
方法我不清楚你想做什么,但我也建议你对代码做一些进一步的修改。在同一个方法中初始化和播放
Clip
通常不会完成,因为这违背了Clip
的预期用途。AClip
是指可以存储在内存中的声音。因此,将Clip
作为一个实例变量。然后,将加载并打开Clip
的代码放在它自己的方法中。并将调用start
或loop
的代码放在一个或多个单独的方法中,并且不要在播放结束时关闭Clip
,除非您确定以后不会再播放它如果使用
clip.loop
,就不必费心处理侦听器和计算迭代次数