例一:java程序定时播放音乐:
public static void main(String[] args) {
play(XXXapplication.class.getResourceAsStream("/file/开始.wav"), 0, 3);
}
public static void play(InputStream filePath, int min, int sec){
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(filePath));
AudioFormat format = audioInputStream.getFormat();
if (!AudioSystem.isLineSupported(new DataLine.Info(Clip.class, format))) {
System.err.println("Line not supported for this audio format.");
} else {
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
Thread.sleep(((long) min * 60L + (long) sec) * 1000L);
clip.close();
}
}
例二:实现检测音乐播放完自动关闭clip并执行后续代码(与例一区别为不需要传参"音乐完成的时间"):
public static void play(InputStream in){
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(in));
AudioFormat format = audioInputStream.getFormat();
if (!AudioSystem.isLineSupported(new DataLine.Info(Clip.class, format))) {
System.err.println("Line not supported for this audio format.");
} else {
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
// 获取音频格式
AudioFormat audioFormat = audioInputStream.getFormat();
// 获取帧长度(如果可用)
long frameLength = audioInputStream.getFrameLength();
// 如果音频流没有指定帧长度,则需要找到音频文件的总字节数
if (frameLength == AudioSystem.NOT_SPECIFIED) {
frameLength = audioInputStream.getFrameLength() * audioFormat.getFrameSize();
}
// 计算总播放时间(秒)
float frameRate = audioFormat.getFrameRate();
// 秒
float totalSeconds = frameLength / frameRate;
clip.start();
//开始后睡眠播放时间秒
Thread.sleep((long) (totalSeconds * 1000L));
//关闭
clip.close();
}
代码解释:
1.play为我定义的一个方法,该方法的三个参数分别表示:播放的文件流,要延迟多长分钟时间退出play函数,要延迟多长秒钟时间退出play函数。
2.我们在play内通过AudioSystem.getAudioInputStream();来获取一个音频输入流,然后再创建一个clip对象,通过clip的open方法,把该流放入clip,此时调用clip的start方法就可以播放音乐。只不过在这中间,对该流读取的文件格式进行判断,看看是不是clip支持播放的格式。
需要注意的问题:
1.java支持的音频格式:默认情况下,Java只支持如WAV,AIFF,AU等格式的音频,你可以引入第三方jar来获得更多支持格式。注意,默认情况下不支持mp3,所以需要使用wav等格式音频。否则按以上代码会输出:Line not supported for this audio format.
2.clip.start是异步方式,也就是说,主线程还会继续往后执行,所以如果不在clip.start和clip.close中间加入sleep函数的话,音乐不会播放,因为立马就会被关闭,所以要给定一些睡眠时间。
3.关于代码中,AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(filePath));
注意,不能改为AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( filePath);这样会报错不支持mark和reset。原因是我们通过getResourceAsStream得到的流是一个抽象类InputStream,而音频输入流需要用到mark和reset这两个方法,而inputstream不支持这两个方法,而BufferedInputStream支持,所以需要先转为BufferedInputStream在调用getAudioInputStream。
这是官方对BufferedInputStream的解释:BufferedInputStream
向另一个输入流添加功能 - 即缓冲输入并支持mark
和reset
方法的功能。 创建BufferedInputStream
将创建内部缓冲区阵列。 当读取或跳过来自流的字节时,内部缓冲区根据需要从包含的输入流中重新填充,一次多个字节。 mark
操作会记住输入流中的一个点,并且reset
操作会导致在从包含的输入流中获取新字节之前重新读取自最近的mark
操作以来读取的所有字节。