网上找了一些java实现录音,Android比较多,还有一些不能使用,本人对音频知识一概不知,在github上找了一个案例进行修改,使用没有问题。
代码有些乱。
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class TestRecord {
byte bts[] = new byte[10000];
ByteArrayOutputStream baos = null;
boolean stopflag;
TargetDataLine td = null;
ByteArrayInputStream bais = null;
// 定义音频输入流
AudioInputStream ais = null;
// 设置一个播放的标志
Boolean playflag;
// 每次保存的最后的文件名
File tarFile = null;
AudioFormat af = null;
// 定义源数据行,源数据行是可以写入数据的数据行。它充当其混频器的源。应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。
SourceDataLine sd = null;
@Test
public void play() throws LineUnavailableException {
af = getAudioFormat();
info = new (, af);
td = (TargetDataLine) ((info));
(af);
();
Record record = new Record();
Thread t1 = new Thread(record);
();
try {
(5000);
} catch (InterruptedException e) {
();
}
stop();
save();
}
// 停止录音
public void stop() {
stopflag = true;
}
private static AudioFormat getAudioFormat() {
// 下面注释部分是另外一种音频格式,两者都可以
encoding = .PCM_SIGNED;
float rate = 8000f;
int sampleSize = 16;
boolean bigEndian = true;
int channels = 1;
return new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8) * channels, rate, bigEndian);
// //采样率是每秒播放和录制的样本数
// float sampleRate = 16000.0F;
// // 采样率8000,11025,16000,22050,44100
// //sampleSizeInBits表示每个具有此格式的声音样本中的位数
// int sampleSizeInBits = 16;
// // 8,16
// int channels = 1;
// // 单声道为1,立体声为2
// boolean signed = true;
// // true,false
// boolean bigEndian = true;
// // true,false
// return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,bigEndian);
}
// 录音类,因为要用到MyRecord类中的变量,所以将其做成内部类
class Record implements Runnable {
// 定义存放录音的字节数组,作为缓冲区
byte bts[] = new byte[10000];
// 将字节数组包装到流里,最终存入到baos中
// 重写run函数
public void run() {
baos = new ByteArrayOutputStream();
try {
stopflag = false;
while (stopflag != true) {
// 当停止录音没按下时,该线程一直执行
// 从数据行的输入缓冲区读取音频数据。
// 要读取长度的字节,cnt 是实际读取的字节数
int cnt = (bts, 0, );
if (cnt > 0) {
(bts, 0, cnt);
}
// 开始从音频流中读取字节数
byte copyBts[] = bts;
bais = new ByteArrayInputStream(copyBts);
ais = new AudioInputStream(bais, af, / ());
try {
dataLineInfo = new (, af);
sd = (SourceDataLine) (dataLineInfo);
(af);
();
} catch (Exception e) {
();
}
}
} catch (Exception e) {
();
} finally {
try {
// intBytes = -1;
// 关闭打开的字节数组流
if (baos != null) {
();
}
} catch (Exception e) {
();
} finally {
// 下面这句()不能要,这样如果不播放数据就阻塞再次录音会出现其他程序访问错误
// ();
();
// 刷新显示波形的面板
}
}
}
}
// 保存录音
public void save() {
af = getAudioFormat();
byte audioData[] = ();
bais = new ByteArrayInputStream(audioData);
ais = new AudioInputStream(bais, af, / ());
// 定义最终保存的文件名
File file = null;
// 写入文件
try {
// 以当前的时间命名录音的名字
// 将录音的文件存放到D盘下
File filePath = new File("D:/");
String tarPath = "D:/";
if (!()) {// 如果文件不存在,则创建该目录
();
}
long time = ();
file = new File(filePath + "/" + time + ".wav");
(ais, , file);
// 将录音产生的wav文件转换为容量较小的mp3格式
// 定义产生后文件名
// tarFile = new File(tarPath + time + ".mp3");
// Runtime run = null;
// // 测试当前的路径
//
// try {
// run = ();
// // 调用编码器来将wav文件转换为mp3文件
// // 把编码得到的mp3文件先存放到D盘下,然后利用文件拷贝函数将它放到指定的文件夹下同时将D盘下的文件删除
// Process p = run
// .exec("lame -b 16 " + filePath + "/" + () + " " + tarPath + ()); // 16为码率,可自行修改
// // 释放进程
// ().close();
// ().close();
// ().close();
// // 等待
// ();
//
// // 删除之前保存的的wav文件
// if (()) {
// ();
// }
//
//定义最终要存放的文件路径
String destPath = "D:/Program Files/apache-tomcat-6.0.35/webapps/XWZ/tempFile/";
copyFile(tarPath+(), destPath);
// } catch (Exception e) {
// ();
// } finally {
// // 最后都要执行的语句
// // run调用lame解码器最后释放内存
// ();
// }
} catch (Exception e) {
();
} finally {
// 关闭流
try {
if (bais != null) {
();
}
if (ais != null) {
();
}
} catch (Exception e) {
();
}
}
}
}