Java 实现录音功能 第一次能录音,第二次录音就不行,抛异常

micaddress 2016-05-27 11:18:22
public class SaveSound1 extends Frame {

boolean stopCapture = false; // 控制录音标志

AudioFormat audioFormat; // 录音格式

// 读取数据:从TargetDataLine写入ByteArrayOutputStream录音

ByteArrayOutputStream byteArrayOutputStream;

int totaldatasize = 0;

TargetDataLine targetDataLine;

// 播放数据:从AudioInputStream写入SourceDataLine播放

AudioInputStream audioInputStream;

SourceDataLine sourceDataLine;

public static void main(String args[]) throws InterruptedException {

for(int i = 0; i < 3; i++){
System.out.println(i);
SaveSound1 s1 = new SaveSound1();
s1.Running(s1.currentTime());
}
}

public void Running(String startTime){
//直接录音
capture();
try {
Thread.sleep(3000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
stop();
String endTime = currentTime();
mySave(startTime,endTime);
}







public String currentTime(){
String currentTime = " ";
SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy年MM月dd日 HH小时mm分ss秒");
Date date = new Date();
currentTime = dateFormater.format(date);
return currentTime;
}


private void capture() {
try {
// 打开录音
audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
targetDataLine.open(audioFormat);
targetDataLine.start();
Thread captureThread = new Thread(new CaptureThread());
captureThread.start();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void stop() {
stopCapture = true;
}
保存文件
public void mySave(String startTime,String endTime) {
// 取得录音输入流
AudioFormat audioFormat = getAudioFormat();
byte audioData[] = byteArrayOutputStream.toByteArray();
InputStream byteArrayInputStream = new ByteArrayInputStream(audioData);
audioInputStream = new AudioInputStream(byteArrayInputStream,audioFormat, audioData.length / audioFormat.getFrameSize());
// 写入文件
try {
File file = new File("D:/"+startTime+" 至 "+endTime+".wav");
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, file);
} catch (Exception e) {
e.printStackTrace();
}
}

private AudioFormat getAudioFormat() {
float sampleRate = 16000.0F;
// 8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
// 8,16
int channels = 1;
// 1,2
boolean signed = true;
// true,false
boolean bigEndian = false;
// true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,bigEndian);
}
class CaptureThread extends Thread {
// 临时数组
byte tempBuffer[] = new byte[10000];
public void run() {
byteArrayOutputStream = new ByteArrayOutputStream();
totaldatasize = 0;
stopCapture = false;
try {// 循环执行,直到按下停止录音按钮
while (!stopCapture) {
// 读取10000个数据
int cnt = targetDataLine.read(tempBuffer, 0,
tempBuffer.length);
if (cnt > 0) {
// 保存该数据
byteArrayOutputStream.write(tempBuffer, 0, cnt);
totaldatasize += cnt;
}
}
byteArrayOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}

class PlayThread extends Thread {
byte tempBuffer[] = new byte[10000];
public void run() {
try {
int cnt;
// 读取数据到缓存数据
while ((cnt = audioInputStream.read(tempBuffer, 0,
tempBuffer.length)) != -1) {
if (cnt > 0) {
// 写入缓存数据
sourceDataLine.write(tempBuffer, 0, cnt);
}
}
// Block等待临时数据被输出为空
sourceDataLine.drain();
sourceDataLine.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}


-------------------------------------------------以下是抛出的异常--------------------------------------------------
1
2
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported.
at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(Unknown Source)
at com.sun.media.sound.AbstractDataLine.open(Unknown Source)
at com.sun.media.sound.AbstractDataLine.open(Unknown Source)
at restart.SaveSound1.capture(SaveSound1.java:161)
at restart.SaveSound1.Running(SaveSound1.java:69)
at restart.SaveSound1$1.run(SaveSound1.java:49)

----------------------------------------------------------------------------------------------------------------------------

提示我targetDataLine.open(audioFormat);出错

求解 为什么 第二次执行就抛异常了



...全文
727 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
一只蚊子啊 2019-07-29
  • 打赏
  • 举报
回复
引用 9 楼 qq_39936465 的回复:
我测试一下,我开始的直觉没错,在capture方法中加入一句关闭语句
targetDataLine.close();就可以了。
的确,我后面也是这样解决的,必须关闭了才能多次执行
qq_39936465 2019-07-24
  • 打赏
  • 举报
回复
我测试一下,我开始的直觉没错,在capture方法中加入一句关闭语句
targetDataLine.close();就可以了。
qq_39936465 2019-07-24
  • 打赏
  • 举报
回复
我说的不对
Some lines, once closed, cannot be reopened. Attempts to reopen such a line will always result in a LineUnavailableException.

这是源码的解释。也就是说有些只能打开一次,无法重复打开。
qq_39936465 2019-07-24
  • 打赏
  • 举报
回复
LineUnavailableException - 如果由于资源限制而无法打开该行

targetDataLine.open(audioFormat);因为这里打开后没有关闭,无法再次打开。
一只蚊子啊 2019-07-24
  • 打赏
  • 举报
回复
引用 4 楼 闲人々人闲 的回复:
楼主解决了吗,我也不会,求指教
解决了吗,兄弟
一只蚊子啊 2019-07-24
  • 打赏
  • 举报
回复
引用 4 楼 闲人々人闲 的回复:
楼主解决了吗,我也不会,求指教
解决了吗,兄弟
闲人々人闲 2019-07-12
  • 打赏
  • 举报
回复
楼主解决了吗,我也不会,求指教

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧