如何在 Java 中播放声音?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26305/
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-08-11 07:18:06  来源:igfitidea点击:

How can I play sound in Java?

javaaudio

提问by pek

I want to be able to play sound files in my program. Where should I look?

我希望能够在我的程序中播放声音文件。我应该在哪里看?

采纳答案by pek

I wrote the following code that works fine. But I think it only works with .wavformat.

我编写了以下工作正常的代码。但我认为它只适用于.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();
}

回答by Greg Hurlman

A bad example:

一个不好的例子:

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); 

回答by Stephen Ware

There is an alternative to importing the sound files which works in both applets and applications: convert the audio files into .java files and simply use them in your code.

导入声音文件的替代方法可以在小程序和应用程序中使用:将音频文件转换为 .java 文件,然后在代码中简单地使用它们。

I have developed a tool which makes this process a lot easier. It simplifies the Java Sound API quite a bit.

我开发了一个工具,可以让这个过程变得更容易。它大大简化了 Java Sound API。

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

http://stephenware.com/projects/soundtoclass/

回答by hamilton.lima

I created a game framework sometime ago to work on Android and Desktop, the desktop part that handle sound maybe can be used as inspiration to what you need.

前段时间我创建了一个游戏框架,可以在 Android 和桌面上运行,处理声音的桌面部分可能可以作为您需要的灵感。

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

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

Here is the code for reference.

这是代码供参考。

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();
        }
    }

}

回答by Ishwor

For playing sound in java, you can refer to the following code.

在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();
   }
}

回答by Cyril Duchon-Doris

I didn't want to have so many lines of code just to play a simple damn sound. This can work if you have the JavaFX package (already included in my jdk 8).

我不想有这么多行代码只是为了播放一个简单的该死的声音。如果您有 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();
}

Notice : You need to initialize JavaFX. A quick way to do that, is to call the constructor of JFXPanel() once in your app :

注意:您需要初始化 JavaFX。一个快速的方法是在你的应用程序中调用一次 JFXPanel() 的构造函数:

static{
    JFXPanel fxPanel = new JFXPanel();
}

回答by Andrew Jenkins

For whatever reason, the top answer by wchargin was giving me a null pointer error when I was calling this.getClass().getResourceAsStream().

无论出于何种原因,当我调用 this.getClass().getResourceAsStream() 时,wchargin 的最佳答案是给了我一个空指针错误。

What worked for me was the following:

对我有用的是以下内容:

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

And I would play the sound with:

我会播放声音:

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

sounds/effects/sheep1.wav was located in the base directory of my project in Eclipse (so not inside the src folder).

sound/effects/sheep1.wav 位于 Eclipse 中我的项目的基本目录中(所以不在 src 文件夹中)。

回答by Galen Nare

This thread is rather old but I have determined an option that could prove useful.

这个线程很旧,但我已经确定了一个可能有用的选项。

Instead of using the Java AudioStreamlibrary you could use an external program like Windows Media Player or VLC and run it with a console command through Java.

AudioStream您可以不使用Java库,而是使用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();
}

This will also create a separate process that can be controlled it the program.

这也将创建一个单独的进程,可以控制它的程序。

p.destroy();

Of course this will take longer to execute than using an internal library but there may be programs that can start up faster and possibly without a GUI given certain console commands.

当然,这比使用内部库需要更长的时间来执行,但可能有一些程序可以更快地启动,并且可能没有给定某些控制台命令的 GUI。

If time is not of the essence then this is useful.

如果时间不是关键,那么这很有用。

回答by Nav

I'm surprised nobody suggested using Applet. UseApplet. You'll have to supply the beep audio file as a wavfile, but it works. I tried this on Ubuntu:

我很惊讶没有人建议使用 Applet。使用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