1

以下は私が見た中で最も可能性の高い説明へのリンクですが、まだ質問があります。

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()メソッドはimportcom.sun.tools.apt.Mainを必要とするようですしかし、そのためのドキュメントが見つからず、それが何をするのかわかりません。たとえば、「/ path / to / sounds /」は絶対的、または相対的であり、後者の場合、どこに相対的ですか?

シンプルな効果音を鳴らそうと何時間も費やしてきました。それがどれほど難しいかは信じられないほどです。上記のコードが機能するようになることを願っています。助けてくれてありがとう。

チャップ

4

3 に答える 3

1

これは、アプレットではなく、アプリケーションで機能しますか?

どちらでも動作します。

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

どこでそのアイデアを思いついたのですか?私はたくさんの健全な例を作りました、そしてあなたが使うべきではないそのクラスについて聞いたことがありません。

..しかし、そのためのドキュメントが見つかりません、..

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

..そして私はそれが何をするのか分かりません。たとえば、「/ path / to / sounds /」は絶対的、または相対的であり、後者の場合、どこに相対的ですか?

クラスパスのルートを基準にしています。

..それがどれほど難しいかは信じられないほどです。

一般に、メディアの処理には注意が必要です。


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

代わりに、私が(書いた&)個人的に推奨するこのコードを参照してください。

于 2011-06-17T17:11:47.913 に答える
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 \ Jeffrey \ bin \ path \ to \ sound \ + urlでリソースを検索します)

私はいつも次のようなサウンドをロードしました:

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

しかし、あなたの方法もうまくいくはずです。

于 2011-06-17T17:15:32.290 に答える
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);
}
}
于 2011-06-19T22:00:10.677 に答える