如何在Java Application中播放音频

我正在制作一个java应用程序,我需要播放音频。 我正在播放我的大炮射击的小声音文件(它是一个大炮射击游戏)和射弹爆炸,虽然我打算循环播放背景音乐。 我找到了两种不同的方法来实现这一目标,但两种方法都无法实现我想要的效果。

第一种方法实际上是一种方法:

public void playSoundFile(File file) {//http://java.ittoolbox.com/groups/technical-functional/java-l/sound-in-an-application-90681 try { //get an AudioInputStream AudioInputStream ais = AudioSystem.getAudioInputStream(file); //get the AudioFormat for the AudioInputStream AudioFormat audioformat = ais.getFormat(); System.out.println("Format: " + audioformat.toString()); System.out.println("Encoding: " + audioformat.getEncoding()); System.out.println("SampleRate:" + audioformat.getSampleRate()); System.out.println("SampleSizeInBits: " + audioformat.getSampleSizeInBits()); System.out.println("Channels: " + audioformat.getChannels()); System.out.println("FrameSize: " + audioformat.getFrameSize()); System.out.println("FrameRate: " + audioformat.getFrameRate()); System.out.println("BigEndian: " + audioformat.isBigEndian()); //ULAW format to PCM format conversion if ((audioformat.getEncoding() == AudioFormat.Encoding.ULAW) || (audioformat.getEncoding() == AudioFormat.Encoding.ALAW)) { AudioFormat newformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, audioformat.getSampleRate(), audioformat.getSampleSizeInBits() * 2, audioformat.getChannels(), audioformat.getFrameSize() * 2, audioformat.getFrameRate(), true); ais = AudioSystem.getAudioInputStream(newformat, ais); audioformat = newformat; } //checking for a supported output line DataLine.Info datalineinfo = new DataLine.Info(SourceDataLine.class, audioformat); if (!AudioSystem.isLineSupported(datalineinfo)) { //System.out.println("Line matching " + datalineinfo + " is not supported."); } else { //System.out.println("Line matching " + datalineinfo + " is supported."); //opening the sound output line SourceDataLine sourcedataline = (SourceDataLine) AudioSystem.getLine(datalineinfo); sourcedataline.open(audioformat); sourcedataline.start(); //Copy data from the input stream to the output data line int framesizeinbytes = audioformat.getFrameSize(); int bufferlengthinframes = sourcedataline.getBufferSize() / 8; int bufferlengthinbytes = bufferlengthinframes * framesizeinbytes; byte[] sounddata = new byte[bufferlengthinbytes]; int numberofbytesread = 0; while ((numberofbytesread = ais.read(sounddata)) != -1) { int numberofbytesremaining = numberofbytesread; sourcedataline.write(sounddata, 0, numberofbytesread); } } } catch (Exception e) { e.printStackTrace(); } } 

这个问题是我的整个程序停止,直到声音文件完成,或至少接近完成。

第二种方法是这样的:

  File file = new File("Launch1.wav"); AudioClip clip; try { clip = JApplet.newAudioClip(file.toURL()); clip.play(); } catch (Exception e) { e.getMessage(); } 

我在这里遇到的问题是每次声音文件提前结束或根本不播放取决于我放置代码的位置。

没有上述问题,他们是否可以播放声音? 难道我做错了什么? 任何帮助是极大的赞赏。

对于第一种方法,您必须为音频创建另一个线程。

例如这样:

 new Thread( new Runnable() { public void run() { try { // PLAY AUDIO CODE } catch (Exception e) { e.printStackTrace(); } } }).start(); 

当然,你必须确保以前的声音还没有播放。

我想你应该在后台线程中运行你的playSound方法,如本文档中所述

“你可能想要在与应用程序其余部分不同的线程中调用这个回放循环,这样你的程序在播放长音时似乎不会冻结”

也许通过做类似的事情

 // shared executor ExecutorService soundExecutor = ...; //Executors.newSingleThreadExecutor(); ... final File soundFile = ...; soundExecutor.submit(new Runnable(){ public void run(){ SoundUtils.playSoundFile(soundFile); } }); 

这个问题是我的整个程序停止,直到声音文件完成,或至少接近完成。

这尖叫是一个线程问题。 你试过在后台线程中播放声音吗? 顺便问一下,这是一个Swing计划吗? 如果是这样,请使用SwingWorker播放声音。 这有很多原因,但一个主要原因是通过SwingWorker内置的PropertyChangeListener支持很容易跟踪线程的状态。

您应该创建一个处理音频播放的线程。 但要确保它能够混合声音,因此两次发生的声音可以在正确的时间播放,而无需等待先前的声音完成。 那里应该有Frameworks为你做混音。

一个很好的起点是: http : //www.oracle.com/technetwork/java/javase/tech/index-jsp-140239.html