代码
import javax.sound.sampled.*;
import java.io.*;
public class Tester {
static Thread th;
public static void main(String[] args) {
startNewThread();
while( th.isAlive() == true) {
System.out.println("sound thread is working");
}
}
public static void startNewThread() {
Runnable r = new Runnable() {
public void run() {
startPlaying();
}
};
th =new Thread(r);
th.start();
}
public static void startPlaying() {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(new File("d:/UnderTest/wavtester.wav"));
Clip clip = AudioSystem.getClip();
clip.open(ais);
clip.loop(-1); // keep playing the sound
} catch(Exception exc) {
System.out.println(exc);
}
}
}
此代码确实输出声音线程正常,但不播放任何内容。在这段代码中,我已经启动了一个单独的线程来播放声音,程序不应该终止,直到声音线程完成它的工作。但程序在打印声音线程工作系列后终止。
这个的原因是什么(程序终止和声音没有播放)?
答案 0 :(得分:6)
问题是Clip
已经启动了后台 守护程序 线程来播放wave文件。
因此,代码的执行流程如下:
最终的结果正是你所看到的:当辅助线程启动播放线程时,主线程会打印一些文本,当播放线程开始播放时,JVM就会完成。有时你甚至可以在JVM退出之前从耳机中听到一些“点击”(当声音开始播放时)。
最简单的解决方法是在播放声音时让辅助线程(即非守护程序线程)休眠。
...
clip.open(ais);
clip.loop(-1);
Thread.sleep(amountToSleep);
...
需要注意的一件重要事情:大约1年前,当我使用该java API时,我注意到方法getMicrosecondLength()
是错误的。我在Windows和Linux上编码,在一个平台上我得到了正确的值,但在另一个平台上,同样的方法会以毫秒为单位返回长度!
我发现获得声音实际长度的最可靠方法是使用getFrameLength()
方法,并从中计算长度。
我找不到我在这个笔记本上写的代码。我将在稍后的另一台PC上查看,如果我发现它,我将发布一个完整的示例(在使用Sun JVM和Linux的Windows上使用OpenJDK或Sun可靠地运行。)
答案 1 :(得分:0)
import javax.sound.sampled.*;
import java.io.*;
import javax.swing.*;
public class Tester {
static Thread th;
public static void main(String[] args) throws Exception {
Clip clip = AudioSystem.getClip();
AudioInputStream ais = AudioSystem.getAudioInputStream(new File("d:/UnderTest/wavtester.wav"));
clip.open(ais);
clip.loop(0);
// Calculate totalFrames
long totalFrames = (long)(clip.getFrameLength() * clip.getFormat().getFrameRate());
Thread.sleep( ( totalFrames* 1000 )); // pause the thread till the sound plays
System.out.println(clip.getFrameLength());
System.out.println(clip.getFormat().getFrameRate());
}
}
答案 2 :(得分:0)
while(clip.isRunning()){}
更好