我一直在努力解决这个问题,我一直在研究计算器:
public void error_sound() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
AudioInputStream AIS = AudioSystem.getAudioInputStream(calculator.class.getResourceAsStream("/resources/Error.wav"));
AudioFormat format = AIS.getFormat();
SourceDataLine playbackLine = AudioSystem.getSourceDataLine(format);
playbackLine.open(format);
playbackLine.start();
int bytesRead = 0;
byte[] buffer = new byte[128000];
while (bytesRead != -1) {
bytesRead = AIS.read(buffer, 0, buffer.length);
if (bytesRead >= 0)
playbackLine.write(buffer, 0, bytesRead);
}
playbackLine.drain();
playbackLine.close();
}
此代码适用于JRE6,但不适用于JRE7。如果有人可以建议在JRE7上进行上述工作的方法,我将永远感激不已?
看来Sun放弃了JRE 1.7中的“Java声音音频引擎”,这是我唯一能想到的吗?
最佳答案
“看来Sun放弃了JRE 1.7中的“Java声音音频引擎”,这是我唯一能想到的吗?”
不,那会被包括我在内的很多人注意到。您的评论表明资源输入流中存在问题。这可能是由不同的音频系统或getAudioStream()的不同实现引起的。
您可以尝试将资源流包装到BufferedInputStream中:
InputStream raw = calculator.class.getResourceAsStream("/resources/Error.wav");
InputStream bis = new BufferedInputStream(raw, 20000);
AudioInputStream ais = AudioSystem.getAudioInputStream(bis);
(那是基于BufferedInputStream支持标记/重置的想法)
您确实应该在代码中添加一些适当的错误处理(检查资源是否存在等,以及适当的错误记录/报告)。如果明确报告问题,从长远来看,这确实有帮助。
编辑:重新阅读您的问题描述,很明显您正在从eclipse运行代码,并且在另一台计算机上从jar文件运行。问题是您的代码无法应对后者。将其包装为BufferedInputStream应该可以解决此问题(不过,您可能需要增加缓冲区的大小)。
Edit2:尝试此操作以重复声音:
public void error_sound() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
AudioInputStream AIS = ...
AudioFormat format = ...
SourceDataLine playbackLine = ...
playbackLine.open(format);
playbackLine.start();
int repeats = 5;
while (true) {
// playloop
int bytesRead = 0;
byte[] buffer = new byte[128000];
while (bytesRead != -1) {
bytesRead = AIS.read(buffer, 0, buffer.length);
if (bytesRead >= 0)
playbackLine.write(buffer, 0, bytesRead);
}
--repeats;
if (repeats <= 0) {
// done, stop playing
break;
} else {
// repeat one more time, reset audio stream
AIS = ...
}
}
playbackLine.drain();
playbackLine.close();
}
唯一复杂的事情是,您需要音频流来获取格式,并且还需要在每个循环迭代中重新创建以从头开始读取它。其他一切保持不变。