Java剪辑不起作用

有人可以帮我理解为什么下面这段代码不起作用?

我通过调用方法start()启动剪辑。 此方法为剪辑创建一个新线程以运行。 然而,不,它似乎没有发挥任何作用。

编译代码时没有任何错误……

 public class Audio { private Clip clip; private Thread thread; public Audio (String audioFile) { AudioInputStream audioStream = null; URL audioURL = this.getClass().getClassLoader().getResource(audioFile); // Obtain audio input stream from the audio file and load the information // into main memory using the URL path retrieved from above. try { audioStream = AudioSystem.getAudioInputStream(audioURL); } catch (Exception e) { e.printStackTrace(); System.exit(1); } try { // Retrieve the object of class Clip from the Data Line. this.clip = AudioSystem.getClip(); // Load the audio input stream into memory for future play-back. this.clip.open(audioStream); } catch (LineUnavailableException e) { e.printStackTrace(); System.exit(1); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } public void start() { Runnable r = new Runnable() { public void run() { loop(); } }; thread = new Thread(r); thread.start(); } public void loop () { // Rewind the media to the beginning of the clip. this.clip.setFramePosition(0); // Continuously play the clip. this.clip.loop(Clip.LOOP_CONTINUOUSLY); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } 

UPDATE

我发现了问题! 问题是因为音频文件。 我使用了不同的音频文件,我可以用上面的代码听到声音。

编译的代码没有任何错误或警告真的很烦人。 我通过获取音频格式检测到问题,然后将其传递给类DataLine.Info的对象。 然后,从数据线中检索剪辑。

所以,基本上不是通过以下方式获取剪辑:

 this.clip = AudioSystem.getClip(); 

我会得到剪辑:

 AudioFormat format = audioStream.getFormat(); DataLine.Info info = new DataLine.Info(Clip.class, format); this.clip = (Clip) AudioSystem.getLine(info); 

当我用这个编译时,Java抛出了以下错误:

没有行匹配接口Clip支持格式PCM_SIGNED 48000.0 Hz,24位

所以,我替换了音频文件,它工作了!

clip.loop是一个非阻塞调用。 也就是说,一旦你调用它(并且它完成它所做的),它将返回,这意味着你的线程将退出,除非有另一个非守护程序线程在运行,否则JVM将退出。

我曾经以为你可能能够使用Clip#drain来阻止它直到剪辑完成,但从技术上讲,剪辑将无法完成……在正常意义上。

相反,我建立了自己的循环……

 public void start() { Runnable r = new Runnable() { public void run() { while (true) { clip.setFramePosition(0); clip.start(); clip.drain(); } } }; thread = new Thread(r); thread.start(); } 

现在,这可能是一个问题,因为Thread是一个非守护进程线程并且永远不会结束…而不是while (true) {你应该设置一些你设置为false并帮助终止循环的volitle标志.. 。

例如…

 import java.io.IOException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.LineUnavailableException; public class Audio { private Clip clip; private Thread thread; private volatile boolean keepPlaying = true; public static void main(String[] args) { Audio audio = new Audio("Kalimba.wav"); audio.start(); try { Thread.sleep(5000); } catch (InterruptedException ex) { } audio.stop(); } public Audio(String audioFile) { AudioInputStream audioStream = null; URL audioURL = this.getClass().getClassLoader().getResource(audioFile); // Obtain audio input stream from the audio file and load the information // into main memory using the URL path retrieved from above. try { audioStream = AudioSystem.getAudioInputStream(audioURL); } catch (Exception e) { e.printStackTrace(); System.exit(1); } try { // Retrieve the object of class Clip from the Data Line. this.clip = AudioSystem.getClip(); // Load the audio input stream into memory for future play-back. this.clip.open(audioStream); } catch (LineUnavailableException e) { e.printStackTrace(); System.exit(1); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } public void stop() { if (thread != null) { keepPlaying = false; clip.stop(); thread.interrupt(); } } public void start() { Runnable r = new Runnable() { public void run() { while (keepPlaying) { clip.setFramePosition(0); clip.start(); clip.drain(); } } }; thread = new Thread(r); thread.start(); } } 

更新

上面的例子(恕我直言)有一些问题,可以用简单的对象监视器修复。

因此,我们可以使用Clip#loopfunction而不是volatile标志和while循环,而只需使用Object#waitObject#notify ,例如

 import java.io.IOException; import java.net.URL; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.LineUnavailableException; public class Audio { private Clip clip; private Thread thread; private final Object loopLock = new Object(); public static void main(String[] args) { Audio audio = new Audio("Music.wav"); audio.start(); try { Thread.sleep(5000); } catch (InterruptedException ex) { } audio.stop(); } public Audio(String audioFile) { AudioInputStream audioStream = null; URL audioURL = this.getClass().getClassLoader().getResource(audioFile); // Obtain audio input stream from the audio file and load the information // into main memory using the URL path retrieved from above. try { audioStream = AudioSystem.getAudioInputStream(audioURL); } catch (Exception e) { e.printStackTrace(); System.exit(1); } try { // Retrieve the object of class Clip from the Data Line. this.clip = AudioSystem.getClip(); // Load the audio input stream into memory for future play-back. this.clip.open(audioStream); } catch (LineUnavailableException e) { e.printStackTrace(); System.exit(1); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } public void stop() { synchronized (loopLock) { loopLock.notifyAll(); } } public void start() { Runnable r = new Runnable() { public void run() { clip.setFramePosition(0); clip.loop(Clip.LOOP_CONTINUOUSLY); synchronized (loopLock) { try { loopLock.wait(); } catch (InterruptedException ex) { } } clip.stop(); } }; thread = new Thread(r); thread.start(); } }