diff --git a/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java b/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java
index abf9f7b62..ae27de871 100644
--- a/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java
+++ b/common/src/main/java/com/yunbao/common/manager/imrongcloud/RongcloudIMManager.java
@@ -12,11 +12,12 @@ import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
+import com.iflytek.cloud.SpeechConstant;
+import com.iflytek.cloud.SpeechUtility;
import com.yunbao.common.CommonAppConfig;
import com.yunbao.common.bean.IMLoginModel;
import com.yunbao.common.event.RongIMConnectionStatusEvent;
import com.yunbao.common.manager.IMLoginManager;
-import com.yunbao.common.views.weight.Recognizer;
import org.greenrobot.eventbus.EventBus;
@@ -61,7 +62,8 @@ public class RongcloudIMManager {
Log.e(CLASSNAME, "initRongIM:");
initPhotoGlide();
//初始化科大讯飞语音转文字
- Recognizer.setAppId("671d2ae3");
+ String params = SpeechConstant.APPID + "=" + "671d2ae3";
+ SpeechUtility.createUtility(application.getApplicationContext(), params);
}
private static RongIMClient.OnReceiveMessageWrapperListener mListener;
diff --git a/common/src/main/java/com/yunbao/common/views/weight/Recognizer.java b/common/src/main/java/com/yunbao/common/views/weight/Recognizer.java
deleted file mode 100644
index e566f5f6c..000000000
--- a/common/src/main/java/com/yunbao/common/views/weight/Recognizer.java
+++ /dev/null
@@ -1,362 +0,0 @@
-package com.yunbao.common.views.weight;
-
-import android.content.Context;
-import android.graphics.drawable.AnimationDrawable;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-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.iflytek.cloud.SpeechUtility;
-import com.yunbao.common.R;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-
-import java.util.Locale;
-import java.util.Random;
-
-
-public class Recognizer extends RelativeLayout {
- private static final String TAG = "Recognizer";
-
- private ImageView imgMic;
-
- private Random random;
- private IRecognizedResult mResultCallBack;
- private SpeechRecognizer mIat = null;
- private AnimationDrawable animStart;
- private AnimationDrawable animEnd;
- private static String mAppId;
-
- /**
- * 开发者可以通过此接口设置自己从科大讯飞官网申请的 appId。 此方法可以在 SDK init 之后调用。
- *
- *
注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
- *
- * @param appId 自定义的 appId
- */
- public static void setAppId(String appId) {
- mAppId = appId;
- }
-
- public Recognizer(Context context) {
- super(context);
- initViews();
- }
-
- public Recognizer(Context context, AttributeSet attrs) {
- super(context, attrs);
- initViews();
- }
-
- private void initViews() {
-// setClickable(true);
-// setBackgroundColor(getResources().getColor(R.color.white));
-// RelativeLayout recognizerContainer =
-// (RelativeLayout)
-// LayoutInflater.from(getContext())
-// .inflate(R.layout.rc_view_recognizer, null);
-// View rlMic = recognizerContainer.findViewById(R.id.rl_mic);
-// rlMic.setOnClickListener(
-// new OnClickListener() {
-// @Override
-// public void onClick(View view) {
-// if (mIat == null || !mIat.isListening()) {
-// startRecognize();
-// } else {
-// reset();
-// }
-// }
-// });
-// imgMic = (ImageView) recognizerContainer.findViewById(R.id.img_mic);
-//
-//
-// addView(recognizerContainer);
-// random = new Random();
-// String params = SpeechConstant.APPID + "=" + mAppId;
-// SpeechUtility.createUtility(getContext().getApplicationContext(), params);
- }
-
- /**
- * 初始化监听器。
- */
- private static InitListener mInitListener =
- new InitListener() {
-
- @Override
- public void onInit(int 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(this);
-// 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, "4000");
- // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
- mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
- // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
- mIat.setParameter(SpeechConstant.ASR_PTT, "1");
- }
-
- private void setRandomImageResource() {
-// int num = random.nextInt(3) + 1;
-// switch (num) {
-// case 1:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_01);
-// break;
-// case 2:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_02);
-// break;
-// default:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_03);
-// break;
-// }
- }
-
- private void changeVolume(int volume) {
-// if (null != imgMic) {
-// switch (volume / 2) {
-// case 0:
-// setRandomImageResource();
-// break;
-// case 1:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_02);
-// break;
-// case 2:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_03);
-// break;
-// case 3:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_04);
-// break;
-// case 4:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_05);
-// break;
-// case 5:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_06);
-// break;
-// case 6:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_07);
-// break;
-// case 7:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_08);
-// break;
-// case 8:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_09);
-// break;
-// case 9:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_10);
-// break;
-// case 10:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_11);
-// break;
-// case 11:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_12);
-// break;
-// case 12:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_13);
-// break;
-// default:
-// imgMic.setImageResource(R.mipmap.rc_recognize_volume_14);
-// break;
-// }
-// }
- }
-
- private void endOfSpeech() {
-// if (null == imgMic) return;
-// imgMic.setImageResource(R.drawable.rc_anim_speech_end);
-// animEnd = (AnimationDrawable) imgMic.getDrawable();
-// imgMic.clearAnimation();
-// animEnd.start();
- }
-
- private void beginOfSpeech() {
-// if (null == imgMic) return;
-// imgMic.setImageResource(R.drawable.rc_anim_speech_start);
-// animStart = (AnimationDrawable) imgMic.getDrawable();
-// imgMic.clearAnimation();
-// animStart.start();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (null != mIat) {
- mIat.cancel();
- mIat.destroy();
- mIat = null;
- }
- if (null != mResultCallBack) {
- mResultCallBack = null;
- }
- if (animEnd != null) {
- animEnd.stop();
- animEnd = null;
- }
- if (animStart != null) {
- animStart.stop();
- animEnd = null;
- }
- mInitListener = null;
- }
-
- 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();
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
-
- if (mResultCallBack != null) {
- mResultCallBack.onResult(text);
- }
- }
-//
-// @Override
-// public void onResult(RecognizerResult recognizerResult, boolean b) {
-// printResult(recognizerResult);
-// if (imgMic != null) {
-// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
-// }
-// }
-//
-// @Override
-// public void onError(SpeechError speechError) {
-// if (speechError.getErrorCode() == ErrorCode.ERROR_NO_NETWORK) {
-// Toast.makeText(
-// getContext(),
-// getContext().getString(R.string.load_failure),
-// Toast.LENGTH_SHORT)
-// .show();
-// }
-// if (imgMic != null) {
-// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
-// }
-// }
-//
-// @Override
-// public void onEvent(int eventType, int i1, int i2, Bundle bundle) {
-// Log.e(TAG, "RecognizerView onEvent eventType: " + eventType);
-// }
-//
-// @Override
-// public void onVolumeChanged(int volume, byte[] bytes) {
-// changeVolume(volume);
-// }
-//
-// @Override
-// public void onBeginOfSpeech() {
-// Log.e(TAG, "RecognizerView onBeginOfSpeech");
-// beginOfSpeech();
-// }
-//
-// @Override
-// public void onEndOfSpeech() {
-// Log.e(TAG, "RecognizerView onEndOfSpeech");
-// endOfSpeech();
-// }
-
- public void setCallBack(IRecognizedResult resultCallBack) {
- mResultCallBack = resultCallBack;
- }
-
- private void reset() {
- if (null != mIat) {
- mIat.cancel();
- mIat.destroy();
- mIat = null;
- }
- if (null != animEnd) {
- animEnd.stop();
- animEnd = null;
- }
- if (animStart != null) {
- animStart.stop();
- animStart = null;
- }
- if (imgMic != null) {
-// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
- }
- }
-
- 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();
- }
-}
diff --git a/common/src/main/res/mipmap-xxhdpi/icon_withdraw.png b/common/src/main/res/mipmap-xxhdpi/icon_withdraw.png
new file mode 100644
index 000000000..f92d292a4
Binary files /dev/null and b/common/src/main/res/mipmap-xxhdpi/icon_withdraw.png differ
diff --git a/common/src/main/res/mipmap-xxhdpi/voice_fluctuations.gif b/common/src/main/res/mipmap-xxhdpi/voice_fluctuations.gif
new file mode 100644
index 000000000..90c6a18db
Binary files /dev/null and b/common/src/main/res/mipmap-xxhdpi/voice_fluctuations.gif differ
diff --git a/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java b/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java
index 2bdd4222f..98cd7738e 100644
--- a/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java
+++ b/live/src/main/java/com/yunbao/live/activity/LiveAudienceActivity.java
@@ -139,6 +139,7 @@ public class LiveAudienceActivity extends LiveActivity {
private int liveBg = 0;
//直播间进入房间队列
private Handler liveHandler = new Handler();
+ private ImageView voicePress;
@Override
public T findViewById(@IdRes int id) {
@@ -178,7 +179,7 @@ public class LiveAudienceActivity extends LiveActivity {
private void initView() {
// 竖直滑动 ViewPager
verticalViewPager = findViewById(R.id.view_pager);
-
+ voicePress = findViewById(R.id.voice_press);
verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
//判断是否有直播悬浮窗,有直接关闭
if (EasyFloat.isShow("LiveFloatView")) {
@@ -623,7 +624,7 @@ public class LiveAudienceActivity extends LiveActivity {
}
public void setEnableScroll(boolean enableScroll) {
- verticalViewPager.setEnableScroll(enableScroll);
+ verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -645,7 +646,7 @@ public class LiveAudienceActivity extends LiveActivity {
manager.onAdd(liveBean, mLiveType, mLiveTypeVal, mLiveSDK);
}
} else {
- verticalViewPager.setEnableScroll(true);
+ verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
}
}
@@ -908,6 +909,18 @@ public class LiveAudienceActivity extends LiveActivity {
case MESSAGE_BOTTOM:
manager.messageBottom();
break;
+ case VOICE_PRESS:
+ voicePress.setVisibility(event.isVoicePress() ? View.VISIBLE : View.GONE);
+ if (IMLoginManager.get(mContext).isSlide()) {
+ if (event.isVoicePress()) {
+ verticalViewPager.setEnableScroll(false);
+ } else {
+ verticalViewPager.setEnableScroll(true);
+ }
+ }
+
+ break;
+
}
diff --git a/live/src/main/java/com/yunbao/live/dialog/TextHintDialog.java b/live/src/main/java/com/yunbao/live/dialog/TextHintDialog.java
new file mode 100644
index 000000000..0ac78c6ac
--- /dev/null
+++ b/live/src/main/java/com/yunbao/live/dialog/TextHintDialog.java
@@ -0,0 +1,48 @@
+package com.yunbao.live.dialog;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.yunbao.common.dialog.AbsDialogFragment;
+import com.yunbao.common.utils.DpUtil;
+import com.yunbao.live.R;
+
+public class TextHintDialog extends AbsDialogFragment {
+
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.view_text_hint;
+ }
+
+ @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 = DpUtil.dp2px(309);
+ params.height = DpUtil.dp2px(44);
+ params.gravity = Gravity.CENTER;
+ window.setAttributes(params);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ new Handler().postDelayed(() -> dismiss(), 2000);
+ }
+
+
+}
diff --git a/live/src/main/java/com/yunbao/live/dialog/VoiceDialog.java b/live/src/main/java/com/yunbao/live/dialog/VoiceDialog.java
new file mode 100644
index 000000000..ae8294607
--- /dev/null
+++ b/live/src/main/java/com/yunbao/live/dialog/VoiceDialog.java
@@ -0,0 +1,292 @@
+package com.yunbao.live.dialog;
+
+import android.os.Bundle;
+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.glide.ImgLoader;
+import com.yunbao.common.utils.DpUtil;
+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;
+
+ 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 = DpUtil.dp2px(350);
+ params.height = DpUtil.dp2px(200);
+ params.gravity = Gravity.CENTER;
+ window.setAttributes(params);
+ }
+
+ @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);
+ }
+
+ /**
+ * 上划取消
+ */
+ public void withdraw() {
+ 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() {
+ voiceFluctuations.setVisibility(View.VISIBLE);
+ iconWithdraw.setVisibility(View.GONE);
+ fingersSlide.setText(getString(R.string.fingers_slide));
+ gifView.setVisibility(View.VISIBLE);
+ isSend = true;
+ }
+
+ /**
+ * 科大讯飞内置录音机
+ */
+ RecognizerListener recognizerListener = new RecognizerListener() {
+ @Override
+ public void onVolumeChanged(int volume, byte[] bytes) {
+ if (volume > 20) {
+ gifView.setVisibility(View.VISIBLE);
+ voiceFluctuations.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onBeginOfSpeech() {
+ Log.e(TAG, "onBeginOfSpeech 开始讲话");
+ voiceFluctuations.setVisibility(View.GONE);
+ gifView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onEndOfSpeech() {
+ Log.e(TAG, "onBeginOfSpeech 结束讲话");
+ ImgLoader.displayGif(mContext, R.mipmap.img_p, voiceFluctuations);
+ 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(builder);
+ } 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();
+ }
+}
diff --git a/live/src/main/java/com/yunbao/live/event/LiveAudienceEvent.java b/live/src/main/java/com/yunbao/live/event/LiveAudienceEvent.java
index 6ba536c79..b4e43512d 100644
--- a/live/src/main/java/com/yunbao/live/event/LiveAudienceEvent.java
+++ b/live/src/main/java/com/yunbao/live/event/LiveAudienceEvent.java
@@ -20,6 +20,16 @@ public class LiveAudienceEvent extends BaseModel {
private int liveTypeVal;
private MsgModel msgModel;//全服消息
private AiAutomaticSpeechModel aiAutomaticSpeechModel;//机器人消息
+ private boolean voicePress = false;
+
+ public boolean isVoicePress() {
+ return voicePress;
+ }
+
+ public LiveAudienceEvent setVoicePress(boolean voicePress) {
+ this.voicePress = voicePress;
+ return this;
+ }
public AiAutomaticSpeechModel getAiAutomaticSpeechModel() {
return aiAutomaticSpeechModel;
@@ -149,7 +159,8 @@ public class LiveAudienceEvent extends BaseModel {
AI_AUTOMATIC_SPEECH(26, "机器人助手"),
STAR_CHALLENGE_UPGRADE_NOTIFY(27, "星级挑战成功"),
MESSAGE_BOTTOM(28, "聊天消息滚动到底部"),
- FLOAT_SETTING(29, "悬浮窗设置");
+ FLOAT_SETTING(29, "悬浮窗设置"),
+ VOICE_PRESS(30, "长按展示图片");
private int type;
private String name;
diff --git a/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java b/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java
index 625a8d5a1..affaa6ea0 100644
--- a/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java
+++ b/live/src/main/java/com/yunbao/live/views/LiveAudienceViewHolder.java
@@ -12,29 +12,28 @@ import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;
-import com.opensource.svgaplayer.SVGACallback;
import com.opensource.svgaplayer.SVGADrawable;
import com.opensource.svgaplayer.SVGAImageView;
import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import com.yunbao.common.CommonAppConfig;
import com.yunbao.common.Constants;
-import com.yunbao.common.bean.MsgModel;
import com.yunbao.common.bean.NewPeopleInfo;
import com.yunbao.common.event.MessageIMEvent;
import com.yunbao.common.glide.ImgLoader;
import com.yunbao.common.http.API;
import com.yunbao.common.http.HttpCallback;
import com.yunbao.common.http.HttpClient;
-import com.yunbao.common.manager.imrongcloud.MessageIMManager;
import com.yunbao.common.utils.Bus;
import com.yunbao.common.utils.DpUtil;
import com.yunbao.common.utils.SVGAViewUtils;
@@ -48,6 +47,7 @@ import com.yunbao.live.bean.LiveChatBean;
import com.yunbao.live.dialog.LiveHDDialogFragment;
import com.yunbao.live.dialog.LiveMicUserDialogFragment;
import com.yunbao.live.dialog.LivePromotionDialogFragment;
+import com.yunbao.live.dialog.VoiceDialog;
import com.yunbao.live.event.LiveAudienceEvent;
import org.greenrobot.eventbus.EventBus;
@@ -79,6 +79,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
private ImageView giftImage, liveNewPeople;
private String newPeopleUrl = null;
private View mNewPeopleRedDot;
+ private LinearLayout voiceButton;
public LiveAudienceViewHolder(Context context, ViewGroup parentView) {
super(context, parentView);
@@ -179,6 +180,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
return R.layout.view_live_audience;
}
+ @SuppressLint("ClickableViewAccessibility")
@Override
public void init() {
super.init();
@@ -188,6 +190,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
findViewById(R.id.btn_red_pack).setOnClickListener(this);
findViewById(R.id.btn_gift).setOnClickListener(this);
findViewById(R.id.btn_zg).setOnClickListener(this);
+ voiceButton = (LinearLayout) findViewById(R.id.voice_button);
giftImage = (ImageView) findViewById(R.id.gift_image);
liveNewPeople = (ImageView) findViewById(R.id.live_new_people);
svga_new_user_gif = (SVGAImageView) findViewById(R.id.svga_new_user_gif);
@@ -262,8 +265,57 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
String language = locale.getLanguage();
ImgLoader.display(mContext, TextUtils.equals(language, "zh") ? R.mipmap.live_icon_new_people_cn : R.mipmap.live_icon_newpeople_en, liveNewPeople);
+
+ voiceButton.setOnTouchListener((v, event) -> {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ downY = event.getY();
+ //按下
+ handler.postDelayed(mLongPressed, 500);
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ float moveY = event.getY();
+ if (downY - moveY > 120) {
+ voiceDialog.withdraw();
+ }
+ if ((downY - moveY < 100) && (downY - moveY > 30)) {
+ voiceDialog.notWithdraw();
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ //松开
+ handler.removeCallbacks(mLongPressed);
+ Bus.get().post(new LiveAudienceEvent()
+ .setVoicePress(false)
+ .setType(LiveAudienceEvent.LiveAudienceType.VOICE_PRESS));
+
+ if (voiceDialog != null) {
+ if (voiceDialog.isSend() && !TextUtils.isEmpty(voiceDialog.sendMessage())) {
+ ((LiveActivity) mContext).sendChatMessage(voiceDialog.sendMessage(), null, null);
+ }
+
+ voiceDialog.dismiss();
+ voiceDialog = null;
+ }
+ }
+ return true;
+ });
+
}
+ private float downY = 0;
+
+ private VoiceDialog voiceDialog = null;
+ private Runnable mLongPressed = new Runnable() {
+ @Override
+ public void run() {
+ if (voiceDialog == null) {
+ voiceDialog = new VoiceDialog();
+ }
+ voiceDialog.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "VoiceDialog");
+ Bus.get().post(new LiveAudienceEvent()
+ .setVoicePress(true)
+ .setType(LiveAudienceEvent.LiveAudienceType.VOICE_PRESS));
+ }
+ };
+
public static Handler handler = new Handler();
public static Runnable runnable;
@@ -360,13 +412,13 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
return;
}
Bundle bundle = new Bundle();
- String url = newPeopleUrl+ (newPeopleUrl.contains("?")?"&":"?") + "g=Appapi&m=Turntable&a=tricky";
+ String url = newPeopleUrl + (newPeopleUrl.contains("?") ? "&" : "?") + "g=Appapi&m=Turntable&a=tricky";
url += "&uid=" + CommonAppConfig.getInstance().getUid() + "&token="
+ CommonAppConfig.getInstance().getToken() + "&anchorUid=" + mLiveUid;
bundle.putString("url", url);
bundle.putInt("show_type", 0);
- bundle.putInt("height",DpUtil.dp2px(1));
- // bundle.putBoolean("banScrollY",true);
+ bundle.putInt("height", DpUtil.dp2px(1));
+ // bundle.putBoolean("banScrollY",true);
LiveHDDialogFragment liveHDDialogFragment = new LiveHDDialogFragment();
liveHDDialogFragment.setArguments(bundle);
liveHDDialogFragment.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "LiveHDDialogFragment");
diff --git a/live/src/main/res/drawable/bg_voice_chat.xml b/live/src/main/res/drawable/bg_voice_chat.xml
new file mode 100644
index 000000000..ef4188aec
--- /dev/null
+++ b/live/src/main/res/drawable/bg_voice_chat.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/live/src/main/res/layout/activity_live_detail.xml b/live/src/main/res/layout/activity_live_detail.xml
index b709ef276..9cb9f4e07 100644
--- a/live/src/main/res/layout/activity_live_detail.xml
+++ b/live/src/main/res/layout/activity_live_detail.xml
@@ -9,6 +9,13 @@
android:layout_height="match_parent"
android:overScrollMode="never" />
-
+
\ No newline at end of file
diff --git a/live/src/main/res/layout/view_live_audience.xml b/live/src/main/res/layout/view_live_audience.xml
index 6bc6f15f7..00dccb471 100644
--- a/live/src/main/res/layout/view_live_audience.xml
+++ b/live/src/main/res/layout/view_live_audience.xml
@@ -245,7 +245,7 @@
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
-
+ android:clickable="false"
android:orientation="horizontal">
+ android:background="@drawable/bc_sound_recording_right"
+ android:clickable="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:gravity="center">
diff --git a/live/src/main/res/layout/view_text_hint.xml b/live/src/main/res/layout/view_text_hint.xml
new file mode 100644
index 000000000..f95a9a5e1
--- /dev/null
+++ b/live/src/main/res/layout/view_text_hint.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/live/src/main/res/layout/view_voice_dialog.xml b/live/src/main/res/layout/view_voice_dialog.xml
new file mode 100644
index 000000000..0d7d75834
--- /dev/null
+++ b/live/src/main/res/layout/view_voice_dialog.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/live/src/main/res/mipmap-xxxhdpi/icon_voice_press.png b/live/src/main/res/mipmap-xxxhdpi/icon_voice_press.png
new file mode 100644
index 000000000..769c6b9d0
Binary files /dev/null and b/live/src/main/res/mipmap-xxxhdpi/icon_voice_press.png differ
diff --git a/live/src/main/res/mipmap-xxxhdpi/img_p.png b/live/src/main/res/mipmap-xxxhdpi/img_p.png
new file mode 100644
index 000000000..07df06059
Binary files /dev/null and b/live/src/main/res/mipmap-xxxhdpi/img_p.png differ
diff --git a/live/src/main/res/values/strings.xml b/live/src/main/res/values/strings.xml
index c36459deb..7ef32f6ac 100644
--- a/live/src/main/res/values/strings.xml
+++ b/live/src/main/res/values/strings.xml
@@ -21,4 +21,7 @@
開通貴族
享受專屬特權!
前往貴族中心
+ 手指上滑,取消發送
+ 松開取消發送
+ 已超过10秒未识别到录音
diff --git a/main/src/main/java/com/yunbao/main/activity/MainActivity.java b/main/src/main/java/com/yunbao/main/activity/MainActivity.java
index 8f634d496..ec9db6525 100644
--- a/main/src/main/java/com/yunbao/main/activity/MainActivity.java
+++ b/main/src/main/java/com/yunbao/main/activity/MainActivity.java
@@ -1264,12 +1264,11 @@ public class MainActivity extends AbsActivity implements MainAppBarLayoutListene
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLiveFloatEvent(LiveFloatEvent event) {
-
- new Handler().post(() -> LiveFloatView.getInstance()
- .cacheLiveData(event.getmLiveBean(), event.getmLiveType(), event.getmLiveSDK(), event.getmLiveTypeVal())
- .builderFloat(mContext, event.getmLiveBean().getPull(), LiveAudienceActivity.class));
-
-
+ if (event != null && event.getmLiveBean() != null && !TextUtils.isEmpty(event.getmLiveBean().getPull())){
+ new Handler().post(() -> LiveFloatView.getInstance()
+ .cacheLiveData(event.getmLiveBean(), event.getmLiveType(), event.getmLiveSDK(), event.getmLiveTypeVal())
+ .builderFloat(mContext, event.getmLiveBean().getPull(), LiveAudienceActivity.class));
+ }
}
}
diff --git a/main/src/main/java/com/yunbao/main/activity/TestActivity.java b/main/src/main/java/com/yunbao/main/activity/TestActivity.java
index 911447166..d4094b529 100644
--- a/main/src/main/java/com/yunbao/main/activity/TestActivity.java
+++ b/main/src/main/java/com/yunbao/main/activity/TestActivity.java
@@ -6,30 +6,18 @@ import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
-import com.yunbao.common.views.weight.IRecognizedResult;
-import com.yunbao.common.views.weight.Recognizer;
import com.yunbao.main.R;
public class TestActivity extends AppCompatActivity {
private TextView contextLayout;
- private Recognizer recognizer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
contextLayout = findViewById(R.id.context_layout);
- recognizer = findViewById(R.id.recognizer);
SpannableStringBuilder builder = new SpannableStringBuilder();
- recognizer.setCallBack(new IRecognizedResult() {
- @Override
- public void onResult(String data) {
- builder.append(data);
- contextLayout.setText(builder);
- }
-
- });
}
}
\ No newline at end of file
diff --git a/main/src/main/res/layout/activity_test.xml b/main/src/main/res/layout/activity_test.xml
index 558c7c8cc..df80af1e9 100644
--- a/main/src/main/res/layout/activity_test.xml
+++ b/main/src/main/res/layout/activity_test.xml
@@ -12,11 +12,5 @@
android:layout_height="0dp"
android:layout_weight="1" />
-
-
\ No newline at end of file