本代码将调用javax.sound库,讲解如何播放音频
得到能够使用的简易音频的播放器
本文可作为javax.sound学习指南,javax.sound学习实战等进行参考
相关内容请看下方代码与注释
注:代码中 SoundFileFormat、SoundInputStream、SoundSourceDataLine、MixerInformation 几个类都是前面几篇文章中讲解的内容,将其中代码依次创立为对应的类,并调用即可
SoundFileFormat中代码对应文章:JAVA音频研究1
SoundInputStream中代码对应文章:JAVA音频研究2
SoundSourceDataLine中代码对应文章:JAVA音频研究3
MixerInformation中代码对应文章:JAVA音频研究4
如:
后续使用请看下片文章:JAVA音频研究6
import java.io.File;
//import java.time.Instant;
public class SoundPlayer {
private static String soundFilePath = null;//保存为字符串类型的绝对地址,例:"C:\\Users\\17512\\Desktop\\bgm.wav";
private static File soundFile = null;//保存音频文件
//========================================================
private volatile boolean running = false; //记录音频是否播放
private static boolean isLoop = false; //记录是否循环播放
private static Thread mainThread = null; //播放音频的任务主线程(音频数据读取输出)
private static Thread secondThread = null; //播放音频的任务次线程(控制主线程暂停、继续)
private static byte tempBuffer[] = null;//缓冲区
private static int count;//保存得到的采样数
//private static Instant startTime = null; 待后续开发
//private static Instant endTime = null;待后续开发
//清空所有内容,释放内存
protected static void clearAll(){
soundFile = null;
mainThread = null;
secondThread = null;
tempBuffer = null;
//startTime = null;待后续开发
//endTime = null;待后续开发
}
//设置音频文件绝对路径
public void setSoundFilePath(String absolutePath){
soundFilePath = absolutePath;
}
private void playMusic(){
try{
synchronized(this){
running = true;
}
//通过数据行读取音频数据流,发送到混音器;
//数据流传输过程:AudioInputStream -> SourceDataLine;
if(soundFilePath == null){
System.out.println("未设置声音文件绝对路径");
return;
}
soundFile = new File(soundFilePath);
//MixerInformation.getMixerInformation();
//MixerInformation.showMixerInformation();
SoundFileFormat.getSoundFileFormat(soundFile);
//SoundFileFormat.showSoundFileFormat();
SoundInputStream.getSoundInputStream(soundFile);
//SoundInputStream.showSoundInputStream();
SoundSourceDataLine.loadSourceDataLine();
System.out.println("播放开始");
tempBuffer = new byte[1024];
//音频输入流读取指定最大大小(tempBuff.length)数据并传输到源数据线,off为传输数据在字节数组(tempBuffer)开始保存数据的位置,最终读取大小保存进count
while((count = SoundInputStream.soundInputStream.read(tempBuffer,0,tempBuffer.length)) != -1){
//System.out.println("音频输入流读取了" + count + "个字节");
synchronized(this){
while(!running)
wait();
}
//源数据线进行一次数据输出,将从字节数组中位置off开始将读取到的数据输出到缓冲区(输出大小为count)(混音器从混音器读取数据播放)
SoundSourceDataLine.sourceDataLine.write(tempBuffer,0,count);
}
stopMusic();
}catch(Exception ex){
ex.printStackTrace();
}
}
private void playMusic(boolean isLoop)throws Exception {
try{
if(isLoop){
while(isLoop){
playMusic();
}
}else{
playMusic();
}
}catch(Exception ex){
ex.printStackTrace();
}
}
//暂停播放音频
private void pauseMusic(){ synchronized(this){ running = false; notifyAll(); } }
//继续播放音乐
private void continueMusic(){ synchronized(this){ running = true; notifyAll(); } }
//停止播放音频
private void stopMusic() throws Exception {
synchronized(this){
running = false;
isLoop = false;
System.out.println("播放结束");
//清空数据行并关闭
SoundSourceDataLine.sourceDataLine.drain();
SoundSourceDataLine.sourceDataLine.close();
SoundInputStream.soundInputStream.close();
SoundFileFormat.clearAll();
SoundSourceDataLine.clearAll();
SoundInputStream.clearAll();
clearAll();
}
}
//外部调用控制方法:生成音频主线程;
public void start(boolean loop)throws Exception{
if(SoundInputStream.soundInputStream != null || SoundSourceDataLine.sourceDataLine != null){
System.out.println("切换歌曲");
stopMusic();
}
isLoop = loop;
mainThread = new Thread(new Runnable(){
public void run(){ try { playMusic(isLoop); } catch (Exception e) { e.printStackTrace(); } }
});
mainThread.start();
}
//外部调用控制方法:暂停音频线程
public void pause(){
secondThread = new Thread(new Runnable(){
public void run(){
System.out.println("调用暂停");
pauseMusic();
}
});
secondThread.start();
}
//外部调用控制方法:继续音频线程
public void continues(){
secondThread = new Thread(new Runnable(){
public void run(){
System.out.println("调用继续");
continueMusic();
} });
secondThread.start();
}
//外部调用控制方法:结束音频线程
public void stop(){
secondThread = new Thread(new Runnable(){
public void run(){
System.out.println("调用停止");
try {stopMusic();}
catch (Exception e) {e.printStackTrace();}
} });
secondThread.start();
}
}