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

This code works fine when I run the application from netbeans. The sound plays and there are no exceptions. However, when I run it from the dist folder, the sound does not play and I get the java.io.IOException: mark/reset not supported in my message dialog.

How can I fix this?

qasimzee
  • 640
  • 1
  • 12
  • 30
Crais
  • 903
  • 1
  • 6
  • 4

5 Answers5

173

The documentation for AudioSystem.getAudioInputStream(InputStream) says:

The implementation of this method may require multiple parsers to examine the stream to determine whether they support it. These parsers must be able to mark the stream, read enough data to determine whether they support the stream, and, if not, reset the stream's read pointer to its original position. If the input stream does not support these operation, this method may fail with an IOException.

Therefore, the stream you provide to this method must support the optional mark/reset functionality. Decorate your resource stream with a 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);
McDowell
  • 107,573
  • 31
  • 204
  • 267
  • 5
    Ty, this worked. I modified the code like this: `BufferedInputStream myStream = new BufferedInputStream(getClass().getResourceAsStream("mySound.au")); AudioInputStream audio2 = AudioSystem.getAudioInputStream(myStream);` And now it works =) P.S. if someone could format this comment it would be great =/ – Crais Apr 03 '11 at 15:05
  • Is that what mark/reset signifies? a stream that can be seeked? @McDowell, could you show the decorated code in your answer? – Ehtesh Choudhury Aug 02 '11 at 20:08
  • @Shurane - mark/reset lets a stream "unread" data back to the mark point when reset is called (typically by buffering data in RAM from when mark is called.) – McDowell Aug 03 '11 at 07:31
  • 4
    Can't upvote this enough. Couldn't figure out why my audio wasn't loading properly from a file. Since I'm loading from a file, it was easier for me to do this: FileInputStream fs = new FileInputStream(filename); BufferedInputStream myStream = new BufferedInputStream(fs); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(myStream); – AndyG Nov 28 '11 at 01:07
  • hey @SauceMaster I used this approach,because I am also trying to open a file,but still it does not compile. I am getting : "java.io.IOException: Stream closed". It seems to behave this way when it faces bitrates of 320kbps while in 112 it works fine. – Potney Switters Aug 06 '12 at 08:57
  • @PotneySwitters I'm afraid I can't levy a good guess based on what you've said. Perhaps you could open a question here with some code and more explanation? – AndyG Aug 08 '12 at 19:01
  • @SauceMaster, thanks for the reply. I gave up this approach because I couldnot get around this exception. I just convert everything to 112kbps and take it from there. – Potney Switters Aug 09 '12 at 09:09
  • This solved the exception but now I am getting a "javax.sound.sampled.UnsupportedAudioFileException: file is not a supported file type" with a 16khz wav-file. Not sure if this has to do with the BufferedInputStream – Sip Apr 23 '18 at 11:04
6

After floundering about for a while and referencing this page many times, I stumbled across this which helped me with my problem. I was initially able to load a wav file, but subsequently only could play it once, because it could not rewind it due to the "mark/reset not supported" error. It was maddening.

The linked code reads an AudioInputStream from a file, then puts the AudioInputStream into a BufferedInputStream, then puts that back into the AudioInputStream like so:

audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
BufferedInputStream bufferedInputStream = new BufferedInputStream(audioInputStream);
audioInputStream = new AudioInputStream(bufferedInputStream, audioInputStream.getFormat(), audioInputStream.getFrameLength());

And then finally it converts the read data to a PCM encoding:

audioInputStream = convertToPCM(audioInputStream);

With convertToPCM defined as:

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

I believe they do this because BufferedInputStream handles mark/reset better than audioInputStream. Hope this helps somebody out there.

AndyG
  • 39,700
  • 8
  • 109
  • 143
5

Just came across this question from someone else with the same problem who referenced it. Looks like this issue arose with Java 7.

Oracle Bug database, #7095006

A test, executed when InputStream is the argument to the getAudioInputStream() method, is triggering the error. The existence of Mark/Reset capabilities in the audio resource file have no bearing on whether the Clip will load and play. Given that, there is no reason to prefer an InputStream as the argument, when a URL or File suffice.

If we substitute a URL as the argument, this needless test is not executed. Revising the OP code:

AudioInputStream ais = AudioSystem.getAudioInputStream(getClass().getResource(fileName));

Details can be seen in the API, in the description text for the two forms. AudioSystem.getAudioInputStream(InputStream)

AudioSystem.getAudioInputStream(URL)

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

The problem is that you're input stream has to support the methods mark and reset. At least if mark is supported you can test with: AudioInputStream#markSupported.

So you should maybe use a different InputStream.

Paul Richter
  • 10,908
  • 10
  • 52
  • 85
0

I solved something similar and your code would look like this, it's up to you to try.

try {
    InputStream is = getClass().getResourceAsStream("mySound.au");
    BufferedInputStream bis = new BufferedInputStream(is);
    Clip clip2 = AudioSystem.getClip();
    clip2.open(bis);
    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());
}
Diego Borba
  • 1,282
  • 8
  • 22