341 lines
10 KiB
Java
341 lines
10 KiB
Java
package com.yunbao.live.dialog;
|
||
|
||
import android.os.Bundle;
|
||
import android.os.Handler;
|
||
import android.text.SpannableStringBuilder;
|
||
import android.text.TextUtils;
|
||
import android.util.Log;
|
||
import android.view.Gravity;
|
||
import android.view.View;
|
||
import android.view.Window;
|
||
import android.view.WindowManager;
|
||
import android.widget.ImageView;
|
||
import android.widget.TextView;
|
||
import android.widget.Toast;
|
||
|
||
import com.iflytek.cloud.ErrorCode;
|
||
import com.iflytek.cloud.InitListener;
|
||
import com.iflytek.cloud.RecognizerListener;
|
||
import com.iflytek.cloud.RecognizerResult;
|
||
import com.iflytek.cloud.SpeechConstant;
|
||
import com.iflytek.cloud.SpeechError;
|
||
import com.iflytek.cloud.SpeechRecognizer;
|
||
import com.yunbao.common.dialog.AbsDialogFragment;
|
||
import com.yunbao.common.utils.WordsTypeUtil;
|
||
import com.yunbao.live.R;
|
||
import com.yunbao.live.activity.LiveAudienceActivity;
|
||
|
||
import org.json.JSONArray;
|
||
import org.json.JSONException;
|
||
import org.json.JSONObject;
|
||
import org.json.JSONTokener;
|
||
|
||
import java.util.Locale;
|
||
|
||
import pl.droidsonroids.gif.GifImageView;
|
||
|
||
public class VoiceDialog extends AbsDialogFragment {
|
||
// 语音识别对象
|
||
private SpeechRecognizer mIat = null;
|
||
private String TAG = "VoiceDialog";
|
||
private ImageView voiceFluctuations, iconWithdraw;
|
||
private TextView voiceChat, fingersSlide;
|
||
private GifImageView gifView;
|
||
private SpannableStringBuilder builder = new SpannableStringBuilder();
|
||
private boolean isSend = true;
|
||
private Handler handler = new Handler();
|
||
|
||
public boolean isSend() {
|
||
return isSend;
|
||
}
|
||
|
||
@Override
|
||
public void onStop() {
|
||
super.onStop();
|
||
if (mIat != null) {
|
||
mIat.cancel();
|
||
mIat.destroy();
|
||
mIat = null;
|
||
}
|
||
|
||
}
|
||
|
||
public String sendMessage() {
|
||
|
||
return voiceChat.getText().toString();
|
||
}
|
||
|
||
@Override
|
||
protected int getLayoutId() {
|
||
return R.layout.view_voice_dialog;
|
||
}
|
||
|
||
@Override
|
||
protected int getDialogStyle() {
|
||
return R.style.dialog4;
|
||
}
|
||
|
||
@Override
|
||
protected boolean canCancel() {
|
||
return false;
|
||
}
|
||
|
||
@Override
|
||
protected void setWindowAttributes(Window window) {
|
||
window.setWindowAnimations(com.yunbao.common.R.style.bottomToTopAnim);
|
||
WindowManager.LayoutParams params = window.getAttributes();
|
||
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||
params.gravity = Gravity.CENTER;
|
||
window.setAttributes(params);
|
||
handler.postDelayed(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
|
||
}
|
||
}, 30000);
|
||
}
|
||
|
||
@Override
|
||
public void dismiss() {
|
||
listener = null;
|
||
handler.removeCallbacks(timeOut);
|
||
super.dismiss();
|
||
}
|
||
|
||
@Override
|
||
public void onActivityCreated(Bundle savedInstanceState) {
|
||
super.onActivityCreated(savedInstanceState);
|
||
voiceFluctuations = (ImageView) findViewById(R.id.voice_fluctuations);
|
||
iconWithdraw = (ImageView) findViewById(R.id.icon_withdraw);
|
||
voiceChat = (TextView) findViewById(R.id.voice_chat);
|
||
fingersSlide = (TextView) findViewById(R.id.fingers_slide);
|
||
gifView = (GifImageView) findViewById(R.id.gif_view);
|
||
startRecognize();
|
||
iconWithdraw.setVisibility(View.GONE);
|
||
gifView.setVisibility(View.GONE);
|
||
voiceFluctuations.setVisibility(View.VISIBLE);
|
||
handler.postDelayed(timeOut, 30000);
|
||
}
|
||
|
||
private Runnable timeOut = new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
if (listener != null) {
|
||
listener.timeout();
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 上划取消
|
||
*/
|
||
public void withdraw() {
|
||
mIat.stopListening();
|
||
if (!isDetached()) {
|
||
voiceFluctuations.setVisibility(View.GONE);
|
||
gifView.setVisibility(View.GONE);
|
||
iconWithdraw.setVisibility(View.VISIBLE);
|
||
fingersSlide.setText(getString(R.string.release_cancel_send));
|
||
isSend = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 上划取消
|
||
*/
|
||
public void notWithdraw() {
|
||
startRecognize();
|
||
if (!isDetached()) {
|
||
if (TextUtils.isEmpty(sendMessage())) {
|
||
if (gifView.getVisibility() != View.VISIBLE)
|
||
voiceFluctuations.setVisibility(View.VISIBLE);
|
||
} else {
|
||
if (voiceFluctuations.getVisibility() != View.VISIBLE)
|
||
gifView.setVisibility(View.VISIBLE);
|
||
}
|
||
iconWithdraw.setVisibility(View.GONE);
|
||
fingersSlide.setText(getString(R.string.fingers_slide));
|
||
isSend = true;
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 科大讯飞内置录音机
|
||
*/
|
||
RecognizerListener recognizerListener = new RecognizerListener() {
|
||
@Override
|
||
public void onVolumeChanged(int volume, byte[] bytes) {
|
||
if (volume > 10) {
|
||
gifView.setVisibility(View.VISIBLE);
|
||
voiceFluctuations.setVisibility(View.GONE);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onBeginOfSpeech() {
|
||
Log.e(TAG, "onBeginOfSpeech 开始讲话");
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onEndOfSpeech() {
|
||
Log.e(TAG, "onBeginOfSpeech 结束讲话");
|
||
if (TextUtils.isEmpty(voiceChat.getText())) {
|
||
dismiss();
|
||
TextHintDialog textHintDialog = new TextHintDialog();
|
||
textHintDialog.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "TextHintDialog");
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onResult(RecognizerResult recognizerResult, boolean b) {
|
||
printResult(recognizerResult);
|
||
}
|
||
|
||
@Override
|
||
public void onError(SpeechError speechError) {
|
||
if (speechError.getErrorCode() == ErrorCode.ERROR_NO_NETWORK) {
|
||
Toast.makeText(
|
||
getContext(),
|
||
getContext().getString(com.yunbao.common.R.string.load_failure),
|
||
Toast.LENGTH_SHORT)
|
||
.show();
|
||
}
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onEvent(int i, int i1, int i2, Bundle bundle) {
|
||
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 结束录音
|
||
*/
|
||
private void endOfSpeech() {
|
||
}
|
||
|
||
/**
|
||
* 初始化监听器。
|
||
*/
|
||
private InitListener mInitListener =
|
||
code -> Log.e(TAG, "onInit " + code);
|
||
|
||
/**
|
||
* 开始识别
|
||
*/
|
||
public void startRecognize() {
|
||
if (null == mIat) {
|
||
mIat = SpeechRecognizer.createRecognizer(getContext(), mInitListener);
|
||
}
|
||
if (mIat.isListening()) {
|
||
return;
|
||
}
|
||
setParam();
|
||
int ret = mIat.startListening(recognizerListener);
|
||
if (ret != ErrorCode.SUCCESS) {
|
||
Log.e(TAG, "startRecognize ret error " + ret);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 参数设置,设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
|
||
*
|
||
* @param
|
||
* @return
|
||
*/
|
||
private void setParam() {
|
||
// 清空参数
|
||
mIat.setParameter(SpeechConstant.PARAMS, null);
|
||
|
||
// 设置听写引擎
|
||
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
|
||
// 设置返回结果格式
|
||
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
|
||
|
||
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
|
||
if ("zh".equals(Locale.getDefault().getLanguage().toLowerCase())) {
|
||
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
|
||
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
|
||
} else {
|
||
mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
|
||
}
|
||
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
|
||
mIat.setParameter(SpeechConstant.VAD_BOS, "10000");
|
||
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
|
||
mIat.setParameter(SpeechConstant.VAD_EOS, "30000");
|
||
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
|
||
mIat.setParameter(SpeechConstant.ASR_PTT, "1");
|
||
}
|
||
|
||
/**
|
||
* 打印数据结果
|
||
*
|
||
* @param result
|
||
*/
|
||
private void printResult(RecognizerResult result) {
|
||
String json = result.getResultString();
|
||
String text = parseRecognizeResult(result);
|
||
Log.e(TAG, "printResult " + text);
|
||
try {
|
||
JSONObject obj = new JSONObject(json);
|
||
boolean isLast = obj.getBoolean("ls");
|
||
if (isLast) {
|
||
endOfSpeech();
|
||
}
|
||
builder.append(text);
|
||
|
||
voiceChat.setText(WordsTypeUtil.changeTraditional(builder.toString()));
|
||
} catch (JSONException e) {
|
||
e.printStackTrace();
|
||
}
|
||
|
||
|
||
}
|
||
|
||
/**
|
||
* 转译语音返回
|
||
*
|
||
* @param results
|
||
* @return
|
||
*/
|
||
public String parseRecognizeResult(RecognizerResult results) {
|
||
StringBuilder ret = new StringBuilder();
|
||
try {
|
||
JSONTokener jsonTokener = new JSONTokener(results.getResultString());
|
||
JSONObject jsonObject = new JSONObject(jsonTokener);
|
||
|
||
JSONArray words = jsonObject.getJSONArray("ws");
|
||
for (int i = 0; i < words.length(); i++) {
|
||
// 转写结果词,默认使用第一个结果
|
||
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
||
JSONObject obj = items.getJSONObject(0);
|
||
ret.append(obj.getString("w"));
|
||
// 如果需要多候选结果,解析数组其他字段
|
||
// for(int j = 0; j < items.length(); j++)
|
||
// {
|
||
// JSONObject obj = items.getJSONObject(j);
|
||
// ret.append(obj.getString("w"));
|
||
// }
|
||
}
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
return ret.toString();
|
||
}
|
||
|
||
private VoiceListener listener;
|
||
|
||
public VoiceDialog setListener(VoiceListener listener) {
|
||
this.listener = listener;
|
||
return this;
|
||
}
|
||
|
||
public interface VoiceListener {
|
||
void timeout();
|
||
}
|
||
}
|