try {
//String location = dir1.getCanonicalPath()+"\\app_yamb_test1\\mySound.au";
//displayMessage(location);
AudioInputStream audio2 = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("mySound.au"));
Clip clip2 = AudioSystem.getClip();
clip2.open(audio2);
clip2.start();
} catch (UnsupportedAudioFileException uae) {
System.out.println(uae);
JOptionPane.showMessageDialog(null, uae.toString());
} catch (IOException ioe) {
System.out.println("Couldn't find it");
JOptionPane.showMessageDialog(null, ioe.toString());
} catch (LineUnavailableException lua) {
System.out.println(lua);
JOptionPane.showMessageDialog(null, lua.toString());
}
当我从netbeans运行应用程序时,此代码工作正常。声音播放,没有例外。但是,当我从dist文件夹运行它时,声音无法播放,我在消息对话框中显示java.io.IOException: mark/reset not supported
。
我该如何解决这个问题?
答案 0 :(得分:126)
AudioSystem.getAudioInputStream(InputStream)
的文档说:
这种方法的实施可能 需要多个解析器来检查 流确定他们是否 支持它。这些解析器必须能够 标记流,读取足够的数据 确定他们是否支持 流,如果没有,重置 stream的读指针指向其原始 位置。如果输入流没有 支持这些操作,这种方法 可能因IOException而失败。
因此,您为此方法提供的流必须支持可选的mark/reset功能。使用BufferedInputStream
装饰您的资源流。
//read audio data from whatever source (file/classloader/etc.)
InputStream audioSrc = getClass().getResourceAsStream("mySound.au");
//add buffer for mark/reset support
InputStream bufferedIn = new BufferedInputStream(audioSrc);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(bufferedIn);
答案 1 :(得分:5)
经过一段时间的挣扎并多次引用此页面后,我偶然发现了this,这帮助了我解决了我的问题。我最初能够加载一个wav文件,但随后只能播放一次,因为由于“标记/重置不支持”错误而无法回放它。这令人抓狂。
链接代码从文件中读取AudioInputStream,然后将AudioInputStream放入BufferedInputStream,然后将 放回到AudioInputStream中,如下所示:
audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
BufferedInputStream bufferedInputStream = new BufferedInputStream(audioInputStream);
audioInputStream = new AudioInputStream(bufferedInputStream, audioInputStream.getFormat(), audioInputStream.getFrameLength());
最后它将读取的数据转换为PCM编码:
audioInputStream = convertToPCM(audioInputStream);
将convertToPCM定义为:
private static AudioInputStream convertToPCM(AudioInputStream audioInputStream)
{
AudioFormat m_format = audioInputStream.getFormat();
if ((m_format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) &&
(m_format.getEncoding() != AudioFormat.Encoding.PCM_UNSIGNED))
{
AudioFormat targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
m_format.getSampleRate(), 16,
m_format.getChannels(), m_format.getChannels() * 2,
m_format.getSampleRate(), m_format.isBigEndian());
audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
}
return audioInputStream;
}
我相信他们这样做是因为BufferedInputStream比audioInputStream更好地处理标记/重置。希望这有助于那里的人。
答案 2 :(得分:4)
刚从其他人那里遇到过同样问题引用它的问题。
Oracle Bug数据库,#7095006
使用以下代码来避免InputStream步骤。导致错误的是InputStream。
URL url = AudioMixer.class.getResource(fileName);
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
瞧 - 没有InputStream
答案 3 :(得分:0)
问题是你输入的流必须支持标记和重置方法。至少如果支持标记,您可以使用:AudioInputStream#markSupported进行测试。
所以你应该使用不同的InputStream。