如何在Java中播放声音?
我希望能够在我的程序中播放声音文件。 我应该在哪里看?
我写了下面的代码,工作正常。 但我认为它只适用于.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(); }
Java教程的声音线索是值得成为起点的。
一个不好的例子:
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);
在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(); } }
我不想有太多的代码只是为了演奏一个简单的该死的声音。 这可以工作,如果你有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()的构造函数:
static{ JFXPanel fxPanel = new JFXPanel(); }
还有一种方法可以导入在Applet和应用程序中工作的声音文件:将audio文件转换成.java文件,并在代码中简单地使用它们。
我开发了一个使这个过程更容易的工具。 它相当简化了Java Sound API。
无论出于何种原因,当我调用this.getClass()。getResourceAsStream()时,wchargin的顶部答案给了我一个空指针错误。
对我有效的是以下几点:
void playSound(String soundFile) { File f = new File("./" + soundFile); audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL()); Clip clip = AudioSystem.getClip(); clip.open(audioIn); clip.start(); }
我会用下面的方式播放声音:
playSound("sounds/effects/sheep1.wav");
sounds / effects / sheep1.wav位于Eclipse项目的基本目录中(因此不在src文件夹中)。
我之前创build了一个游戏框架来处理Android和桌面,处理声音的桌面部分也许可以作为您需要的灵感来使用。
这里是供参考的代码。
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(); } } }
这个线程是相当老,但我已经确定了一个可以certificate有用的选项。
您可以不使用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(); }
这也将创build一个单独的过程,可以控制它的程序。
p.destroy();
当然,这比使用内部库需要更长的时间来执行,但是可能会有程序启动得更快,可能没有给定某些控制台命令的GUI。
如果时间不是本质的,那么这是有用的。