简体   繁体   中英

Resetting Java AudioInputStream loaded from file

A part of my program requires loading of sounds and playing them back when prompted. Currently I support loading .wav files that I have "embedded" as resources within my project. To do this I use a line of code like this:

sounds[i+1] = AudioSystem.getAudioInputStream(MyProject.class.getResource("filename.wav"));

My next goal is to allow the user to load their own .wav files for playback. To do this I use a line of code like this:

sounds[i+1] = AudioSystem.getAudioInputStream(new File("filename.wav"));

Now comes the issue. Naturally I want to be able to play these sounds more than once. In my initial approach I used:

sound.markSupported();
sound.mark(Integer.MAX_VALUE); 
/* do stuff with it */
sound.reset();

And this worked perfectly fine. However it does not work (crashes upon invocation of reset() ) for audio streams I create from loading files "regularly" (the second method above).

The error I am receiving is

java.io.IOException: mark/reset not supported
at java.io.InputStream.reset(InputStream.java:348)
at javax.sound.sampled.AudioInputStream.reset(AudioInputStream.java:427)....

Why is that? How should I go about fixing this?

Why do you store the Streams in your sounds[] array. Just save the info how to create the stream. an OO way to do this would be as follow:

public abstract class AudioSource {
    public abstract InputStream getStream() throws IOException;
}

public class FileAudioSource extends AudioSource {

    private final File audioFile;

    public FileAudioSource(File audioFile) {
        this.audioFile = audioFile;
    }

    @Override
    public InputStream getStream() throws FileNotFoundException {
        return new FileInputStream(audioFile);
    }
}

public class ResourceAudioSource extends AudioSource {

    private final String resourceName;

    public ResourceAudioSource(String resourceName) {
        this.resourceName = resourceName;
    }

    @Override
    public InputStream getStream() {
        return this.getClass().getResourceAsStream(resourceName)
    }
}

Finally you can create your list:

sounds[i+1] = new ResourceAudioSource("resource_filename.wav");
sounds[i+1] = new FileAudioSource(new File("filename.wav"));

And if you need the stream just call sounds[j].getStream() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM