JavaSound是一个小巧的低层应用程序接口(API),它支持数字音频和乐器数字接口(MIDI)数据的记录和回放。在JDK 1.3.0之前,JavaSound是一个标准的Java扩展API,但从Java 2的1.3.0版开始,JavaSound就被包含到JDK之中。由于Java有着跨平台(操作系统、硬件平台)的特点,基于JavaSound的音频处理程序能够在任何实现了Java 1.3以上版本的系统上运行,无需加装任何支持软件。
使用JavaSound API,可以实现各种基于声音的应用,例如声音录制、音乐播放、网络电话、音乐编辑等。JavaSound API又以各种解码和合成器SPI(服务提供者接口,Service Provider Interface)为基础,实现各种音乐格式的解码与转码。
在处理输入音频时,对于来自各种音频输入端口的信号,例如麦克风、CD播放器、磁带播放器等,可以在它们到达TargetDataLine之前,利用混频器控制输入混频,最后在程序中通过TargetDataLine获得数字化的音频输入流。
类似地,在处理输出音频时,混频器用来对一系列来自SourceDataLine的数据进行混频处理,经处理后的信号可输出到各种输出端口,例如扬声器、耳机等。SourceDataLine是一个可写入音频信号数字流的设备,例如,我们可以从一个WAV文件读取内容写入到SourceDataLine,然后再通过扬声器输出。我们可以认为SourceDataLine是一个虚拟的播放器,只要电脑中连接的扬声器、耳机可用,音频信号就会经SourceDataLine进行播放。
但是,JavaSound只支持wav等格式的音频,它缺少对MP3格式音频文件的支持,想要使用Java代码播放MP3需要第三方库。JLayer-MP3 library是一款Java语言编写的开源MP3解码器库(jl1.0.jar),又称为javazoom.jl包。为了支持mp3的播放,我们必须添加mp3的SPI支持库(已包含JLayer-MP3 library)到当前项目中。mp3的SPI支持库共有三个Jar文件jl1.0.jar、mp3spi1.9.4.jar、tritonus_share.jar。
为了让Java程序能同时播放MP3格式和WAV等格式的音频,需要如图在当前项目的构建文件中添加mp3的SPI支持库:
下面是一个简单的播放例程,可兼容播放MP3和WAV音频,MP3 音频实际上是被转码为WAV格式了。
import java.io.File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class AudioPlayTest {
private AudioInputStream audioStream;
private AudioFormat audioFormat;
private SourceDataLine sourceDataLine;
public AudioPlayTest(String path) {
playMusic(path);
}
private void playMusic(String path){
try{
int count;
byte buf[] = new byte[2048];
//获取音频输入流
audioStream = AudioSystem.getAudioInputStream(new File(path));
//获取音频格式
audioFormat = audioStream.getFormat();
System.out.println("音频文件: "+path);
System.out.println("音频Encoding: "+audioFormat.getEncoding());
//如果不是wav格式,转换mp3文件编码。MPEG1L3(mp3格式)转为PCM_SIGNED(wav格式)
if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(), 16, audioFormat
.getChannels(), audioFormat.getChannels() * 2,
audioFormat.getSampleRate(), false);
audioStream = AudioSystem.getAudioInputStream(audioFormat,
audioStream);
} //转换mp3文件编码结束
//封装音频信息
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
audioFormat,AudioSystem.NOT_SPECIFIED);
//获取虚拟扬声器(SourceDataLine)实例
sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
//播放音频
while((count = audioStream.read(buf,0,buf.length)) != -1){
sourceDataLine.write(buf,0,count);
}
//播放结束,释放资源
sourceDataLine.drain();
sourceDataLine.close();
audioStream.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
public static void main(String[] args) {
String path = "D:\\test\\三步舞曲.mp3";
new AudioPlayTest(path);
path = "D:\\test\\我是一片云.wav";
new AudioPlayTest(path);
}
}
实际上这个程序只是在"使用Java播放wav音乐"博客的第二种方案程序的基础上增加了一点对MP3格式音频的转码处理。请参见:
使用Java播放wav音乐_Java编程乐园的博客-CSDN博客
说明:
在JDK 8至JDK 10的版本中已包含了JavaFX(富客户端GUI应用程序框架),Java已可支持直接播放mp3格式的音频,而且处理也更简洁。
请参阅我的另一篇博客:
【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【音视频播放】