语音转文字

This commit is contained in:
18401019693 2022-10-24 18:18:39 +08:00
parent 6b7fd4d53e
commit 7fabc4f1b6
20 changed files with 532 additions and 403 deletions

View File

@ -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;

View File

@ -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 之后调用
*
* <p>注意 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();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -139,6 +139,7 @@ public class LiveAudienceActivity extends LiveActivity {
private int liveBg = 0;
//直播间进入房间队列
private Handler liveHandler = new Handler();
private ImageView voicePress;
@Override
public <T extends View> 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;
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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,7 +265,56 @@ 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;

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="9dp"/>
<solid android:color="#000000"/>
</shape>

View File

@ -9,6 +9,13 @@
android:layout_height="match_parent"
android:overScrollMode="never" />
<ImageView
android:id="@+id/voice_press"
android:layout_width="54dp"
android:layout_height="54dp"
android:visibility="gone"
android:src="@mipmap/icon_voice_press"
android:layout_alignParentBottom="true"
android:layout_marginStart="54dp" />
</RelativeLayout>

View File

@ -245,7 +245,7 @@
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:clickable="false"
android:orientation="horizontal">
<TextView
@ -264,17 +264,24 @@
android:textSize="12sp" />
<LinearLayout
android:id="@+id/voice_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4"
android:gravity="center"
android:background="@drawable/bc_sound_recording_right">
android:background="@drawable/bc_sound_recording_right"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_gravity="center"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:src="@mipmap/icon_voice"
android:visibility="visible" />
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="309dp"
android:layout_height="44dp"
android:background="@drawable/bg_voice_chat">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:text="@string/more_than"
android:textColor="@color/white"
android:textSize="14sp" />
</RelativeLayout>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="270dp"
android:layout_height="170dp"
android:background="@drawable/bg_voice_chat">
<ImageView
android:id="@+id/icon_withdraw"
android:layout_width="38dp"
android:layout_height="31dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:src="@mipmap/icon_withdraw" />
<ImageView
android:id="@+id/voice_fluctuations"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:scaleType="fitCenter"
android:src="@mipmap/img_p" />
<pl.droidsonroids.gif.GifImageView
android:id="@+id/gif_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:background="@mipmap/voice_fluctuations"
android:visibility="gone" />
<TextView
android:id="@+id/fingers_slide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="@string/fingers_slide"
android:textColor="#9A9A9A" />
<TextView
android:id="@+id/voice_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginStart="8dp"
android:layout_marginTop="55dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:maxLines="4"
android:textColor="#FFFFFF"
android:textSize="14sp" />
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -21,4 +21,7 @@
<string name="live_gift_buy_gold" translatable="false">開通貴族</string>
<string name="live_gift_buy_gold_desc" translatable="false">享受專屬特權!</string>
<string name="live_gift_buy_gold_desc_to" translatable="false">前往貴族中心</string>
<string name="fingers_slide" translatable="false">手指上滑,取消發送</string>
<string name="release_cancel_send" translatable="false">松開取消發送</string>
<string name="more_than" translatable="false">已超过10秒未识别到录音</string>
</resources>

View File

@ -1264,12 +1264,11 @@ public class MainActivity extends AbsActivity implements MainAppBarLayoutListene
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLiveFloatEvent(LiveFloatEvent event) {
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));
}
}
}

View File

@ -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);
}
});
}
}

View File

@ -12,11 +12,5 @@
android:layout_height="0dp"
android:layout_weight="1" />
<com.yunbao.common.views.weight.Recognizer
android:id="@+id/recognizer"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center" />
</LinearLayout>