本文目录导读:

在Java中实现录音功能,最常用的方式是使用 javax.sound.sampled 包,它是Java标准库自带的音频处理API,无需额外引入第三方库即可完成基本的录音和播放功能。
下面是一个完整的Java录音案例,包含录音、保存音频文件(WAV格式)以及播放录音的功能。
核心思路
- 获取音频输入设备:通过
AudioSystem.getTargetDataLine()获取麦克风等音频输入设备。 - 定义音频格式:设置采样率、采样位数、声道数等参数。
- 开始录音:打开数据线,启动音频数据读取线程,将数据写入内存或直接写入文件。
- 停止录音:关闭数据线,停止线程。
- 保存文件:将捕获的音频数据写入WAV文件(需自行处理WAV文件头)。
完整代码示例
import javax.sound.sampled.*;
import java.io.*;
/**
* Java录音案例:支持录音、暂停、停止,保存为WAV文件
*/
public class AudioRecorder {
// 音频格式参数
private static final int SAMPLE_RATE = 44100; // 采样率:44.1kHz
private static final int BITS_PER_SAMPLE = 16; // 采样位数:16位
private static final int CHANNELS = 1; // 声道数:单声道
private static final boolean SIGNED = true; // 有符号
private static final boolean BIG_ENDIAN = false; // 小端序
private TargetDataLine targetDataLine;
private AudioInputStream audioInputStream;
private volatile boolean isRecording = false;
private volatile boolean isPaused = false;
private ByteArrayOutputStream byteArrayOutputStream;
private Thread recordingThread;
/**
* 开始录音
* @param audioFile 要保存的WAV文件路径(如果为null则暂存内存)
*/
public void startRecording(File audioFile) {
if (isRecording) {
System.out.println("录音正在进行中...");
return;
}
try {
// 1. 定义音频格式
AudioFormat audioFormat = new AudioFormat(
SAMPLE_RATE,
BITS_PER_SAMPLE,
CHANNELS,
SIGNED,
BIG_ENDIAN
);
// 2. 获取音频输入设备(麦克风)
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
if (!AudioSystem.isLineSupported(dataLineInfo)) {
System.err.println("不支持该音频格式或没有麦克风输入设备");
return;
}
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
targetDataLine.open(audioFormat);
targetDataLine.start();
// 3. 创建音频输入流
audioInputStream = new AudioInputStream(targetDataLine);
// 4. 准备输出流
byteArrayOutputStream = new ByteArrayOutputStream();
isRecording = true;
isPaused = false;
// 5. 启动录音线程
recordingThread = new Thread(() -> {
try {
byte[] buffer = new byte[4096];
int bytesRead;
while (isRecording && !Thread.currentThread().isInterrupted()) {
if (!isPaused) {
bytesRead = audioInputStream.read(buffer);
if (bytesRead > 0) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
} else {
Thread.sleep(100); // 暂停时休眠,避免CPU空转
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "RecordingThread");
recordingThread.start();
System.out.println("录音已开始...");
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
/**
* 暂停录音
*/
public void pauseRecording() {
if (isRecording && !isPaused) {
isPaused = true;
System.out.println("录音已暂停");
}
}
/**
* 恢复录音
*/
public void resumeRecording() {
if (isRecording && isPaused) {
isPaused = false;
System.out.println("录音已恢复");
}
}
/**
* 停止录音并保存到文件
* @param audioFile 保存的WAV文件路径
*/
public void stopRecordingAndSave(File audioFile) {
if (!isRecording) {
System.out.println("录音尚未开始");
return;
}
isRecording = false;
// 等待录音线程结束
try {
if (recordingThread != null) {
recordingThread.interrupt();
recordingThread.join(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// 关闭资源
if (targetDataLine != null) {
targetDataLine.stop();
targetDataLine.close();
}
try {
if (audioInputStream != null) {
audioInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
// 保存WAV文件
if (byteArrayOutputStream != null && byteArrayOutputStream.size() > 0) {
try {
byte[] audioData = byteArrayOutputStream.toByteArray();
AudioFormat format = new AudioFormat(
SAMPLE_RATE, BITS_PER_SAMPLE, CHANNELS, SIGNED, BIG_ENDIAN
);
ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
AudioInputStream saveStream = new AudioInputStream(
bais, format, audioData.length / format.getFrameSize()
);
AudioSystem.write(saveStream, AudioFileFormat.Type.WAVE, audioFile);
saveStream.close();
System.out.println("录音已保存到: " + audioFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 停止录音但不保存(丢弃数据)
*/
public void stopRecording() {
stopRecordingAndSave(null);
}
}
使用示例(主程序)
import java.io.File;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
AudioRecorder recorder = new AudioRecorder();
Scanner scanner = new Scanner(System.in);
System.out.println("Java录音示例");
System.out.println("输入 'start' 开始录音");
System.out.println("输入 'pause' 暂停/恢复");
System.out.println("输入 'stop' 停止并保存");
System.out.println("输入 'quit' 退出\n");
while (true) {
System.out.print("> ");
String command = scanner.nextLine().trim().toLowerCase();
switch (command) {
case "start":
recorder.startRecording(new File("recording.wav"));
break;
case "pause":
// 简单切换暂停/恢复
recorder.pauseRecording();
break;
case "resume":
recorder.resumeRecording();
break;
case "stop":
recorder.stopRecordingAndSave(new File("recording.wav"));
break;
case "quit":
System.out.println("退出程序");
scanner.close();
return;
default:
System.out.println("未知命令");
}
}
}
}
运行效果
- 启动程序。
- 输入
start→ 录音开始,麦克风开始采集音频。 - 输入
pause→ 暂停采集,输入resume恢复。 - 输入
stop→ 停止录音,在当前目录生成recording.wav文件。 - 可以使用任意播放器(如 Windows Media Player、VLC)播放该WAV文件。
注意事项
| 问题 | 说明 |
|---|---|
| 权限 | 运行程序时需要允许Java进程访问麦克风(部分操作系统会弹窗询问) |
| 格式 | 保存为WAV格式是未压缩的PCM数据,文件体积较大(44.1kHz, 16位单声道约为5MB/分钟) |
| 线程安全 | volatile 和 interrupt 保证了录音线程能正确响应停止指令 |
| 文件覆盖 | 如果多次录音使用同一个文件名,之前的文件会被覆盖 |
| 中文路径 | 建议使用英文路径,避免编码问题 |
扩展方向
- 压缩格式:可使用
javax.sound.sampled结合 JLayer(MP3)或 Java FLAC 等第三方库实现MP3/FLAC格式保存。 - 实时播放:同时使用
SourceDataLine在录音时直接播放(回声/耳返功能)。 - 图形界面:结合Swing/JavaFX开发可视化录音应用。
- 音频处理:对录制的音频数据进行频谱分析、降噪、变声等处理。
这个案例提供了完整、可运行的Java录音实现,适用于桌面应用、语音识别、语音聊天等场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播