2013-10-05 42 views
0

我正在嘗試向我正在製作的遊戲添加聲音,但每次嘗試加載聲音時,都會收到流關閉異常。我不明白爲什麼會發生這種情況。Java音頻流關閉錯誤

加載聲音:

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) at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) at java.io.BufferedInputStream.read(BufferedInputStream.java:237) at java.io.DataInputStream.readInt(DataInputStream .java:370) at com.su n.media.sound.WaveFileReader.getFMT(WaveFileReader.java:224) at com.sun.media.sound.WaveFileReader.getAudioInputStream(WaveFileReader.java:140) at 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)」

+0

的問題是,在靜態方法'loadSound'要返回'null'的'異常'肯定是抓住了,你什麼都不做 – nachokk

回答

2

最有可能在此行中的文件路徑是不正確的:

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

您應該通過「coin.wav」文件研究所的路徑只是它的名字而已。

例如,如果它在一個名爲sounds的文件夾下面,我們可以說在項目的根目錄下,那個參數應該是'sounds/coin.wav'。

0

問題出在您的靜態方法loadSound。拋出異常時,此方法返回null。你抓住它,但你什麼都不做吧,

  • NEVER使空的catch。
  • 捕獲特定的異常。

我會改變你的方法簽名loadSound

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

然後你的方法,無需try-catch

+0

我試過這個,我得到了一個流關閉異常 – user2850551

+0

@ user2850551好現在你走了一步!用新的錯誤的完整堆棧跟蹤來更新問題!所以更多的人可以幫助你。看看[這](http://stackoverflow.com/questions/4953142/stream-closed-exception-in-java)幫助你。 – nachokk