package cn.netkiller.album.religion.ai;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.iflytek.cloud.RequestListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvent;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;
import java.nio.charset.StandardCharsets;
import cn.netkiller.album.religion.ContextHolder;
import cn.assets.album.religion.R;
public class Wakeup {
private static final String TAG = Wakeup.class.getSimpleName();
private final int curThresh = 1450;
private final String threshStr = "门限值:";
private final String keep_alive = "1";
private final String ivwNetMode = "0";
private final Context context;
// 查询资源请求回调监听
private final RequestListener requestListener = new RequestListener() {
@Override
public void onEvent(int eventType, Bundle params) {
// 以下代码用于获取查询会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
//if(SpeechEvent.EVENT_SESSION_ID == eventType) {
// Log.d(TAG, "sid:"+params.getString(SpeechEvent.KEY_EVENT_SESSION_ID));
//}
}
@Override
public void onCompleted(SpeechError error) {
if (error != null) {
Log.d(TAG, "error:" + error.getErrorCode());
showTip(error.getPlainDescription(true));
}
}
@Override
public void onBufferReceived(byte[] buffer) {
try {
String resultInfo = new String(buffer, StandardCharsets.UTF_8);
Log.d(TAG, "resultInfo:" + resultInfo);
// JSONTokener tokener = new JSONTokener(resultInfo);
// JSONObject object = new JSONObject(tokener);
//
// int ret = object.getInt("ret");
// if (ret == 0) {
// String uri = object.getString("dlurl");
// String md5 = object.getString("md5");
// Log.d(TAG, "uri:" + uri);
// Log.d(TAG, "md5:" + md5);
// showTip("请求成功");
// }
} catch (Exception e) {
e.printStackTrace();
}
}
};
private VoiceWakeuper voiceWakeuper;
// 唤醒结果内容
private String resultString;
private final WakeuperListener wakeuperListener = new WakeuperListener() {
@Override
public void onResult(WakeuperResult result) {
Log.d(TAG, "onResult");
try {
String text = result.getResultString();
Log.d(TAG, text);
// JSONObject object;
// object = new JSONObject(text);
// StringBuffer buffer = new StringBuffer();
// buffer.append("【RAW】 " + text);
// buffer.append("\n");
// buffer.append("【操作类型】" + object.optString("sst"));
// buffer.append("\n");
// buffer.append("【唤醒词id】" + object.optString("id"));
// buffer.append("\n");
// buffer.append("【得分】" + object.optString("score"));
// buffer.append("\n");
// buffer.append("【前端点】" + object.optString("bos"));
// buffer.append("\n");
// buffer.append("【尾端点】" + object.optString("eos"));
// resultString = buffer.toString();
showTip(text);
} catch (Exception e) {
resultString = "结果解析出错";
e.printStackTrace();
}
}
@Override
public void onError(SpeechError error) {
showTip(error.getPlainDescription(true));
}
@Override
public void onBeginOfSpeech() {
}
@Override
public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
// EVENT_RECORD_DATA 事件仅在 NOTIFY_RECORD_DATA 参数值为 真 时返回
if (eventType == SpeechEvent.EVENT_RECORD_DATA) {
final byte[] audio = obj.getByteArray(SpeechEvent.KEY_EVENT_RECORD_DATA);
Log.i(TAG, "ivw audio length: " + audio.length);
}
}
@Override
public void onVolumeChanged(int volume) {
}
};
// 设置门限值 : 门限值越低越容易被唤醒
public Wakeup() {
this.context = ContextHolder.getContext();
// String param = "appid=" + context.getString(R.string.app_id) + "," + SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC;
// SpeechUtility.createUtility(context, param);
voiceWakeuper = VoiceWakeuper.createWakeuper(context, null);
if (null == voiceWakeuper) {
// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
Toast.makeText(context
, "创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化"
, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "准备唤醒", Toast.LENGTH_LONG).show();
// 清空参数
voiceWakeuper.setParameter(SpeechConstant.PARAMS, null);
// 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
voiceWakeuper.setParameter(SpeechConstant.IVW_THRESHOLD, "0:1450");
// 设置唤醒模式
voiceWakeuper.setParameter(SpeechConstant.IVW_SST, "wakeup");
// 设置持续进行唤醒
voiceWakeuper.setParameter(SpeechConstant.KEEP_ALIVE, "1");
// 设置闭环优化网络模式
voiceWakeuper.setParameter(SpeechConstant.IVW_NET_MODE, "1");
// 设置唤醒资源路径
voiceWakeuper.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
// 设置唤醒录音保存路径,保存最近一分钟的音频
voiceWakeuper.setParameter(SpeechConstant.IVW_AUDIO_PATH,
context.getExternalFilesDir("msc").getAbsolutePath() + "/ivw.wav");
voiceWakeuper.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
// 如有需要,设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节
//voiceWakeuper.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" );
// 启动唤醒
/* voiceWakeuper.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");*/
}
}
public void startListening(WakeuperListener wakeuperListener) {
//非空判断,防止因空指针使程序崩溃
voiceWakeuper = VoiceWakeuper.getWakeuper();
if (voiceWakeuper != null) {
resultString = "";
voiceWakeuper.startListening(wakeuperListener);
} else {
showTip("唤醒未初始化");
}
}
private void stopListening() {
voiceWakeuper = VoiceWakeuper.getWakeuper();
if (voiceWakeuper != null) {
voiceWakeuper.stopListening();
}
}
public void cancel() {
// 销毁合成对象
voiceWakeuper = VoiceWakeuper.getWakeuper();
if (voiceWakeuper != null) {
voiceWakeuper.cancel();
}
}
public void destroy() {
// 销毁合成对象
voiceWakeuper = VoiceWakeuper.getWakeuper();
if (voiceWakeuper != null) {
voiceWakeuper.destroy();
}
}
private String getResource() {
final String resPath = ResourceUtil.generateResourcePath(context, ResourceUtil.RESOURCE_TYPE.assets, "ivw/" + context.getString(R.string.app_id) + ".jet");
Log.d(TAG, "resPath: " + resPath);
return resPath;
}
/**
* 查询闭环优化唤醒资源
* 请在闭环优化网络模式1或者模式2使用
*/
// public void queryResource() {
// int ret = voiceWakeuper.queryResource(getResource(), requestListener);
// showTip("updateResource ret:" + ret);
// }
private void showTip(final String str) {
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
Toast.makeText(context.getApplicationContext(), str, Toast.LENGTH_SHORT).show();
// }
// });
}
}