简体   繁体   English

如何从InputStream转换为AudioInputStream

[英]How to cast from InputStream to AudioInputStream

Is it possible to cast from an InputStream to an AudioInputStream? 是否可以从InputStream转换为AudioInputStream?

I want to play little sound files at certain events, so I made following SoundThread 我想在某些事件中播放小声音文件,所以我跟随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. 一开始我使用sun.audio.AudioPlayer和sun.audio.AudioStream处理它,但是一旦我将代码放在eclipse中,它就会向我显示错误。 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. 将InputStream强制转换为AudioInputStream(eclipse没有显示任何错误),但运行它会引发ClassCastException。 Is there any solution for this problem? 这个问题有什么解决方案吗?

Use the AudioSystem to get an AudioInputStream directly from the URL to the resource. 使用AudioSystem直接从URL获取AudioInputStream到资源。

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'. 另请参见AudioSystem.getAudioInputStream(InputStream)但这更“危险”。 Java Sound will typically require a repositionable input stream. Java Sound通常需要可重新定位的输入流。 For some reason that I am not quite clear on, the Class.getResourceAsStream() variants sometimes return a non -repositionable stream. 由于某些原因我不太清楚, Class.getResourceAsStream()变体有时会返回一个不可重入的流。

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. 在Java中,只有在您投射的真实对象已经是目标类型的实例时,对引用类型的类型转换才有效。 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 . 前两个成功是因为我们在第一行创建的字符串对象是Object一个实例(因为StringObject的子类型),还有一个String实例。 The third one fails because a String is NOT an Integer . 第三个失败,因为String不是Integer


In your example, the object that you get from getSystemResourceAsStream is a raw stream containing (presumably) audio data. 在您的示例中,您从getSystemResourceAsStream获取的对象是包含(可能)音频数据的原始流。 It is not an audio stream; 它不是音频流; ie not an instance of AudioInputStream . 即不是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. 或者使用AudioSystem.getAudioInputStream(...)工厂方法之一,它在引擎盖下进行包装。

See Andrew Thomson's answer for details of the RIGHT way to do this. 有关正确执行此操作的详细信息,请参阅Andrew Thomson的答案。

The InputStream returned by getSystemResourceAsStream is not an AudioInputStream , so casting it will never work. getSystemResourceAsStream返回的InputStream不是AudioInputStream ,因此转换它将永远不会工作。 Just create a new AudioInputStream instead. 只需创建一个新的AudioInputStream

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM