java.io.IOException: mark/reset not supported Java

2019-05-26 13:43发布

问题:

I'm in the process of creating a 2D Java Platform Game and I'm trying to get audio to play from a .wav file while the game is running...

Below is an AudioPlayer class I created to take care of loading the resource into an Audio Input Stream

import javax.sound.sampled.*;
import java.io.*;
import java.util.*;
import java.net.*;

public class AudioPlayer {

    private Clip clip;

    public AudioPlayer(String s) {

        try {

            /************/
            InputStream is = getClass().getResourceAsStream(s);
            AudioInputStream ais;
            BufferedInputStream bis = new BufferedInputStream(is);
            ais = AudioSystem.getAudioInputStream(bis);
            /************/

            AudioFormat baseFormat = ais.getFormat();

            AudioFormat decodeFormat = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED, 
            baseFormat.getSampleRate(),
            16, 
            baseFormat.getChannels(), 
            baseFormat.getChannels() * 2, 
            baseFormat.getSampleRate(), 
            false);

            AudioInputStream dais = AudioSystem.getAudioInputStream(decodeFormat, ais);
            clip = AudioSystem.getClip();
            clip.open(dais);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void play() {
        if(clip == null) return;
        stop();
        clip.setFramePosition(0);
        clip.start();
    }

    public void stop() {  
        if(clip.isRunning()) clip.stop();
    }

    public void toggle() {
        if(clip.isRunning()) {
            clip.stop();
        }
        else {
            clip.start();
        }
    }
    public void close() {
        stop();
        clip.close();
    }
}

When I compile and run the game directly from the source code, the audio works fine but when I try to compress the files into a .jar format and run the .jar file I get the 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(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at audio.AudioPlayer.<init><AudioPlayer.java:18)
    ...

I'm not sure if I set up the Buffered Input Stream up correctly for the game to run in .jar format.

Any thoughts on how to resolve this issue would be much appreciated.

Thanks!

回答1:

Change:

        /************/
        InputStream is = getClass().getResourceAsStream(s);
        AudioInputStream ais;
        BufferedInputStream bis = new BufferedInputStream(is);
        ais = AudioSystem.getAudioInputStream(bis);
        /************/

To something like:

        /************/
        URL url = getClass().getResource(s);
        AudioInputStream ais;
        ais = AudioSystem.getAudioInputStream(url);
        /************/

It will work because getResourceAsStream typically returns a non-repositionable input stream, whereas if you provide the URL to the AudioSystem, it can establish as many streams as it wants from the URL, or wrap it in a repositionable stream.