How to cast from InputStream to AudioInputStream

做~自己de王妃 提交于 2020-01-03 19:32:06

问题


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?


回答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.




回答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.




回答3:


The InputStream returned by getSystemResourceAsStream is not an AudioInputStream, so casting it will never work. Just create a new AudioInputStream instead.



来源:https://stackoverflow.com/questions/10591852/how-to-cast-from-inputstream-to-audioinputstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!