com.alibaba
fastjson
1.2.83
com.squareup.okhttp3
okhttp
4.9.3
ws.schild
jave-all-deps
3.5.0
com.baidu.aip
java-sdk
4.16.19
/**
* 录音,存储为WAV文件
* @author admin_70 + haoranhaoshi
*/
@Component
public class VoiceRecorder {
AudioFormat audioFormat;
TargetDataLine targetDataLine;
private volatile boolean isRecording = false; // 录音状态标志
private CaptureThread captureThread;
//记录录音时长
long testtime;
//注入文件路径
@Value("${upload.voice}")
private static String filePath;
//语音路径
private static String fileName = filePath + genImageName();
//开始录音
public synchronized void StartVoice() {
if (isRecording) {
System.out.println("已经在录音中...");
return;
}
isRecording = true;
testtime = System.currentTimeMillis();
captureAudio(); // 调用录音方法
System.out.println("开始录音:");
}
//结束录音
public synchronized String EndVoice() {
if (!isRecording || targetDataLine == null) {
System.out.println("当前没有正在进行的录音");
return "";
}
closeCaptureAudio();
try {
if (captureThread != null) {
captureThread.join(); // 等待录音线程完成
}
} catch (InterruptedException e) {
e.printStackTrace();
}
isRecording = false;
System.out.println("录音结束;");
System.out.println("录音了"+(System.currentTimeMillis()-testtime)/1000+"秒!");
return VoiceRecognition.start(fileName);
}
public void closeCaptureAudio(){
targetDataLine.stop();
targetDataLine.close();
}
public void captureAudio(){
try {
// 构造具有线性 PCM 编码和给定参数的 AudioFormat。
audioFormat = getAudioFormat();
// 根据指定信息构造数据行的信息对象,这些信息包括单个音频格式。此构造方法通常由应用程序用于描述所需的行。
// lineClass - 该信息对象所描述的数据行的类
// format - 所需的格式
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
// 如果请求 DataLine,且 info 是 DataLine.Info 的实例(至少指定一种完全限定的音频格式),
// 上一个数据行将用作返回的 DataLine 的默认格式。
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
// 开启线程
new CaptureThread().start();
} catch (Exception e){
e.printStackTrace();
System.exit(0);
}
}
private AudioFormat getAudioFormat() {
// 8000,11025,16000,22050,44100 采样率
float sampleRate = 8000F;
// 8,16 每个样本中的位数
int sampleSizeInBits = 16;
// 1,2 信道数(单声道为 1,立体声为 2,等等)
int channels = 2;
// true,false
boolean signed = true;
// true,false 指示是以 big-endian 顺序还是以 little-endian 顺序存储音频数据。
boolean bigEndian = false;
// 构造具有线性 PCM 编码和给定参数的 AudioFormat。
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
bigEndian);
}
/** 录音名生成 **/
public static String genImageName() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//加上三位随机数
Random random = new Random();
int end3 = random.nextInt(999);
//如果不足三位前面补0
String str = millis + String.format("%03d", end3);
return str+".wav";
}
class CaptureThread extends Thread {
public void run() {
// 指定的文件类型
AudioFileFormat.Type fileType = null;
// 设置文件类型和文件扩展名
File audioFile = null;
fileType = AudioFileFormat.Type.WAVE;
audioFile = new File(fileName);
try {
// format - 所需音频格式
targetDataLine.open(audioFormat);
// 当开始音频捕获或回放时,生成 START 事件。
targetDataLine.start();
// new AudioInputStream(TargetDataLine line):构造从指示的目标数据行读取数据的音频输入流。该流的格式与目标数据行的格式相同,line - 此流从中获得数据的目标数据行。
// stream - 包含要写入文件的音频数据的音频输入流
// fileType - 要写入的音频文件的种类
// out - 应将文件数据写入其中的外部文件
AudioSystem.write(new AudioInputStream(targetDataLine),fileType, audioFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
百度AI开发平台的控制台中创建一个语音应用
/**
* 识别WAV文件,上传百度服务器,返回结果
* @author haoranhaoshi
*/
public class VoiceRecognition {
// 设置APPID/AK/SK
// 百度AI开发平台的控制台中创建一个语音应用即可获得
public static final String APP_ID = "116784952";
public static final String API_KEY = "8xQ30oLJrs4esJ0aXRZdyQus";
public static final String SECRET_KEY = "m9bLi9RG7TLUs8JtE0zGEPSKRf2hKG5n";
private static final AipSpeech aipSpeech = getAipSpeech();
private static String resultText;
private static String filePath;
public static String getResultText() {
return resultText;
}
public static void main(String[] args) throws JSONException {
VoiceRecognition voiceRecognition = new VoiceRecognition();
if(voiceRecognition.recognizeVoice()){
System.out.println("结果为:" + voiceRecognition.getResultText());
}else{
System.out.println("识别错误");
}
}
public static String start(String path) throws JSONException {
filePath = path;
VoiceRecognition voiceRecognition = new VoiceRecognition();
if(voiceRecognition.recognizeVoice()){
System.out.println("结果为:" + voiceRecognition.getResultText());
}else{
System.out.println("识别错误");
}
return voiceRecognition.getResultText();
}
public static AipSpeech getAipSpeech(){
// 初始化一个AipSpeech
AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
//client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
//client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
// 可选:设置log4j日志输出格式,若不设置,则使用默认配置
// 也可以直接通过jvm启动参数设置此环境变量
// System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
return client;
}
public boolean recognizeVoice() throws JSONException {
String wavFileName = "record";
// 对本地语音文件进行识别
JSONObject asrRes = aipSpeech.asr(filePath, "wav", 16000, null);
System.out.println(asrRes);
if(asrRes.getString("err_msg").equals("success.")){
resultText = asrRes.getJSONArray("result").getString(0);
return true;
}else{
return false;
}
}
}
注:如需更多详情配置请移步到百度api官网进行查阅。