package com.iflytek.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.iflytek.cloud.speech.RecognizerListener;
import com.iflytek.cloud.speech.RecognizerResult;
import com.iflytek.cloud.speech.Setting;
import com.iflytek.cloud.speech.SpeechConstant;
import com.iflytek.cloud.speech.SpeechError;
import com.iflytek.cloud.speech.SpeechRecognizer;
import com.iflytek.cloud.speech.SpeechUtility;
/**
* 音频文件识别
*
* @author zxh
*
*/
public class MscRecognition {
private static final Log logger = LogFactory.getLog(MscRecognition.class);
// 账号ID
private static final String APPID = "5a290e4a";
private StringBuffer mResult = new StringBuffer();
/** 最大等待时间, 单位ms */
private int maxWaitTime = 600;
/** 每次等待时间 */
private int perWaitTime = 100;
/** 音频文件 */
private String fileName = "";
static {
Setting.setShowLog(false);
SpeechUtility.createUtility("appid=" + APPID);
}
public String voiceTowords(String fileName) {
return initVoiceTowords(fileName, true);
}
/**
*
* @param fileName
* @param init
* 初始化最大等待时间
* @return
*/
public String initVoiceTowords(String fileName, boolean init) {
if (init) {
maxWaitTime = 6000;
}
this.fileName = fileName;
return recognize();
}
// *************************************音频流听写*************************************
/**
* 听写
*
* @return
*/
private String recognize() {
if (SpeechRecognizer.getRecognizer() == null)
SpeechRecognizer.createRecognizer();
return RecognizePcmfileByte();
}
/**
* 自动化测试注意要点 如果直接从音频文件识别,需要模拟真实的音速,防止音频队列的堵塞
*
*/
private String RecognizePcmfileByte() {
// 1、读取音频文件
FileInputStream fis = null;
byte[] voiceBuffer = null;
try {
fis = new FileInputStream(new File(fileName));
voiceBuffer = new byte[fis.available()];
fis.read(voiceBuffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fis) {
fis.close();
fis = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 2、音频流听写
if (0 == voiceBuffer.length) {
mResult.append("no audio avaible!");
} else {
// 解析之前将存出结果置为空
mResult.setLength(0);
SpeechRecognizer recognizer = SpeechRecognizer.getRecognizer();
// 设置参数,详见《MSC Reference Manual》SpeechConstant类
// 应用领域用于听写和语音语义服务
recognizer.setParameter(SpeechConstant.DOMAIN, "iat");
// 语言区域
recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 方言 每一种语言区域
recognizer.setParameter(SpeechConstant.ACCENT, "mandarin");
// 音频源
recognizer.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
// 音频采样率
recognizer.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
// 返回格式
recognizer.setParameter(SpeechConstant.RESULT_TYPE, "plain");
// 开始听写
recognizer.startListening(recListener);
// voiceBuffer为音频数据流,splitBuffer为自定义分割接口,将其以4.8k字节分割成数组
ArrayList<byte[]> buffers = splitBuffer(voiceBuffer, voiceBuffer.length, 4800);
for (int i = 0; i < buffers.size(); i++) {
// 每次写入msc数据4.8K,相当150ms录音数据
recognizer.writeAudio(buffers.get(i), 0, buffers.get(i).length);
}
recognizer.stopListening();
// 在原有的代码基础上主要添加了这个while代码等待音频解析完成,recognizer.isListening()返回true,说明解析工作还在进行
while (recognizer.isListening()) {
try {
Thread.sleep(perWaitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
maxWaitTime -= perWaitTime;
}
}
return mResult.toString();
}
/**
* 将字节缓冲区按照固定大小进行分割成数组
*
* @param buffer
* 缓冲区
* @param length
* 缓冲区大小
* @param spsize
* 切割块大小
* @return
*/
private ArrayList<byte[]> splitBuffer(byte[] buffer, int length, int spsize) {
ArrayList<byte[]> array = new ArrayList<byte[]>();
if (spsize <= 0 || length <= 0 || buffer == null || buffer.length < length)
return array;
int size = 0;
// 截断识别5秒得数据
/*int fiveMsec = 93946;
if (length >= fiveMsec) {
length = fiveMsec;
}
*/
while (size < length) {
int left = length - size;
if (spsize < left) {
byte[] sdata = new byte[spsize];
System.arraycopy(buffer, size, sdata, 0, spsize);
array.add(sdata);
size += spsize;
} else {
byte[] sdata = new byte[left];
System.arraycopy(buffer, size, sdata, 0, left);
array.add(sdata);
size += left;
}
}
return array;
}
/**
* 听写监听器
*/
private RecognizerListener recListener = new RecognizerListener() {
// 开始录音
public void onBeginOfSpeech() {
}
// 结束录音
public void onEndOfSpeech() {
}
// 音量值0~30
public void onVolumeChanged(int volume) {
}
public void onResult(RecognizerResult result, boolean islast) {
mResult.append(result.getResultString());
}
// 会话发生错误回调接口
public void onError(SpeechError error) {
System.out.println("---------------error");
error.getErrorDescription(true);// 获取错误码描述
logger.debug(fileName + "-xf错误码:-" + error.getErrorCode());
}
// 扩展用接口
public void onEvent(int eventType, int arg1, int agr2, String msg) {
}
};
}