如何从InputStream转换为AudioInputStream

时间:2012-05-14 22:23:43

标签: java audio casting inputstream javasound

是否可以从InputStream转换为AudioInputStream?

我想在某些事件中播放小声音文件,所以我跟随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();
        } 
    }
}

我用

运行它
new Thread(new SoundThread("nameOfTheSoundFile")).start();

一开始我用sun.audio.AudioPlayer和sun.audio.AudioStream处理它,但是一旦我把这个代码放在eclipse中,它就向我显示了错误。所以我试过

AudioInputStream in = (AudioInputStream)ClassLoader.getSystemResourceAsStream("sounds/"+filename+".wav");

将InputStream强制转换为AudioInputStream(eclipse没有显示任何错误),但运行它会抛出ClassCastException。这个问题有什么解决方案吗?

3 个答案:

答案 0 :(得分:7)

使用AudioSystem直接从AudioInputStream获取URL资源。

URL url = ClassLoader.getResource("/sounds/"+filename+".wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.open(ais);

另见AudioSystem.getAudioInputStream(InputStream),但这更“危险”。 Java Sound通常需要可重新定位的输入流。出于某些原因,我不太清楚,Class.getResourceAsStream()变体有时会返回 - 可重定位的流。

答案 1 :(得分:1)

你无法施展它。在Java中,引用类型上的类型转换仅在您要转换的实际对象目标类型的实例时才有效。例如:

    String myString = new String("42");
    Object obj = (Object) myString;  // OK
    String mystery = (String) obj;   // OK
    String mystery2 = (Integer) obj; // FAIL

前两个成功,因为我们在第一行创建的字符串对象是Object的实例(因为StringObject的子类型),并且实例为{ {1}}。第三个失败是因为String不是String


在您的示例中,您从Integer获得的对象是包含(可能)音频数据的原始流。它不是音频流;即不是getSystemResourceAsStream的实例。

你必须包装原始输入流,如下所示:

AudioInputStream

或使用 InputStream in = ClassLoader.getSystemResourceAsStream( "sounds/"+filename+".wav"); AudioFormat format = ... int length = ... AudioInputStream audio = new AudioInputStream(in, format, length); 工厂方法之一进行引擎封装。

有关正确方法的详细信息,请参阅Andrew Thomson的答案。

答案 2 :(得分:0)

InputStream返回的getSystemResourceAsStream不是AudioInputStream,因此投射它将永远不会有效。只需创建一个新的AudioInputStream