2016-07-13 31 views
0

加載我的計劃的一部分,需要聲音的加載和提示時播放他們回來。 目前我支持加載.wav文件,我已經「嵌入」作爲我的項目資源。要做到這一點我用一行這樣的代碼:重置的Java的AudioInputStream從文件

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

我的下一個目標是讓用戶上傳自己的.wav文件進行播放。爲此,我使用如下代碼行:

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

現在出現這個問題。當然,我希望能夠不止一次地播放這些聲音。在我最初的方法中,我使用:

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

而且這個工作非常好。然而,它不起作用(調用reset()時崩潰)我創建的音頻流「定期」加載文件(上面的第二種方法)。

我收到的錯誤是

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

這是爲什麼? 我應該如何解決這個問題?

+0

你必須檢查是否'sound.markSupported()''返回如果TRUE'沒有你不能使用'標誌()' – mariusz2108

回答

1

爲什麼你存儲在您sounds[]陣列的流。只需保存信息如何創建流。一個面向對象的方式來做到這將是如下:

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

最後,你可以創建你的列表:

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

如果您需要的流就叫sounds[j].getStream()

+0

謝謝你,與一對夫婦額外的改動這個工程。我所要做的就是在一個文件中的資源的情況下,返回'BufferedInputStream',而不是純粹的'FileInputstream',否則它不能被鑄造成'AudioInputStream',因此無法通過片段播放,這是我的當前選擇的方法。以爲我會寫它以防其他人遇到過這種情況。 出於好奇,這似乎在複雜性方面的浪費,創建和重新創建這些流。在績效很重要的時候,有沒有「便宜」的方法來應對? – TheFooBarWay

相關問題