Javaでサウンドを再生するにはどうすればよいですか?


回答:


133

正常に動作する次のコードを書きました。しかし、それは.wavフォーマットでのみ機能すると思います。

public static synchronized void playSound(final String url) {
  new Thread(new Runnable() {
  // The wrapper thread is unnecessary, unless it blocks on the
  // Clip finishing; see comments.
    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();
}

7
Clipがランダムにシャットダウンされるのを防ぐには、LineListenerが必要です。見て:stackoverflow.com/questions/577724/trouble-playing-wav-in-java/...
yanchenko

3
公開APIを使用するソリューションの+1。新しいスレッドを作成する必要はありませんか?
Jataro 2009

4
ありがとう..それは冗長ですか?新しいスレッドにしたので、最初のクリップが終了する前にもう一度サウンドを再生できます。
2009

4
clip.start()が新しいスレッドを生成することを知っているので、それが不要であると確信しています。
Jataro 2009

44
1)Threadは不要です。2)の良い使用例Clipについては、JavaSound情報を参照してください。ページ。3)メソッドがURL(またはFile)を必要とする場合、それを表すaではなく、dang URL(またはFile)を指定しStringます。(ちょうど私のボンネットの中の個人的なものです。)4)e.printStackTrace();より少ないタイプでより多くの情報を提供しますSystem.err.println(e.getMessage());
Andrew Thompson

18

悪い例:

import  sun.audio.*;    //import the sun.audio package
import  java.io.*;

//** add this into your application code as appropriate
// Open an input stream  to the audio file.
InputStream in = new FileInputStream(Filename);

// Create an AudioStream object from the input stream.
AudioStream as = new AudioStream(in);         

// Use the static class member "player" from class AudioPlayer to play
// clip.
AudioPlayer.player.start(as);            

// Similarly, to stop the audio.
AudioPlayer.player.stop(as); 

13
java.sun.com/products/jdk/faq/faq-sun-packages.html sun.audioを使用する代わりに公開APIがあります。
McDowell、

4
@GregHurlman sun。*パッケージは私たちの開発者が使用しないように作られていますか?
Tom Brito

36
この例は、1997年のJavaWorldの記事に基づいています。時代遅れです。sun。*パッケージは使用しないでください。
sproketboy

3
「閉じ込める」必要がありますか?
rogerdpack 2010

6
sun。*パッケージを使用しない場合は+1 。彼らは、以前はなど、まだ完了していない場合は、1つのクリップを再生することができるというファイル> 1メガバイトを処理していないではないような奇妙なバグを持っている
rogerdpack

10

単純なくそな音を再生するためだけに多くのコード行を入れたくありませんでした。これは、JavaFXパッケージ(すでに私のjdk 8に含まれている)を持っている場合に機能します。

private static void playSound(String sound){
    // cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader();
    URL file = cl.getResource(sound);
    final Media media = new Media(file.toString());
    final MediaPlayer mediaPlayer = new MediaPlayer(media);
    mediaPlayer.play();
}

注意:JavaFX初期化する必要があります。これを行う簡単な方法は、アプリでJFXPanel()のコンストラクターを1回呼び出すことです。

static{
    JFXPanel fxPanel = new JFXPanel();
}

8

Javaでサウンドを再生するには、次のコードを参照できます。

import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;

// To play sound using Clip, the process need to be alive.
// Hence, we use a Swing application.
public class SoundClipTest extends JFrame {

   public SoundClipTest() {
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setTitle("Test Sound Clip");
      this.setSize(300, 200);
      this.setVisible(true);

      try {
         // Open an audio input stream.
         URL url = this.getClass().getClassLoader().getResource("gameover.wav");
         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
         // Get a sound clip resource.
         Clip clip = AudioSystem.getClip();
         // Open audio clip and load samples from the audio input stream.
         clip.open(audioIn);
         clip.start();
      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }
   }

   public static void main(String[] args) {
      new SoundClipTest();
   }
}

7

なんらかの理由で、wcharginの一番の答えは、this.getClass()。getResourceAsStream()を呼び出したときにnullポインターエラーが発生することでした。

私にとってうまくいったのは次のとおりです:

void playSound(String soundFile) {
    File f = new File("./" + soundFile);
    AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL());  
    Clip clip = AudioSystem.getClip();
    clip.open(audioIn);
    clip.start();
}

そして、私は音を再生します:

 playSound("sounds/effects/sheep1.wav");

sound / effects / sheep1.wavは、Eclipseの私のプロジェクトのベースディレクトリにありました(srcフォルダー内ではありません)。


こんにちはアンリュー、あなたのコードは私のために働いたが、実行に少し余分な時間がかかることに気付いた...約1.5秒。

getResourceAsStream()nullリソースが見つからない場合は戻りますが、そうnamenullない場合は例外をスローします-指定されたパスが有効でない場合、トップアンサーのエラーではありません
user85421

3

Androidとデスクトップで動作するように、ゲームフレームワークを少し前に作成しました。サウンドを処理するデスクトップ部分は、おそらく必要なもののインスピレーションとして使用できます。

https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java

参照用のコードを以下に示します。

package com.athanazio.jaga.desktop.sound;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Sound {

    AudioInputStream in;

    AudioFormat decodedFormat;

    AudioInputStream din;

    AudioFormat baseFormat;

    SourceDataLine line;

    private boolean loop;

    private BufferedInputStream stream;

    // private ByteArrayInputStream stream;

    /**
     * recreate the stream
     * 
     */
    public void reset() {
        try {
            stream.reset();
            in = AudioSystem.getAudioInputStream(stream);
            din = AudioSystem.getAudioInputStream(decodedFormat, in);
            line = getLine(decodedFormat);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            line.close();
            din.close();
            in.close();
        } catch (IOException e) {
        }
    }

    Sound(String filename, boolean loop) {
        this(filename);
        this.loop = loop;
    }

    Sound(String filename) {
        this.loop = false;
        try {
            InputStream raw = Object.class.getResourceAsStream(filename);
            stream = new BufferedInputStream(raw);

            // ByteArrayOutputStream out = new ByteArrayOutputStream();
            // byte[] buffer = new byte[1024];
            // int read = raw.read(buffer);
            // while( read > 0 ) {
            // out.write(buffer, 0, read);
            // read = raw.read(buffer);
            // }
            // stream = new ByteArrayInputStream(out.toByteArray());

            in = AudioSystem.getAudioInputStream(stream);
            din = null;

            if (in != null) {
                baseFormat = in.getFormat();

                decodedFormat = new AudioFormat(
                        AudioFormat.Encoding.PCM_SIGNED, baseFormat
                                .getSampleRate(), 16, baseFormat.getChannels(),
                        baseFormat.getChannels() * 2, baseFormat
                                .getSampleRate(), false);

                din = AudioSystem.getAudioInputStream(decodedFormat, in);
                line = getLine(decodedFormat);
            }
        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        }
    }

    private SourceDataLine getLine(AudioFormat audioFormat)
            throws LineUnavailableException {
        SourceDataLine res = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class,
                audioFormat);
        res = (SourceDataLine) AudioSystem.getLine(info);
        res.open(audioFormat);
        return res;
    }

    public void play() {

        try {
            boolean firstTime = true;
            while (firstTime || loop) {

                firstTime = false;
                byte[] data = new byte[4096];

                if (line != null) {

                    line.start();
                    int nBytesRead = 0;

                    while (nBytesRead != -1) {
                        nBytesRead = din.read(data, 0, data.length);
                        if (nBytesRead != -1)
                            line.write(data, 0, nBytesRead);
                    }

                    line.drain();
                    line.stop();
                    line.close();

                    reset();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

このコードはにstream.reset();つながるとエラーになる可能性がありますResetting to invalid mark。これを修正するために何をすることを提案しますか?
driima

ストリームを再作成してください。stackoverflow.com
questions /

1
これを実際に解決するにはraw.mark(raw.available()+1)、初期化raw後にwhileループで使用し、のraw.reset()代わりに使用しますstream.reset()。私の今の問題は、それがリセットすることになると、プレーの間にギャップがあるということです。あなたがで得るような連続ループを実現したいのですがClipClipMASTER_GAINなどのコントロールの操作には500msほどの遅延があるため、使用していません。これはおそらく、後で質問するための独自の質問になるはずです。
driima

じゃないdo { ... } while
Andreas

2

アプレットとアプリケーションの両方で機能するサウンドファイルをインポートする代わりに、オーディオファイルを.javaファイルに変換して、コードで単に使用する方法があります。

私はこのプロセスをずっと簡単にするツールを開発しました。Java Sound APIをかなり単純化します。

http://stephengware.com/projects/soundtoclass/


私はあなたのシステムを使用してwavファイルからクラスを作成しましたが、my_wave.play();を実行すると、それは私が初期化か何かする必要があるオーディオシステムがあります。..オーディオを再生しません..?
ネイサンF.

それが実際に機能した場合、これは本当にクールです。play()を実行すると、オーディオラインの取得が失敗します(例外「java.lang.IllegalArgumentException:ラインマッチングインターフェイスSourceDataLineサポート形式PCM_UNSIGNED 44100.0 Hz、16ビット、ステレオ、4バイト/フレーム、リトルエンディアンはサポートされません。」は例外です)。スローされます)。悲しい。
phil294

2

誰もがアプレットの使用を提案していないことに驚いています。を使用し Appletます。ビープオーディオファイルをファイルとして提供する必要がありwavますが、機能します。私はこれをUbuntuで試しました:

package javaapplication2;

import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

public class JavaApplication2 {

    public static void main(String[] args) throws MalformedURLException {
        File file = new File("/path/to/your/sounds/beep3.wav");
        URL url = null;
        if (file.canRead()) {url = file.toURI().toURL();}
        System.out.println(url);
        AudioClip clip = Applet.newAudioClip(url);
        clip.play();
        System.out.println("should've played by now");
    }
}
//beep3.wav was available from: http://www.pacdv.com/sounds/interface_sound_effects/beep-3.wav

2
AppletJavaの9のよう推奨されていません
Fre_d

0

このスレッドはかなり古いですが、役立つと思われるオプションを決定しました。

Java AudioStreamライブラリを使用する代わりに、Windows Media PlayerやVLCなどの外部プログラムを使用して、Javaを介してコンソールコマンドで実行できます。

String command = "\"C:/Program Files (x86)/Windows Media Player/wmplayer.exe\" \"C:/song.mp3\"";
try {
    Process p = Runtime.getRuntime().exec(command);
catch (IOException e) {
    e.printStackTrace();
}

これにより、プログラムで制御できる別のプロセスも作成されます。

p.destroy();

もちろん、これは内部ライブラリを使用するよりも実行に時間がかかりますが、特定のコンソールコマンドを与えられたGUIなしで、より速く起動できるプログラムがあるかもしれません。

時間が本質ではない場合、これは役立ちます。


4
これは(信頼性、効率、およびその他のそのようなメトリックに関して)客観的に悪いソリューションだと思いますが、他の方法では考えられなかった少なくとも興味深いソリューションです。
マックスフォンヒッペル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.