我们的程序往往需要播放一些音效,Java 提供了 AudioInputStream 类来帮助我们读取声音档案,但是该类支持的格式甚少,只支持 WAV、AIFF、AU 等PCM(Pulse-code modulation)格式的文件,如果要播放例如 MP3 等格式的文件的话,可以使用 JavaFX 提供的 MediaPlayer 或 AudioClip 或者其他第三方类库。
可以通过 AudioSystem 的 getAudioInputStream 方法来获取到 AudioInputStream,由于 AudioInputStream 只是一个输入流,并没有播放声音的功能,只是包含了音频的格式和长度,播放声音需要通过 AudioInputStream 对象的 AudioFormat 来创建一个 DataLine.Info 对象,然后根据 AudioFomart 来获取 SourceDataLine,这样扬声器有了 SourceDataLine 就有了数据流,扬声器就可以发声了。
SourceDataLine 就像一个管道一样,数据流从计算机内部的音频文件中流到 AudioSystem 音频系统中,line.open()
打开管道入口,line.start()
打开管道出口,line.drain()
将管道出口端导入另一个地方将管道中剩余的数据流放空,line.close()
关闭管道的出口。
AudioSystem 类包含许多操作 AudioInputStream 对象的方法。例如,这些方法可以让您:
从外部音频文件、流或 URL 获得音频输入流
从音频输入流写入外部文件
将音频输入流转换为不同的音频格式
关于Java sound的更多内容,请查看:
java sound初探 - weidiao - 博客园
Java如何播放聲音? - Magic Len
简单示例:
public class AudioInputStreamTest {
public static void main(String[] args) {
new AudioInputStreamTest().player(new File("D:\\李宗盛 - 山丘.wav"));
}
private void player(File file) {
try {
AudioInputStream audioInputStream = AudioSystem
.getAudioInputStream(file);
System.out.println("此音频的格式为:" + audioInputStream.getFormat()
+ "\n此音频的流长度为:" + audioInputStream.getFrameLength()
+ "帧\n此文件共有 " + file.length() + " 字节");
AudioFormat format = audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open();
line.start();
int length = 0;
byte[] buffer = new byte[512];
while ((length = audioInputStream.read(buffer)) != -1) {
// if (audioInputStream.available() > 8459032) {
// audioInputStream.skip(length);
// continue;
// }
NumberFormat numberFormat = NumberFormat.getInstance();
numberFormat.setMaximumFractionDigits(2);
// System.out
// .println(numberFormat.format(((float) file.length() - (float) audioInputStream
// .available()) / (float) file.length() * 100)
// + "%");
line.write(buffer, 0, length);
}
line.drain();
line.close();
audioInputStream.close();
} catch (UnsupportedAudioFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}