2011-06-17 10 views
1

以下は私が見た可能性が最も高い説明へのリンクですが、まだ質問があります。Javaアプリケーションはどのようにサウンドクリップを再生できますか?

How can I play sound in Java?

私はここで、コードを引用します:

public static synchronized void playSound(final String url) { 
new Thread(new Runnable() { 
    public void run() { 
    try { 
     Clip clip = AudioSystem.getClip(); 
     AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream("/path/to/sounds/" + url)); 
     clip.open(inputStream); 
     clip.start(); 
    } catch (Exception e) { 
     System.err.println(e.getMessage()); 
    } 
    } 
}).start(); 

}

  1. をアプレットとは対照的に、アプリケーションでこの仕事をしていますか?
  2. Main.class.getResourceAsStream()メソッドが必要と思われるimport com.sun.tools.apt.Main;しかし、私はそれのためのドキュメントを見つけることができない、と私はそれが何かを知らない。例えば、 "/ path/to/sounds /"は絶対的なものか相対的なものか、後者の場合は相対的なものですか?

シンプルなサウンドエフェクトを再生しようと多くの時間を費やしました。それがいかに難しいかは信じられないほどです。私は上記のコードが働くことができることを願っています。助けてくれてありがとう。

答えて

0

私は@ Andrewのコードから大きく引っ張ってきましたが、私はここでいくつか調整をしなければなりませんでした。以下はサンプルの.wavファイルを除き、私のソリューションのデモです。

// Developed in Eclipse, YMMV regarding resource location. 
import java.net.URL; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 

class ClipPlayer { 

public static void main(String[] args) { 
    // First, instantiate ourselves so we can call demoSam which 
    // needs to be able to do a wait(). 
    ClipPlayer cp = new ClipPlayer(); 
    // Now run the actual demo 
    cp.demoSam(); 
} 

private void demoSam() { 

    /** 
    * Construct a Sam, capable of playing the "Chook.wav", a 0.1 sec sound. 
    * NOTE: it's very tricky debugging an incorrectly-located 
    * resource file, and I'm unable to give a general rule 
    * here. But in this example, Chook.wav is expected to be in the same 
    * directory as the .class file, and there is no surrounding 
    * package (i.e. we're taking the default package name). If you 
    * are using a package, you may have to write "myPackage/Chook.wav" 
    * instead. 
    */ 

    Sam sam; 
    try { 
     sam = new Sam("Chook.wav"); // or whatever, but it has to be .wav 
    } 
    catch (Exception e) { 
     say("Exception thrown by Sam: " + e.getMessage()); 
     System.exit(1); // scoot 
     return; // get rid of warning about sam possib not init'd 
    } 
    int countDown = 20; 
    do { 
     say("Doing something requiring accompanying sound effect..."); 
     try { 
      sam.playIt(); 
     } 
     catch (Exception e) { 
      say("Caught exception from playIt: " + e.getMessage()); 
      System.exit(1); 
     } 

     // Now wait a human-scale duration, like 1/8 second. In 
     // practice we may be processing, since the sound is playing 
     // asynchronously. 

     synchronized (this) { 
      try { 
       wait(125); // wait 1/8 sec 
      } 
      catch (Exception e2) { 
       say("huh?"); 
      } 
     } 
    } while (--countDown > 0); 

} 

/** 
* 'Sam' is a class that implements one method, playIt(), that simply 
* plays the .wav file clip it was instantiated with. Just using an 
* inner class here for simplicity of demo. 
*/ 
final class Sam { 

    AudioInputStream ais; 
    Clip    clip; 

    /** 
    * Constructor: prepare clip to be played. Do as much here as 
    * possible, to minimize the overhead of playing the clip, 
    * since I want to call the play() method 5-10 times a second. 
    */ 
    Sam(String clipName) throws Exception { 

     // Resource is in same directory as this source code. 
     ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
     URL url = classLoader.getResource(clipName); 
     ais = AudioSystem.getAudioInputStream(url); 
     clip = AudioSystem.getClip(); 
     clip.open(ais); 
    } 

    /** 
    * playIt(): Start the clip playing once, asynchronously, and exit. 
    */ 
    public void playIt() throws Exception { 
     clip.setFramePosition(0); // Must always rewind! 
     clip.loop(0); 
     clip.start(); 
    } 
} 

private static void say(String s) { 
    System.out.println(s); 
} 
} 
1

アプレットとは反対に、アプリケーションでこの仕事をしていますか?

どちらでも動作します。

メソッドMain.class.getResourceAsStream()は、import com.sun.tools.apt.Mainを必要とするようです。

あなたはそのアイデアをどこで手に入れましたか?私はたくさんの音の例を作りました。そして、あなたが使ってはいけないクラスについて聞いたことはありません。私はそのためのドキュメントを見つけることができません..but

..

いいえ、com.sunクラスがないだけで文書化されていないですが、次のマイクロバージョンで変更される可能性があります。

..と私はそれが何かを知りません。例えば、 "/ path/to/sounds /"は絶対的なものか相対的なものか、後者の場合は相対的なものですか?

これは、class-pathのルートからの相対パスです。

..それはどれほど難しいのですか。

一般的なメディアの取り扱いは厄介です。


私は、リンクされたスレッドのコードにあまり感心していません。 Threadラッパーは、Clipのインスタンスを同時に再生する場合でも、コメントのいくつかで説明したように、は不要です。

代わりに、私は個人的にお勧めします(&を書いた)this codeを参照してください。

+0

興味深い:あなたの最後の行は 'JOptionPane.showMessageDialog(null、"終わりに近い.. ..); 'です。不在の場合、サウンドクリップは、プログラムが終了してから開始するとすぐに再生が停止します。 @Chapがこれを認識しているのだろうかと思います。 – toto2

+0

ここで間違ったフォーマットをしているのは残念です。引用ブロックを達成する方法を知らない。その問題のための新しい行、grrr。 Main.class.getResourceAsStream()メソッドは、import com.sun.tools.apt.Mainを必要とするようです。 あなたはそのアイデアをどこで手に入れましたか?私はたくさんの音の例を作りました。そして、あなたが使ってはいけないクラスについて聞いたことはありません。 ええ - NetBeansやEclipseの「クリーンアップインポート」で提案されています。 – Chap

+0

@toto:いいえ、私はかなり素早くそれを理解していたでしょう:-) @andrew:あなたのコードに感謝します。私はそれを "ローカル"オーディオファイルリソースを見つけるための他の提案と組み合わせることができると思います。 – Chap

1
  1. これはアプリケーションで動作するはずです。
  2. このコード行は、そのメソッドがあるクラスを参照している可能性が最も高いです。そのメソッドはもともとMainクラスにあったので、メソッドをFooBarクラスに入れると、FooBar.class.getResourceAsStream()に変更する必要があります。
  3. 相対パスです。それはすべてのパッケージの外のリソースを探します。例:このコードを実行しているクラスがC:\ Users \ Jeffrey \ bin \ foo \ bar \ SoundPlayer.classにあり、クラスがパッケージfoo.barにあるとします。つまり、ClassLoaderはC:\ Users \ Jeffrey \ bin \フォルダ内のリソースを検索します。 (あなたのケースでは、それはCでリソースを探します:音を\する\ Users \ユーザージェフリー\ビン\パス\ \ + URL)

は、このようなI常にロード音:

Clip sound = (Clip) AudioSystem.getLine(new Line.Info(Clip.class)); 
sound.open(AudioSystem.getAudioInputStream(file)); 

あなたの方法はまた働かなければならない。

+1

#2に関しては、実際にメソッドを非静的にしてからgetClass()を使用するだけです。 – Dave

+0

** Main.class **の部分を赤ん坊として識別し、** getResourceAsStream()**のヘルプに感謝します。 – Chap

関連する問題