2016-07-13 21 views
0

Ein Teil meines Programms erfordert das Laden von Sounds und die Wiedergabe von Sounds, wenn Sie dazu aufgefordert werden. Momentan unterstütze ich das Laden von .wav-Dateien, die ich als Ressourcen in meinem Projekt "eingebettet" habe. Um dies zu tun verwende ich eine Zeile Code wie folgt aus:Zurücksetzen von Java AudioInputStream geladen aus Datei

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

Mein nächstes Ziel ist es dem Benutzer zu ermöglichen, ihre eigenen WAV-Dateien für die Wiedergabe zu laden. Um dies zu tun, verwende ich eine Zeile Code wie folgt:

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

Jetzt kommt das Problem. Natürlich möchte ich diese Sounds mehr als einmal spielen können. In meinem ersten Ansatz habe ich verwendet:

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

Und das funktionierte einwandfrei. Es funktioniert jedoch nicht (stürzt beim Aufruf von reset() ab) für Audio-Streams, die ich beim Laden von Dateien "regelmäßig" erstelle (die zweite Methode oben).

Der Fehler Ich erhalte ist

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

Warum ist das so? Wie soll ich das beheben?

+0

Sie müssen überprüfen, ob 'sound.markSupported()' '' 'zurückgibt, wenn nicht' '' '' '' – mariusz2108

Antwort

1

Warum speichern Sie die Streams in Ihrem sounds[] Array. Speichern Sie einfach die Informationen zum Erstellen des Streams. ein OO Weg, dies zu tun, wie folgt wäre:

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

Schließlich können Sie Ihre Liste erstellen:

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

Und wenn man den Strom benötigt sounds[j].getStream() einfach anrufen.

+0

Vielen Dank, mit ein paar zusätzlichen Verbesserungen funktioniert das. Was ich tun musste, war im Falle einer Dateiressource ein 'BufferedInputStream' anstelle des reinen' FileInputstream' zu geben, sonst konnte es nicht in einen 'AudioInputStream' umgewandelt werden und konnte daher nicht über einen Clip abgespielt werden, der mein ist aktuell gewählte Methode. Ich dachte, ich würde es für den Fall schreiben, dass irgendjemand anderes dies jemals erfährt. Aus Neugier, dies scheint verschwenderisch in Bezug auf Komplexität, Erstellen und Wiederherstellen dieser Streams. Gibt es für Zeiten, in denen Leistung wichtig ist, "billigere" Möglichkeiten? – TheFooBarWay