3

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 がスローされます。この問題の解決策はありますか?

4

3 に答える 3

7

からリソースへの を 直接AudioSystem取得するには、 を使用します。AudioInputStreamURL

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()バリアントは再配置不可能なストリームを返すことがあります

于 2012-05-14T22:34:09.963 に答える
1

キャストできません。Java では、参照型の型キャストは、キャストしている実際のオブジェクトが既にターゲット型のインスタンスである場合にのみ機能します。例えば:

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

最初の行で作成した文字列オブジェクトは のインスタンスObject(Stringは のサブタイプであるためObject) であり、 のインスタンスであるため、最初の 2 つが成功しますStringStringaが an ではないため、3 番目は失敗しますInteger


あなたの例では、取得するオブジェクトgetSystemResourceAsStreamは、(おそらく) オーディオ データを含む生のストリームです。これはオーディオ ストリームではありません。のインスタンスではありませんAudioInputStream

次のように、生の入力ストリームをラップする必要があります。

    InputStream in = ClassLoader.getSystemResourceAsStream(
        "sounds/"+filename+".wav");
    AudioFormat format = ...
    int length = ...
    AudioInputStream audio = new AudioInputStream(in, format, length);

またはAudioSystem.getAudioInputStream(...)、ボンネットの下でラッピングを行うファクトリ メソッドのいずれかを使用します。

これを行う正しい方法の詳細については、Andrew Thomson の回答を参照してください。

于 2012-05-14T22:35:01.980 に答える
0

InputStreamによって返されるはgetSystemResourceAsStreamではないためAudioInputStream、キャストは機能しません。AudioInputStream代わりに新しいものを作成してください。

于 2012-05-14T22:33:32.497 に答える