📄 basicplayer.java
字号:
package com.test;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.SourceDataLine;
import java.util.Date;
import java.io.IOException;
import java.io.File;
public class BasicPlayer implements Runnable{
//音频输入流
private AudioInputStream stream = null;
//音频格式
private AudioFormat format = null;
//源数据行
private SourceDataLine sourceDataLine;
//缓冲区大小
private static final int BUFFER_SIZE=1024*50;
private File fileName;
//能否播放
public static boolean isActive=true;
//是否停止
public static boolean isStop=true;
/**
* 构造器
* @param fileName 音频文件
*/
public BasicPlayer(File fileName) {
this.fileName=fileName;
}
/**
* 播放音频文件
*/
public void play(){
try {
//从提供的 File 获得音频输入流
stream=AudioSystem.getAudioInputStream(fileName);
//获得此音频输入流中声音数据的音频格式
format=stream.getFormat();
//音频编码转换
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED, //音频编码技术
format.getSampleRate(), //每秒的样本数
16, //每个样本的位数
format.getChannels(), //声道数
format.getChannels() * 2, //每帧的字节数
format.getSampleRate(), //每秒的帧数
false //指示是否以big-endian字节顺序存储单个样本中的数据(false 意味着 little-endian)
);
//格式化音频输入流
stream = AudioSystem.getAudioInputStream(format, stream);
}
//获得源数据行
sourceDataLine=getDataLine(format);
//允许数据行执行数据 I/O操作
sourceDataLine.start();
int inBytes=0;
byte[] audioData=new byte[BUFFER_SIZE];
BasicPlayer.isStop=false;
Date date=new Date();
System.out.println("开始时间:"+date.getMinutes()+":"+date.getSeconds());
while(inBytes!=-1){
//判断能否播放
if(BasicPlayer.isActive){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println("处于播放状态");
//从音频输入流读取一定数量的字节,并将其存储在缓冲区数组audioData中
inBytes = stream.read(audioData, 0, BUFFER_SIZE);
if (inBytes >= 0) {
//通过此源数据行将音频数据写入混频器
int outBytes = sourceDataLine.write(audioData, 0, inBytes);
}
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println("处于暂停状态");
}
}
date=new Date();
System.out.println("结束时间:"+date.getMinutes()+":"+date.getSeconds());
BasicPlayer.isStop=true;
sourceDataLine.drain();
sourceDataLine.stop();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭源数据行
sourceDataLine.close();
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 获得源数据行
* @param audioFormat
* @return 源数据行
*/
private SourceDataLine getDataLine(AudioFormat audioFormat){
//SourceDataLine是DataLine的子接口,主要作用充当其混频器的源,是可以写入数据的数据行
SourceDataLine res = null;
//DataLine是Line的子接口,Info是DataLine的一个静态的内部类
DataLine.Info info = new DataLine.Info(SourceDataLine.class,audioFormat);
try {
//获得与指定 Line.Info 对象中的描述匹配的行
res = (SourceDataLine) AudioSystem.getLine(info);
//打开具有指定格式的行,这样可使行获得所有所需的系统资源并变得可操作
res.open(audioFormat);
}
catch (Exception e) {
e.printStackTrace();
}
return res; //返回源数据行
}
/**
* 启动该线程
*/
public void run() {
// TODO Auto-generated method stub
if(BasicPlayer.isStop){
this.play();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -