3

I guess my code is okay, and my .jar file its okay with the .wav inside it.. But when I try to load it using getResourceAsStream I get a error..

this is my error:

java.io.IOException: mark/reset not supported
    at java.util.zip.InflaterInputStream.reset(Unknown Source)
    at java.io.FilterInputStream.reset(Unknown Source)
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unkno
wn Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at operation.MainWindowOperations.prepareAudio(MainWindowOperations.java
:92)
    at operation.MainWindowOperations.<init>(MainWindowOperations.java:81)
    at graphics.LaunchGraphics.<init>(LaunchGraphics.java:25)
    at run.RunApp.main(RunApp.java:14)

this is my code:

private void prepareAudio() {
    try {

        InputStream is = this.getClass().getClassLoader().getResourceAsStream("beep.wav");
        inputStream = AudioSystem.getAudioInputStream(is);
        clip = AudioSystem.getClip();
        clip.open(inputStream);

    } catch (Exception ex) {
        ex.printStackTrace();

    }

}

Can someone help me? thanks alot in advance!!

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
TiagoM
  • 187
  • 3
  • 14
  • 1
    You can find your answer in this [post][1]. [1]: http://stackoverflow.com/questions/5529754/java-io-ioexception-mark-reset-not-supported –  Mar 12 '12 at 01:04
  • @EricR. +1 that thread contains two potential short-cuts that I was unaware of. – Andrew Thompson Mar 12 '12 at 01:29
  • its not working for me, it gives me another error... stream closed.. – TiagoM Mar 12 '12 at 01:30
  • with that solution I get this, i dont understand.. : http://pastebin.com/6taaMJKG my code here: http://pastebin.com/8wamm4E1 thanks alot in advance guys ;) – TiagoM Mar 12 '12 at 01:41
  • An interesting question on which I learned some things about streams. :) – Andrew Thompson Mar 12 '12 at 12:08

2 Answers2

6

Java Sound requires repositionable (mark/reset supported) input streams for some operations. If you strike this problem it is because the stream is not repositionable.

One way to get around it is to put the byte[] of the original stream into a ByteArrayInputStream, which supports mark/reset.


The 2nd answer on the question linked by Eric R. is also a possibility, and looks simpler. To try it, change..

InputStream is = this.getClass().getClassLoader().getResourceAsStream("beep.wav");
inputStream = AudioSystem.getAudioInputStream(is);

To:

URL url = this.getClass().getClassLoader().getResource("beep.wav");
inputStream = AudioSystem.getAudioInputStream(url);
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Really? Java seems so bad with sound :s I need to use a byte array ? and then loop the entire array an play each byte ? :s Thanks in advance – TiagoM Mar 12 '12 at 01:18
  • *"then loop the entire array an play each byte"* No, just pass the `ByteArrayInputStream` to `AudioSystem.getAudioInputStream(..)` and the rest of the code can work as-is. – Andrew Thompson Mar 12 '12 at 01:27
  • I didnt understand what u mean there Andrew.. Do u mean this: ByteArrayInputStream b = (ByteArrayInputStream) this.getClass().getResourceAsStream("beep.wav"); inputStream = AudioSystem.getAudioInputStream(b); ? thanks alot in advance – TiagoM Mar 12 '12 at 01:36
  • @Andrew - +1 for including the "URL" answer. This question is bound to come up multiple times, it seems. The ByteArrayInputStream answer is a neat workaround, but turns out to be overkill when all one has to do is avoid the creation of an InputStream from the audio file, which can be done by loading via a URL. – Phil Freihofner Mar 12 '12 at 06:10
  • I tryed to implement that second option u told me , was getting a error on the URL was returning null because I had the beep.wav on my project root, I changed to the package folder, where I had my class loading resource. and now it works okay. thanks alot for your second option! it works very nice! thanks alot mate! – TiagoM Mar 12 '12 at 10:22
  • Glad you got it sorted. I don't deal with the streams returned by `getResourceAsStream()` as commonly as the `URL` returned by `getResource()`. One reason is I like to log the URL as a sanity check. Logging the input stream provides less useful information. ;) – Andrew Thompson Mar 12 '12 at 11:56
  • Yes you are right its better to use URL, I can also test with URL if I am getting the right resource :) Thanks alot mate for your help, got my problem solved ;) – TiagoM Mar 12 '12 at 12:06
2

I got the answer with the help of Tim Moores at JavaRanch. I thought the clearest thing would be to just post it here, even though Andrew mentions this correct answer in the second part of his answer. (The first part works too, but is overkill.)

Url url = this.getClass().getResource("beep.wav");           
inputStream = AudioSystem.getAudioInputStream(url);

http://www.coderanch.com/t/558274/Applets/java/mark-reset-not-supported-getResourceAsStream

Tim wrote: I have no specific knowledge about this problem, or audio in applets in general, but I'm not surprised that mark/reset doesn't work with resources obtained through the ClassLoader mechanism. (Actually, I'm sort of surprised it works at all, at least some of the time :-)

Assuming that the audio file is publicly accessible through HTTP, try AudioSystem.getAudioInputStream(URL) instead of the InputStream version you're using now. Looking at the javax.sound.sampled.spi.AudioFileReader javadocs (which is the class being used underneath), only the InputStream variant talks about mark/reset problems, not the URL version.

This also came up here: https://forums.oracle.com/forums/thread.jspa?threadID=2289395&tstart=0 and the answer is near the bottom, along with a Oracle Bug Reference #7095006 which is an interesting read as it explains why the code (as the op originally attempted) used to work but no longer does.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41