[Modify]声音签名功能完善

This commit is contained in:
wushaocheng
2023-01-11 15:06:21 +08:00
parent 7a5247a9b5
commit d029d03997
13 changed files with 178 additions and 51 deletions

Binary file not shown.

View File

@@ -23,6 +23,7 @@ import com.yizhuan.erban.ui.webview.CommonWebViewActivity;
import com.yizhuan.xchat_android_core.UriProvider;
import com.yizhuan.xchat_android_core.statistic.StatisticManager;
import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol;
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
import com.yizhuan.xchat_android_library.utils.ResUtil;
@@ -136,9 +137,10 @@ public class UIHelper {
mActivity.startActivityForResult(intent, requestCode);
}
public static void showSoundAct(Activity mActivity, int requestCode, String label) {
public static void showSoundAct(Activity mActivity, int requestCode, String label, UserInfo.SoundBean audioCard) {
StatisticManager.Instance().onEvent(StatisticsProtocol.EVENT_MY_SOUND, ResUtil.getString(R.string.yizhuan_erban_uihelper_03) + label);
Intent intent = new Intent(mActivity, SoundSignatureActivity.class);
intent.putExtra(SoundSignatureActivity.AUDIO_BEAN, audioCard);
mActivity.startActivityForResult(intent, requestCode);
}

View File

@@ -19,7 +19,6 @@ import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.yizhuan.erban.R
import com.yizhuan.erban.audio.helper.AudioPlayerHelper
import com.yizhuan.erban.audio.presenter.RecordingVoicePresenter
import com.yizhuan.erban.audio.viewmodel.SoundViewModel
import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.common.widget.dialog.DialogManager.OkCancelDialogListener
@@ -29,6 +28,7 @@ import com.yizhuan.xchat_android_core.file.FileModel
import com.yizhuan.xchat_android_core.room.model.AvRoomModel
import com.yizhuan.xchat_android_core.statistic.StatisticManager
import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol
import com.yizhuan.xchat_android_core.user.bean.UserInfo.SoundBean
import com.yizhuan.xchat_android_library.utils.ResUtil
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
import io.reactivex.SingleObserver
@@ -43,6 +43,7 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
View.OnClickListener {
companion object {
const val AUDIO_BEAN = "audio_bean"
const val AUDIO_FILE = "AUDIO_FILE"
const val AUDIO_DURA = "AUDIO_DURA"
const val MIN_RECORD_VOICE_DURATION = 1 // 最少1秒
@@ -67,7 +68,39 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
playDrawable = ContextCompat.getDrawable(context, R.drawable.ic_pause_record)
pauseDrawable = ContextCompat.getDrawable(context, R.drawable.ic_resume_record)
refreshButtonView(RecordingVoicePresenter.STATE_RECORD_NORMAL)
val audioCard = intent.getSerializableExtra(AUDIO_BEAN) as SoundBean
when (audioCard.status ?: 0) {
0 -> {
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
}
1 -> {
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SUCCESS
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
refreshButtonView(SoundViewModel.STATE_RECORD_SAVE_SUCCESS)
}
2 -> {
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SUCCESS
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
refreshButtonView(SoundViewModel.STATE_RECORD_AUDIT_SUCCESS)
}
else -> {
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
}
}
}
private fun setListener() {
@@ -136,7 +169,7 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
}
soundViewModel.deleteRecordLiveData.observe(this) {
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
soundViewModel.showNormalState()
}
}
@@ -172,9 +205,10 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
}
}
return
}
}else {
soundViewModel.clickCenterIcon()
}
}
R.id.ivSaveRecord -> {//保存按钮
finishRecord()
}
@@ -271,6 +305,15 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
binding.tvUnderReview.visibility = View.VISIBLE
binding.svgRecorder.stopAnimation()
}
SoundViewModel.STATE_RECORD_AUDIT_SUCCESS -> {
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record) }
binding.tvRecordTip.text = getString(R.string.click_to_listen)
binding.groupRsRecord.visibility = View.VISIBLE
binding.groupSaveSound.visibility = View.INVISIBLE
binding.groupDeleteSound.visibility = View.VISIBLE
binding.tvUnderReview.visibility = View.GONE
binding.svgRecorder.stopAnimation()
}
}
}

View File

@@ -34,9 +34,10 @@ class SoundViewModel : BaseViewModel() {
const val STATE_RECORD_RECORDING = 1//录音中
const val STATE_RECORD_SUCCESS = 2//录音完成
const val STATE_RECORD_SAVE_SUCCESS = 3//保存成功
const val STATE_RECORD_AUDIT_SUCCESS = 4//审核成功
}
private var audioState = STATE_RECORD_NORMAL
var audioState = STATE_RECORD_NORMAL
private var audioManager: AudioPlayAndRecordManager? = null
private var audioRecorder: AudioRecorder? = null
@@ -170,6 +171,9 @@ class SoundViewModel : BaseViewModel() {
*/
fun showNormalState() {
audioState = STATE_RECORD_NORMAL
audioUrl = null
audioDur = 0
audioFile = null
_refreshLiveData.value = audioState
if (null != audioRecorder) {
audioRecorder?.destroyAudioRecorder()
@@ -276,6 +280,30 @@ class SoundViewModel : BaseViewModel() {
}
})
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
}else if(null != audioUrl && audioUrl?.contains("http") == true){
MLog.debug(TAG, "play audioUrl: $audioUrl")
AudioPlayerHelper.get().playInThread(audioUrl, object : OnPlayListener {
override fun onError(error: String) {
_refreshPlayStatusLiveData.value = false // 出错:停止状态(播放按钮)
}
override fun onPrepared() {
_refreshPlayStatusLiveData.value = true// 准备完毕要开始播放:播放状态(暂停按钮)
}
override fun onPlaying(currDuration: Long) {
MLog.debug(
TAG,
"duration = $currDuration"
)
_showCountDownLiveData.value = (currDuration / 1000).toInt()
}
override fun onCompletion() {
_refreshPlayStatusLiveData.value = false// 播放完成:停止状态(播放按钮)
}
})
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
}
}
}

View File

@@ -1,15 +1,15 @@
package com.yizhuan.erban.ui.user;
import static com.yizhuan.erban.ui.user.UserInfoActivity.IdentityState.OWN;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.View;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -31,6 +31,7 @@ import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import com.yizhuan.erban.R;
import com.yizhuan.erban.UIHelper;
import com.yizhuan.erban.audio.SoundSignatureActivity;
import com.yizhuan.erban.audio.helper.AudioPlayerHelper;
import com.yizhuan.erban.audio.helper.OnPlayListener;
import com.yizhuan.erban.avroom.ButtonItemFactory;
@@ -75,13 +76,11 @@ import com.yizhuan.xchat_android_core.user.UserInfoUiMgr;
import com.yizhuan.xchat_android_core.user.UserModel;
import com.yizhuan.xchat_android_core.user.bean.UserDetailInfo;
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
import com.yizhuan.xchat_android_core.user.bean.UserInfoSkillEntity;
import com.yizhuan.xchat_android_core.user.bean.UserPhoto;
import com.yizhuan.xchat_android_core.user.event.LoginUserInfoUpdateEvent;
import com.yizhuan.xchat_android_core.utils.LogUtils;
import com.yizhuan.xchat_android_core.utils.Logger;
import com.yizhuan.xchat_android_core.utils.StarUtils;
import com.yizhuan.xchat_android_core.utils.net.BeanObserver;
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes;
import com.yizhuan.xchat_android_library.utils.ListUtils;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
@@ -94,8 +93,9 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import lombok.val;
import static com.yizhuan.erban.ui.user.UserInfoActivity.IdentityState.OWN;
/**
* create by lvzebiao on 2018/8/31
@@ -340,6 +340,8 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
VipHelper.loadVipIcon(mBinding.ivVipIcon, userInfo.getUserVipInfoVO());
initVoiceShow(userInfo.getAudioCard());
mBinding.tvErbanId.setOnLongClickListener(view -> {
try {
ClipboardManager cm = (ClipboardManager) UserInfoActivity.this.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -607,7 +609,22 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// 获取数据并刷新显示
String audioFileUrl = data.getStringExtra(SoundSignatureActivity.AUDIO_FILE);
int audioDuration = data.getIntExtra(SoundSignatureActivity.AUDIO_DURA, 0);
if (!TextUtils.isEmpty(audioFileUrl) && audioDuration != 0) {
mBinding.llAudio.setVisibility(View.VISIBLE);
String url = "";
if (audioFileUrl.contains("http")) {
url = audioFileUrl;
}
if (TextUtils.isEmpty(url)) return;
if (!audioPlaying) {
playAudio(url, audioDuration);
} else {
stopAudio();
}
}
}
}
@@ -624,36 +641,35 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
}
}
public void initVoiceShow(UserInfoSkillEntity skillEntity) {
if (skillEntity != null) {
public void initVoiceShow(UserInfo.SoundBean audioCard) {
if (audioCard != null && !TextUtils.isEmpty(audioCard.getAudioUrl())) {
mBinding.llAudio.setVisibility(View.VISIBLE);
mBinding.livUser.stop();
mBinding.llAudio.setOnClickListener(v -> toggleAudio(skillEntity.getPropVals()));
mBinding.tvAudio.setText(String.valueOf(audioCard.getSecond()));
mBinding.livUser.stopAnimation();
mBinding.llAudio.setOnClickListener(v -> toggleAudio(audioCard));
} else {
mBinding.llAudio.setVisibility(View.GONE);
}
}
private void toggleAudio(List<String> list) {
if (ListUtils.isListEmpty(list)) return;
private void toggleAudio(UserInfo.SoundBean audioCard) {
String url = "";
for (String s : list) {
if (s.contains("http")) {
url = s;
}
if (audioCard.getAudioUrl().contains("http")) {
url = audioCard.getAudioUrl();
}
if (TextUtils.isEmpty(url)) return;
if (!audioPlaying) {
playAudio(url);
playAudio(url, audioCard.getSecond());
} else {
stopAudio();
}
}
private void playAudio(String url) {
private void playAudio(String url, int second) {
if (audioPlaying) return;
audioPlaying = true;
mBinding.livUser.start();
playSvgaBg(mBinding.livUser, "svga/user_sound_play.svga");
startChronometer(second);
mBinding.ivAudioControl.setImageResource(R.drawable.ic_skill_play);
AudioPlayerHelper.get().playInThread(url, new OnPlayListener() {
@@ -681,10 +697,34 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
});
}
private void startChronometer(int time) {
mBinding.tvAudio.setOnChronometerTickListener(chronometer -> {
long elapsedMillis =
SystemClock.elapsedRealtime() - chronometer.getBase();
int second = (int) (elapsedMillis / 1000);
String showStr = String.format(
Locale.getDefault(),
"%d",
second
);
if (second >= time) {
stopChronometer();// 录制时长超过上限时,停止录制
}
chronometer.setText(showStr);
});
mBinding.tvAudio.setBase(SystemClock.elapsedRealtime());
mBinding.tvAudio.start();
}
private void stopChronometer(){
mBinding.tvAudio.stop();
}
private void stopAudio() {
stopChronometer();
if (!audioPlaying) return;
audioPlaying = false;
mBinding.livUser.stop();
mBinding.livUser.stopAnimation();
mBinding.ivAudioControl.setImageResource(R.drawable.ic_skill_pause);
AudioPlayerHelper.get().endPlay();
}
@@ -701,7 +741,6 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
StatusBarUtil.StatusBarLightMode(this);
}
public interface IdentityState {
int NON = 0; // 无法识别
int OWN = 1; // 自己

View File

@@ -264,7 +264,8 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
UIHelper.showSoundAct(
this@UserInfoModifyActivity,
Method.AUDIO,
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_07)
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_07),
mUserInfo?.audioCard
)
isAvatar = false
}, R.string.ask_again,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

View File

@@ -329,10 +329,10 @@
<LinearLayout
android:id="@+id/ll_audio"
android:layout_width="63dp"
android:layout_height="@dimen/dp_25"
android:layout_gravity="end|center_vertical"
android:background="@drawable/bg_userinfo_skill_audio"
android:layout_width="98dp"
android:layout_height="@dimen/dp_28"
android:layout_marginEnd="@dimen/dp_15"
android:background="@drawable/bg_common_confirm_normal"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone"
@@ -340,21 +340,35 @@
<ImageView
android:id="@+id/iv_audio_control"
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_marginStart="@dimen/dp_8"
android:layout_width="@dimen/dp_18"
android:layout_height="18dp"
android:layout_marginStart="@dimen/dp_4"
android:src="@drawable/ic_skill_pause" />
<com.yizhuan.erban.ui.widget.LivingIconView
<com.opensource.svgaplayer.SVGAImageView
android:id="@+id/liv_user"
android:layout_width="60dp"
android:layout_width="35dp"
android:layout_height="20dp"
android:src="@mipmap/user_sound_play"
android:layout_marginStart="@dimen/dp_4"
app:autoPlay="true"/>
<Chronometer
android:id="@+id/tvAudio"
android:layout_marginStart="@dimen/dp_6"
android:background="@color/transparent"
android:scaleType="fitXY"
app:cus_dp_height="20dp"
app:cus_dp_width="60dp"
app:cus_drawable="@drawable/skill_audio_animation" />
android:format="60"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/sp_14"
tools:text="60" />
<androidx.appcompat.widget.AppCompatTextView
android:text="''"
android:textColor="@color/white"
android:textSize="@dimen/sp_14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

View File

@@ -821,7 +821,7 @@ public class UserInfo implements Serializable {
* 声音签名
*/
@Data
public static class SoundBean {
public static class SoundBean implements Serializable{
private long uid;
private String audioUrl;//音频七牛云url
private Integer second;//时间