How to cast from InputStream to AudioInputStream
Solution 1
Use the AudioSystem
to get an AudioInputStream
directly from the URL
to the resource.
URL url = ClassLoader.getResource("/sounds/"+filename+".wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.open(ais);
See also AudioSystem.getAudioInputStream(InputStream)
but this is 'more dangerous'. Java Sound will typically require a repositionable input stream. For some reason that I am not quite clear on, the Class.getResourceAsStream()
variants sometimes return a non-repositionable stream.
Solution 2
You can't cast it. In Java, a type cast on a reference type only works if the real object you are casting is already an instance of the target type. For example:
String myString = new String("42");
Object obj = (Object) myString; // OK
String mystery = (String) obj; // OK
String mystery2 = (Integer) obj; // FAIL
The first two succeed because the string object that we created in the first line is an instance of Object
(because String
is a subtype of Object
), and an instance of String
. The third one fails because a String
is NOT an Integer
.
In your example, the object that you get from getSystemResourceAsStream
is a raw stream containing (presumably) audio data. It is not an audio stream; i.e. not an instance of AudioInputStream
.
You have to wrap the raw input stream, something like this:
InputStream in = ClassLoader.getSystemResourceAsStream(
"sounds/"+filename+".wav");
AudioFormat format = ...
int length = ...
AudioInputStream audio = new AudioInputStream(in, format, length);
or use one of AudioSystem.getAudioInputStream(...)
factory methods, which does the wrapping under the hood.
See Andrew Thomson's answer for details of the RIGHT way to do this.
Valentino Ru
Updated on June 04, 2022Comments
-
Valentino Ru about 2 years
Is it possible to cast from an InputStream to an AudioInputStream?
I want to play little sound files at certain events, so I made following SoundThread
import java.io.*; import javax.sound.sampled.*; public class SoundThread implements Runnable{ private String filename; SoundThread(String filename) { this.filename = filename; } public void run() { try { InputStream in = ClassLoader.getSystemResourceAsStream("sounds/"+filename+".wav"); Clip clip = AudioSystem.getClip(); clip.open((AudioInputStream)in); clip.start(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } catch (LineUnavailableException e){ e.printStackTrace(); } } }
I run it with
new Thread(new SoundThread("nameOfTheSoundFile")).start();
At the beginning I handled it with the sun.audio.AudioPlayer and sun.audio.AudioStream, but as soon I put that code in eclipse, it showed me errors. So I tried
AudioInputStream in = (AudioInputStream)ClassLoader.getSystemResourceAsStream("sounds/"+filename+".wav");
to cast the InputStream to AudioInputStream (eclipse didn't show any errors), but running it it throws an ClassCastException. Is there any solution for this problem?