我编写了一个读取WAV文件(大小约为80 MB)并播放该代码的代码。问题是声音播放严重(极端滞后)。你能告诉我这是什么问题吗?
这是我的代码:
(我在Jframe构造函数中调用doPlay
函数)
private void doPlay(final String path) {
try {
stopPlay();
InputStream is = new FileInputStream(path);
InputStream bufferedIn = new BufferedInputStream(is);
AudioInputStream ais = AudioSystem.getAudioInputStream(bufferedIn);
AudioFormat format = ais.getFormat();
// this is the value of format.
// PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
DataLine.Info info = new DataLine.Info(Clip.class, format);
clip = (Clip)AudioSystem.getLine(info);
clip.open(ais);
clip.start();
} catch (Exception e) {
stopPlay();
e.printStackTrace();
}
}
答案 0 :(得分:7)
问题是您需要先加载剪辑 才能播放它。剪辑在播放之前完全加载到内存中。
换句话说,在播放剪辑之前,一切都应该发生在clip.open()之前。当您准备播放Clip时,您应该使用的唯一命令是clip.start()。要重放剪辑,请将其光标位置设置回到开始并调用clip.start()。
如果一个Clip足够短,你可以在播放它们的同时打开它们(加载它们)的低效编码实践。如果你真的想从一个文件而不是从内存中播放,请使用SourceDataLine,它将比Clip对大文件的启动速度快得多。
Clip:在播放之前必须加载到内存中,一旦加载,它就会以最小的cpu播放。专为小型和重复使用的声音文件而设计。
SourceDataLine:从文件位置播放,立即启动,消耗非常少的内存(远小于Clip),但由于文件读取而使用比Clip略多的cpu。最适合大型和单播音频。
LAG的另一个来源:第一次调用声音文件时,由于从编译的代码执行,它运行速度稍慢。通过重用,声音代码被放入内存并以最小的延迟执行。因此,有时我会在程序开始时播放“静音”声音以“灌注泵”,这样当需要听到的第一个声音播放时,播放的延迟就会减少。
答案 1 :(得分:3)
实际上你的代码应该可以正常工作(在带有+ 80mb音频文件的JFrame构造函数中测试它),所以我只能给出一些建议: