2011-04-03 51 views
52
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 supportedjava.io.IOException:不支持标记/重置

我该如何解决这个问题?

回答

113

AudioSystem.getAudioInputStream(InputStream)文档说:

这种方法可能 需要多个解析器的执行检查 流,以确定它们是否 支持。这些解析器必须能够 标记流,读取足够的数据 以确定它们是否支持 流,如果不支持,则将流的读取指针重置为其原始位置的 位置。如果输入流 不支持这些操作,则此方法 可能会因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); 
+3

泰,这个工作。我修改了这样的代码: 'BufferedInputStream myStream = new BufferedInputStream(getClass()。getResourceAsStream(“mySound.au”)); AudioInputStream audio2 = AudioSystem.getAudioInputStream(myStream);' 现在它工作=) P.S.如果有人可以格式化这个评论,它会很棒=/ – Crais 2011-04-03 15:05:17

+0

这是什么标记/重置意味着什么?可以查找的流? @McDowell,你可以在你的答案中显示装饰的代码吗? – 2011-08-02 20:08:52

+0

@Shurane - 标记/重置允许在调用重置时(通常通过从标记被调用时缓冲RAM中的数据)将“未读”数据流回到标记点。 – McDowell 2011-08-03 07:31:40

0

的问题是,你输入流必须支持的方法标记和复位。至少如果支持标记,您可以使用:AudioInputStream#markSupported进行测试。

所以你应该使用不同的InputStream。

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处理mark/reset比audioInputStream更好。希望这可以帮助那里的人。

+0

这里的其他解决方案不适用于我的问题,但这是一个!谢谢! – 2014-03-29 00:38:12

4

过这个问题,刚刚从别人谁与它引用了同样的问题。

Oracle错误数据库,#7095006

使用下面的代码,以避免InputStream的一步。这是导致错误的InputStream。

URL url = AudioMixer.class.getResource(fileName); 
AudioInputStream ais = AudioSystem.getAudioInputStream(url); 

瞧 - 没有的InputStream

mark/reset exception during getAudioInputStream()

+1

我可以在哪里获得AudioMixer?我尝试了一个类似帖子中的链接,但它指向其他地方。 – 2012-08-02 13:49:22

+2

@Potney对不起。 AudioMixer确实看起来可能是核心Java类的名称,但它只是我写的一个类。我在代码源中使用它的目录位置作为查找“文件名”的起点。 http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html如果您还不熟悉这一点,请参阅上述教程中的“使用getResource加载图像”一节。 – 2012-08-02 17:18:35