0

我正在尝试为正在制作的游戏添加声音,但每次尝试加载声音时,都会收到 Stream Closed Exception。我不明白为什么会这样。

加载声音:

public class WavPlayer extends Thread {

/*
 * @param s The path of the wav file.
 * @return The sound data loaded into the WavSound object
 */
public static WavSound loadSound(String s){
    // Get an input stream
    InputStream is = WavPlayer.class.getClassLoader().getResourceAsStream(s);
    AudioInputStream audioStream;
    try {
        // Buffer the input stream
        BufferedInputStream bis = new BufferedInputStream(is);
        // Create the audio input stream and audio format
        audioStream = AudioSystem.getAudioInputStream(bis); //!Stream Closed Exception occurs here
        AudioFormat format = audioStream.getFormat();
        // The length of the audio file
        int length = (int) (audioStream.getFrameLength() * format.getFrameSize());
        // The array to store the samples in
        byte[] samples = new byte[length];
        // Read the samples into array to reduce disk access
        // (fast-execution)
        DataInputStream dis = new DataInputStream(audioStream);
        dis.readFully(samples);
        // Create a sound container
        WavSound sound = new WavSound(samples, format, (int) audioStream.getFrameLength());
        // Don't start the sound on load
        sound.setState(SoundState.STATE_STOPPED);
        // Create a new player for each sound
        new WavPlayer(sound);
        return sound;
    } catch (Exception e) {
        // An error. Mustn't happen
    }
    return null;
}

// Private variables
private WavSound sound = null;

/**
 * Constructs a new player with a sound and with an optional looping
 * 
 * @param s The WavSound object
 */
public WavPlayer(WavSound s) {
    sound = s;
    start();
}

/**
 * Runs the player in a separate thread
 */
@Override
public void run(){
    // Get the byte samples from the container
    byte[] data = sound.getData();
    InputStream is = new ByteArrayInputStream(data);
    try {
        // Create a line for the required audio format
        SourceDataLine line = null;
        AudioFormat format = sound.getAudioFormat();
        // Calculate the buffer size and create the buffer
        int bufferSize = sound.getLength();
        // System.out.println(bufferSize);
        byte[] buffer = new byte[bufferSize];
        // Create a new data line to write the samples onto
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
        line = (SourceDataLine) AudioSystem.getLine(info);
        // Open and start playing on the line
        try {
            if (!line.isOpen()) {
                line.open();
            }
            line.start();
        } catch (Exception e){}
        // The total bytes read
        int numBytesRead = 0;
        boolean running = true;
        while (running) {
            // Destroy this player if the sound is destroyed
            if (sound.getState() == SoundState.STATE_DESTROYED) {
                running = false;
                // Release the line and release any resources used
                line.drain();
                line.close();
            }
            // Write the data only if the sound is playing or looping
            if ((sound.getState() == SoundState.STATE_PLAYING)
                    || (sound.getState() == SoundState.STATE_LOOPING)) {
                numBytesRead = is.read(buffer, 0, buffer.length);
                if (numBytesRead != -1) {
                    line.write(buffer, 0, numBytesRead);
                } else {
                    // The samples are ended. So reset the position of the
                    // stream
                    is.reset();
                    // If the sound is not looping, stop it
                    if (sound.getState() == SoundState.STATE_PLAYING) {
                        sound.setState(SoundState.STATE_STOPPED);
                    }
                }
            } else {
                // Not playing. so wait for a few moments
                Thread.sleep(Math.min(1000 / Global.FRAMES_PER_SECOND, 10));
            }
        }
    } catch (Exception e) {
        // Do nothing
    }
}

我收到的错误消息是: “线程“主”java.io.IOException 中的异常:流在 java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134) 处的 java.io.BufferedInputStream.fill(BufferedInputStream.java: 218) 在 java.io.BufferedInputStream.read(BufferedInputStream.java:237) 在 java.io.DataInputStream.readInt(DataInputStream.java:370) 在 com.sun.media.sound.WaveFileReader.getFMT(WaveFileReader.java:224) ) 在 com.sun.media.sound.WaveFileReader.getAudioInputStream(WaveFileReader.java:140) 在 javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1094) 在 stm.sounds.WavPlayer.loadSound(WavPlayer.java: 42) 在 stm.STM.(STM.java:265) 在 stm.STM.main(STM.java:363)"

4

2 回答 2

2

很可能此行中的文件路径不正确:

WavPlayer sound1 = WavPlayer.loadSound("coin.wav");

您应该传递“coin.wav”文件的路径,而不仅仅是其名称。

例如,如果它在一个名为sounds 的文件夹下,比如说在项目的根目录下,那么该参数应该是' sounds/coin.wav '。

于 2013-10-05T22:21:14.660 回答
0

问题出在您的静态方法loadSound中。此方法null在抛出异常时返回。你抓住了它,但你什么也不做,

  • 切勿空接。
  • 捕获特定的异常。

我会将您的方法签名更改loadSound

public static WavSound loadSound(String s) throws Exception // rather than exception specific exception!!

然后你的方法没有try-catch

于 2013-10-05T22:22:33.947 回答