java 如何从 InputStream 转换到 AudioInputStream

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10591852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:43:47  来源:igfitidea点击:

How to cast from InputStream to AudioInputStream

javaaudiocastinginputstreamjavasound

提问by Valentino Ru

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. So I tried

一开始我用sun.audio.AudioPlayer 和sun.audio.AudioStream 处理它,但是一旦我将该代码放入eclipse,它就显示了错误。所以我试过了

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?

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

回答by Andrew Thompson

Use the AudioSystemto get an AudioInputStreamdirectly from the URLto the resource.

使用直接从AudioSystem获取资源。 AudioInputStreamURL

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.

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

回答by Stephen C

You can't cast it. In Java, a type cast on a reference type only works if the real object you are casting is alreadyan instance of the target type. For example:

你不能投。在 Java 中,仅当您正在转换的真实对象已经是目标类型的实例时,才能对引用类型进行类型转换。例如:

    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 Stringis a subtype of Object), and an instance of String. The third one fails because a Stringis NOT an Integer.

前两个成功是因为我们在第一行中创建的字符串对象是 的实例Object(因为String是 的子类型Object)和 的实例String。第三个失败,因为 aString不是Integer



In your example, the object that you get from getSystemResourceAsStreamis a raw stream containing (presumably) audio data. It is not an audio stream; i.e. not an instance of AudioInputStream.

在您的示例中,您从中获取的对象getSystemResourceAsStream是包含(大概)音频数据的原始流。它不是音频流;即不是AudioInputStream.

You have to wrapthe 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 的回答。

回答by Jeffrey

The InputStreamreturned by getSystemResourceAsStreamis not an AudioInputStream, so casting it will never work. Just create a new AudioInputStreaminstead.

InputStream返回的getSystemResourceAsStream不是一个AudioInputStream,所以铸造它永远不会工作。只需创建一个新的AudioInputStream