我一直在努力解决这个问题,我一直在研究计算器:

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();
}

唯一复杂的事情是,您需要音频流来获取格式,并且还需要在每个循环迭代中重新创建以从头开始读取它。其他一切保持不变。

08-17 13:47
查看更多