本文目录导读:

我来为您提供一个完整的Java语音识别案例,使用Google的Speech-to-Text API和Java Speech API。
使用Google Cloud Speech-to-Text API
Maven依赖配置
<dependencies>
<!-- Google Cloud Speech -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-speech</artifactId>
<version>4.3.0</version>
</dependency>
<!-- 录音库 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
</dependencies>
语音识别主类
package com.example.speech;
import com.google.cloud.speech.v1.*;
import com.google.protobuf.ByteString;
import javax.sound.sampled.*;
import java.io.*;
import java.util.List;
public class SpeechRecognitionExample {
private static final String GOOGLE_CREDENTIALS_PATH = "path/to/your/service-account-key.json";
public static void main(String[] args) {
try {
// 设置Google Cloud认证
System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", GOOGLE_CREDENTIALS_PATH);
// 1. 录音
System.out.println("开始录音,请说话...");
byte[] audioData = recordAudio(5); // 录音5秒
// 2. 语音识别
String recognizedText = recognizeSpeech(audioData);
System.out.println("识别结果: " + recognizedText);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 录音方法
*/
public static byte[] recordAudio(int durationSeconds) throws LineUnavailableException {
// 音频格式设置
AudioFormat format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
16000, // 采样率
16, // 位深度
1, // 单声道
2, // 帧大小
16000, // 帧率
false // big-endian
);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
System.out.println("录音中...");
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int numBytesRead;
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < durationSeconds * 1000) {
numBytesRead = line.read(buffer, 0, buffer.length);
out.write(buffer, 0, numBytesRead);
}
line.stop();
line.close();
System.out.println("录音结束");
return out.toByteArray();
}
/**
* 语音识别方法
*/
public static String recognizeSpeech(byte[] audioData) throws Exception {
// 创建Speech客户端
try (SpeechClient speechClient = SpeechClient.create()) {
// 构建识别配置
RecognitionConfig config = RecognitionConfig.newBuilder()
.setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
.setSampleRateHertz(16000)
.setLanguageCode("zh-CN") // 中文普通话
.setModel("default")
.build();
// 构建音频数据
RecognitionAudio audio = RecognitionAudio.newBuilder()
.setContent(ByteString.copyFrom(audioData))
.build();
// 执行语音识别
RecognizeResponse response = speechClient.recognize(config, audio);
// 解析结果
List<SpeechRecognitionResult> results = response.getResultsList();
StringBuilder resultText = new StringBuilder();
for (SpeechRecognitionResult result : results) {
SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0);
resultText.append(alternative.getTranscript());
}
return resultText.toString();
}
}
}
使用Java Speech API (JSAPI)
Maven依赖
<dependencies>
<!-- JSAPI 2.0 -->
<dependency>
<groupId>javax.speech</groupId>
<artifactId>jsapi</artifactId>
<version>1.0</version>
</dependency>
<!-- Sphinx-4 离线语音识别 -->
<dependency>
<groupId>edu.cmu.sphinx</groupId>
<artifactId>sphinx4-core</artifactId>
<version>5prealpha-SNAPSHOT</version>
</dependency>
<!-- 中文语音模型 -->
<dependency>
<groupId>edu.cmu.sphinx</groupId>
<artifactId>sphinx4-data</artifactId>
<version>5prealpha-SNAPSHOT</version>
</dependency>
</dependencies>
离线语音识别实现
package com.example.speech;
import edu.cmu.sphinx.api.Configuration;
import edu.cmu.sphinx.api.LiveSpeechRecognizer;
import edu.cmu.sphinx.api.SpeechResult;
import edu.cmu.sphinx.api.StreamSpeechRecognizer;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class OfflineSpeechRecognition {
public static void main(String[] args) {
try {
// 实时语音识别
liveSpeechRecognition();
// 或从文件识别
// fileSpeechRecognition("path/to/audio.wav");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 实时语音识别(麦克风输入)
*/
public static void liveSpeechRecognition() throws Exception {
// 配置语音识别器
Configuration configuration = new Configuration();
// 设置模型路径(需要下载中文模型)
configuration.setAcousticModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us");
configuration.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict");
configuration.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin");
// 对于中文,需要使用中文模型
// configuration.setAcousticModelPath("resource:/models/zh-cn/mandarin");
// configuration.setDictionaryPath("resource:/models/zh-cn/mandarin.dict");
// configuration.setLanguageModelPath("resource:/models/zh-cn/mandarin.lm.bin");
LiveSpeechRecognizer recognizer = new LiveSpeechRecognizer(configuration);
System.out.println("语音识别已启动,请说话...");
recognizer.startRecognition(true);
SpeechResult result;
while ((result = recognizer.getResult()) != null) {
System.out.println("识别结果: " + result.getHypothesis());
}
recognizer.stopRecognition();
}
/**
* 从音频文件识别
*/
public static void fileSpeechRecognition(String audioFilePath) throws Exception {
Configuration configuration = new Configuration();
configuration.setAcousticModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us");
configuration.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict");
configuration.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin");
StreamSpeechRecognizer recognizer = new StreamSpeechRecognizer(configuration);
InputStream stream = new FileInputStream(new File(audioFilePath));
recognizer.startRecognition(stream);
SpeechResult result;
while ((result = recognizer.getResult()) != null) {
System.out.println("识别结果: " + result.getHypothesis());
}
recognizer.stopRecognition();
}
}
录音并保存为WAV文件
package com.example.speech;
import javax.sound.sampled.*;
import java.io.*;
public class AudioRecorder {
private static final int SAMPLE_RATE = 16000;
private static final int BITS_PER_SAMPLE = 16;
private static final int CHANNELS = 1;
public static void main(String[] args) {
try {
// 录制音频并保存
recordAndSave("recorded_audio.wav", 5);
System.out.println("音频已保存到 recorded_audio.wav");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 录音并保存为WAV文件
*/
public static void recordAndSave(String filePath, int durationSeconds)
throws LineUnavailableException, IOException {
AudioFormat format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
SAMPLE_RATE,
BITS_PER_SAMPLE,
CHANNELS,
CHANNELS * BITS_PER_SAMPLE / 8,
SAMPLE_RATE,
false
);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
System.out.println("录音开始...");
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < durationSeconds * 1000) {
bytesRead = line.read(buffer, 0, buffer.length);
out.write(buffer, 0, bytesRead);
}
line.stop();
line.close();
// 保存为WAV文件
byte[] audioData = out.toByteArray();
writeWavFile(audioData, filePath, format);
}
/**
* 写入WAV文件
*/
private static void writeWavFile(byte[] audioData, String filePath, AudioFormat format)
throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
AudioInputStream audioInputStream = new AudioInputStream(
bais, format, audioData.length / format.getFrameSize()
);
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File(filePath));
audioInputStream.close();
}
}
使用说明
方案一(Google API):
- 在Google Cloud Console创建项目并启用Speech-to-Text API
- 下载服务账号密钥JSON文件
- 修改代码中的
GOOGLE_CREDENTIALS_PATH路径
方案二(离线):
- 需要下载中文语音模型文件
- 配置正确的模型路径
- 支持实时和文件两种模式
注意事项:
- 在线API需要网络连接和API密钥
- 离线识别准确率可能不如在线API
- 音频格式建议使用16kHz采样率、16位深度、单声道
运行配置
# 编译 javac -cp "lib/*" com/example/speech/*.java # 运行 java -cp ".:lib/*" com.example.speech.SpeechRecognitionExample
这个案例提供了三种不同的语音识别实现方案,您可以根据实际需求选择适合的方案。