Java 如何使用AudioSystem预加载不同的剪辑?
我在Java应用程序中集成了音频。问题是有时clip.open()会挂起一点,所以我读到需要重新加载剪辑,然后只需clip.start() 我为每个音频文件使用一个sound类,它会在播放结束后重新加载剪辑。 这里的问题是,当我触发声音时,它不会正确播放,但是当我触发下一个声音时。它改变了所有的声音 我想到了这样的想法,因为加载方法打开了一个剪辑,然后被另一个声音实例使用,它不应该只加载它的剪辑吗 就像我说的,如果一个调用在启动后立即调用load方法,它有时会冻结。 我已经创建了一个线程来运行它,这样它就不会挂起主线程,但它会冻结,所以声音会播放得很晚Java 如何使用AudioSystem预加载不同的剪辑?,java,javasound,Java,Javasound,我在Java应用程序中集成了音频。问题是有时clip.open()会挂起一点,所以我读到需要重新加载剪辑,然后只需clip.start() 我为每个音频文件使用一个sound类,它会在播放结束后重新加载剪辑。 这里的问题是,当我触发声音时,它不会正确播放,但是当我触发下一个声音时。它改变了所有的声音 我想到了这样的想法,因为加载方法打开了一个剪辑,然后被另一个声音实例使用,它不应该只加载它的剪辑吗 就像我说的,如果一个调用在启动后立即调用load方法,它有时会冻结。 我已经创建了一个线程来运行它
public class Sound {
private final String file;
private static Clip clip;
public Sound(String file){
this.file = file;
load();
}
public final void load(){
try {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(file).getAbsoluteFile());
clip = AudioSystem.getClip();
System.out.println(clip);
clip.open(stream);
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
Logger.getLogger(Sound.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void play() {
clip.start();
clip.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
clip.stop();
clip.close();
load();
}
});
}
}
我希望音频能在触发时播放。我想出来了。这真是个愚蠢的错误。Clip对所有类都是一样的,不是因为getClip()返回了相同的值,而是因为我将其设置为静态。 刚刚改变:
private static Clip clip;
到
你是否不止一次播放这些声音?如果是这样,您将多次调用addLineListener,这将导致奇怪的行为。尝试将addLineListener调用移动到您的
load
方法中,这样每个剪辑对象只调用一次。我已将addLineListener移动到构造函数中,因此不会多次调用它,因为每次剪辑结束时都会调用load。但是现在不管我触发什么声音,它播放的声音总是一样的。我只是注意到clip
是一个静态场。这意味着所有声音实例都使用相同的剪辑对象!让它成为一个非静态的场。我无法表达我有多激动和羞愧。非常感谢,它现在运行良好。很高兴您解决了问题,但代码可以进一步改进。如果要重复重新加载声音文件,请使用SourceDataLine,而不是Clip。SourceDataLine将立即开始播放(只要加载了缓冲区的数据量)。剪辑必须在播放之前完成整个声音文件的加载。基本上,如果你需要重新加载一个剪辑,你就是在滥用它。它是专门用来将声音数据保存在内存中以供重用的。“这真是一个愚蠢的错误。”哈哈。到目前为止,我已经犯了三个错误,还有更多的时间。聪明地解决问题,再加上一个报告解决方案。
private Clip clip;