|
@@ -0,0 +1,1267 @@
|
|
|
+package com.cooleshow.teacher.ui.live;
|
|
|
+
|
|
|
+import android.Manifest;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.DialogInterface;
|
|
|
+import android.content.Intent;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.Handler;
|
|
|
+import android.os.Looper;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.util.Log;
|
|
|
+import android.view.KeyEvent;
|
|
|
+import android.view.View;
|
|
|
+import android.view.WindowManager;
|
|
|
+import android.widget.FrameLayout;
|
|
|
+import android.widget.ImageView;
|
|
|
+import android.widget.RelativeLayout;
|
|
|
+import android.widget.TextView;
|
|
|
+
|
|
|
+import com.alibaba.android.arouter.facade.annotation.Route;
|
|
|
+import com.bumptech.glide.Glide;
|
|
|
+import com.cooleshow.base.common.BaseApplication;
|
|
|
+import com.cooleshow.base.data.net.ApiException;
|
|
|
+import com.cooleshow.base.router.RouterPath;
|
|
|
+import com.cooleshow.base.ui.activity.BaseMVPActivity;
|
|
|
+import com.cooleshow.base.utils.AppUtils;
|
|
|
+import com.cooleshow.base.utils.ClickUtils;
|
|
|
+import com.cooleshow.base.utils.PermissionUtils;
|
|
|
+import com.cooleshow.base.utils.SoftKeyboardUtil;
|
|
|
+import com.cooleshow.base.utils.ToastUtil;
|
|
|
+import com.cooleshow.base.utils.Utils;
|
|
|
+import com.cooleshow.base.widgets.InputBar;
|
|
|
+import com.cooleshow.base.widgets.dialog.CommonConfirmDialog;
|
|
|
+import com.cooleshow.base.widgets.dialog.InputBarDialog;
|
|
|
+import com.cooleshow.teacher.R;
|
|
|
+import com.cooleshow.teacher.adapter.LiveRoomMessageAdapter;
|
|
|
+import com.cooleshow.teacher.bean.LiveRoomInfoBean;
|
|
|
+import com.cooleshow.teacher.contract.LiveRoomContract;
|
|
|
+import com.cooleshow.teacher.databinding.ActivityTeacherLiveRoomLayoutBinding;
|
|
|
+import com.cooleshow.teacher.helper.LiveRoomAnimatorHelper;
|
|
|
+import com.cooleshow.teacher.presenter.live.LiveRoomPresenter;
|
|
|
+import com.cooleshow.teacher.widgets.dialog.LiveBeautyOptionsDialog;
|
|
|
+import com.cooleshow.teacher.widgets.dialog.LiveMicManagerDialog;
|
|
|
+import com.cooleshow.teacher.widgets.dialog.LiveRoomManagerDialog;
|
|
|
+import com.cooleshow.teacher.widgets.helper.VideoViewManager;
|
|
|
+import com.cooleshow.usercenter.helper.UserHelper;
|
|
|
+import com.daya.live_teaching.utils.ToastUtils;
|
|
|
+import com.gyf.immersionbar.ImmersionBar;
|
|
|
+import com.rong.io.live.LiveRoomMsgConstants;
|
|
|
+import com.rong.io.live.bean.User;
|
|
|
+import com.rong.io.live.config.LiveConfig;
|
|
|
+import com.rong.io.live.helper.LiveEventHelper;
|
|
|
+import com.rong.io.live.helper.LiveMemberHelper;
|
|
|
+import com.rong.io.live.helper.LiveMessageHelper;
|
|
|
+import com.rong.io.live.helper.LiveRTCEngineInitHelper;
|
|
|
+import com.rong.io.live.helper.LiveRoomMicMemberHelper;
|
|
|
+import com.rong.io.live.message.RCChatJoinRoomMessage;
|
|
|
+import com.rong.io.live.message.RCOnSnappingUpMessage;
|
|
|
+import com.rong.io.live.message.RCUserAddLikeMessage;
|
|
|
+import com.rong.io.live.message.RCUserSeatApplyMessage;
|
|
|
+import com.tbruyelle.rxpermissions3.RxPermissions;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import androidx.annotation.NonNull;
|
|
|
+import androidx.constraintlayout.widget.ConstraintLayout;
|
|
|
+import androidx.recyclerview.widget.LinearLayoutManager;
|
|
|
+import androidx.recyclerview.widget.RecyclerView;
|
|
|
+import cn.rongcloud.rtc.api.RCRTCAudioRouteManager;
|
|
|
+import cn.rongcloud.rtc.api.RCRTCEngine;
|
|
|
+import cn.rongcloud.rtc.api.RCRTCRemoteUser;
|
|
|
+import cn.rongcloud.rtc.api.RCRTCVideoStream;
|
|
|
+import cn.rongcloud.rtc.api.callback.IRCRTCStatusReportListener;
|
|
|
+import cn.rongcloud.rtc.api.report.StatusBean;
|
|
|
+import cn.rongcloud.rtc.api.report.StatusReport;
|
|
|
+import cn.rongcloud.rtc.api.stream.RCRTCAudioInputStream;
|
|
|
+import cn.rongcloud.rtc.api.stream.RCRTCVideoInputStream;
|
|
|
+import cn.rongcloud.rtc.api.stream.RCRTCVideoOutputStream;
|
|
|
+import cn.rongcloud.rtc.api.stream.RCRTCVideoView;
|
|
|
+import cn.rongcloud.rtc.base.RCRTCLiveRole;
|
|
|
+import cn.rongcloud.rtc.base.RCRTCMediaType;
|
|
|
+import cn.rongcloud.rtc.base.RCRTCResourceState;
|
|
|
+import io.reactivex.rxjava3.disposables.Disposable;
|
|
|
+import io.rong.imkit.IMCenter;
|
|
|
+import io.rong.imkit.picture.tools.DoubleUtils;
|
|
|
+import io.rong.imlib.IRongCoreCallback;
|
|
|
+import io.rong.imlib.IRongCoreEnum;
|
|
|
+import io.rong.imlib.RongIMClient;
|
|
|
+import io.rong.imlib.model.Message;
|
|
|
+import io.rong.imlib.model.MessageContent;
|
|
|
+import io.rong.imlib.model.UserInfo;
|
|
|
+import io.rong.message.TextMessage;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Author by pq, Date on 2022/6/5.
|
|
|
+ * 老师端直播间页面
|
|
|
+ */
|
|
|
+@Route(path = RouterPath.LiveCenter.ACTIVITY_LIVE_ROOM_TEACHER)
|
|
|
+public class TeacherLiveRoomActivity extends BaseMVPActivity<ActivityTeacherLiveRoomLayoutBinding, LiveRoomPresenter> implements LiveRoomContract.LiveRoomView, View.OnClickListener, SoftKeyboardUtil.OnSoftInputChangedListener {
|
|
|
+ public static final String ROOMID_KEY = "roomid_key";
|
|
|
+ public static final int SYNC_ADD_LIKE_TIME = 10000;//同步点赞数时长(兼心跳功能)
|
|
|
+ public static final int SEND_APP_BACKGROUND_MSG = 1001;//退到后台消息
|
|
|
+
|
|
|
+
|
|
|
+ ImageView ivReverseCamera;
|
|
|
+ ImageView ivLiveBeauty;
|
|
|
+ ImageView ivLiveShare;
|
|
|
+ TextView tvStartLive;
|
|
|
+ TextView tvClose;
|
|
|
+ ImageView mIvAvatar;
|
|
|
+ TextView mTvRoomCreateName;
|
|
|
+ TextView mTvNumPeople;
|
|
|
+ RelativeLayout flLiveView;
|
|
|
+ RecyclerView recyclerMsg;
|
|
|
+ FrameLayout mFlCreateOptions;
|
|
|
+ ConstraintLayout mCsMainLayout;
|
|
|
+ TextView mTvOnMicNumTip;
|
|
|
+ TextView mTvAddLikeCount;
|
|
|
+ TextView mTvLiveDelay;
|
|
|
+ ImageView mIvLiveDelay;
|
|
|
+ FrameLayout mFlJoinBarrage;
|
|
|
+ TextView mTvJoinBarrage;
|
|
|
+ FrameLayout mFlSnapUpBarrage;
|
|
|
+ TextView mTvSnapUpBarrage;
|
|
|
+
|
|
|
+ public String mRoomId = "";
|
|
|
+ private VideoViewManager mVideoViewManager;
|
|
|
+ private int currentAddLikeCount = 0;//当前点赞数量
|
|
|
+ private boolean isNeedRefresh = false;//是否需要重新刷新房间信息
|
|
|
+ private LiveRoomInfoBean mRoomInfoBean;
|
|
|
+ private String mUserId;
|
|
|
+ private InputBarDialog mInputBarDialog;
|
|
|
+ private int currentLiveMode = LiveConfig.LIVE_MODE_PREVIEW;//默认是预览模式
|
|
|
+ private int currentLiveStatus = LiveConfig.LIVE_STATUS_NORMAL;
|
|
|
+ private RongIMClient.ConnectionStatusListener connectStatusListener = new RongIMClient.ConnectionStatusListener() {
|
|
|
+ @Override
|
|
|
+ public void onChanged(ConnectionStatus status) {
|
|
|
+ Log.i("pq", "LiveRoomActivity receive ConnectionStatus:" + status);
|
|
|
+ if (status == ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT
|
|
|
+ || status == ConnectionStatus.SIGN_OUT || status == ConnectionStatus.TIMEOUT) {
|
|
|
+ finish();
|
|
|
+ }
|
|
|
+ if (status == ConnectionStatus.CONNECTED) {
|
|
|
+ //IM连接成功
|
|
|
+ if (presenter != null && isNeedRefresh) {
|
|
|
+ isNeedRefresh = false;
|
|
|
+ presenter.init(mRoomId, true);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //其他状态的时候需要重新刷新房间信息
|
|
|
+ isNeedRefresh = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private Runnable mRunnable = new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ //10S更新一次当前UI,通知服务端点赞数量
|
|
|
+ Log.i("pq", "sync add like:" + currentAddLikeCount);
|
|
|
+ updateAddLikeCountView();
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.syncAddLikeNum(String.valueOf(currentAddLikeCount), mRoomId);
|
|
|
+ presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_ADD_LIKE_COUNT, currentAddLikeCount);
|
|
|
+ }
|
|
|
+ syncAddLikeNum();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ private LiveRoomMessageAdapter mMessageAdapter;
|
|
|
+ private LinearLayoutManager mLinearLayoutManager;
|
|
|
+ private LiveBeautyOptionsDialog mOptionsDialog;
|
|
|
+ private LiveRoomMicMemberHelper mRoomMicMemberHelper;
|
|
|
+ private LiveMicManagerDialog mLiveMicManagerDialog;
|
|
|
+
|
|
|
+ private Handler mHandler = new Handler(Looper.myLooper()) {
|
|
|
+ @Override
|
|
|
+ public void handleMessage(@NonNull android.os.Message msg) {
|
|
|
+ int what = msg.what;
|
|
|
+ if (what == SEND_APP_BACKGROUND_MSG) {
|
|
|
+ if (!isOnResume && AppUtils.isApplicationInBackground(TeacherLiveRoomActivity.this)) {
|
|
|
+ Log.i("pq", "onPause publish");
|
|
|
+ pauseLive();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private LiveRoomManagerDialog mRoomManagerDialog;
|
|
|
+ private CommonConfirmDialog mConfirmDialog;
|
|
|
+ private boolean isOnResume = false;
|
|
|
+
|
|
|
+ public static void start(Context context, String roomId) {
|
|
|
+ Intent intent = new Intent(context, TeacherLiveRoomActivity.class);
|
|
|
+ intent.putExtra(ROOMID_KEY, roomId);
|
|
|
+ context.startActivity(intent);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onCreate(Bundle savedInstanceState) {
|
|
|
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void initView() {
|
|
|
+ setStatusBarColor();
|
|
|
+ ivReverseCamera = viewBinding.viewCreateOptions.ivReverseCamera;
|
|
|
+ ivLiveBeauty = viewBinding.viewCreateOptions.ivLiveBeauty;
|
|
|
+ ivLiveShare = viewBinding.viewCreateOptions.ivLiveShare;
|
|
|
+ tvStartLive = viewBinding.viewCreateOptions.tvStartLive;
|
|
|
+ tvClose = viewBinding.viewCreateOptions.tvClose;
|
|
|
+ mIvAvatar = viewBinding.viewMainLayout.ivAvatar;
|
|
|
+ mTvRoomCreateName = viewBinding.viewMainLayout.tvRoomAuthorName;
|
|
|
+ mTvNumPeople = viewBinding.viewMainLayout.tvNumPeople;
|
|
|
+ flLiveView = viewBinding.flLiveView;
|
|
|
+ recyclerMsg = viewBinding.viewMainLayout.recyclerMsg;
|
|
|
+ mFlCreateOptions = viewBinding.viewCreateOptions.getRoot();
|
|
|
+ mCsMainLayout = viewBinding.viewMainLayout.getRoot();
|
|
|
+ mTvOnMicNumTip = viewBinding.viewMainLayout.tvOnMicNumTip;
|
|
|
+ mTvAddLikeCount = viewBinding.viewMainLayout.tvAddLikeCount;
|
|
|
+ mTvLiveDelay = viewBinding.viewMainLayout.tvLiveDelay;
|
|
|
+ mIvLiveDelay = viewBinding.viewMainLayout.ivLiveDelay;
|
|
|
+ mFlJoinBarrage = viewBinding.viewMainLayout.flJoinBarrage;
|
|
|
+ mTvJoinBarrage = viewBinding.viewMainLayout.tvJoinBarrage;
|
|
|
+ mFlSnapUpBarrage = viewBinding.viewMainLayout.flSnapUpBarrage;
|
|
|
+ mTvSnapUpBarrage = viewBinding.viewMainLayout.tvSnapUpBarrage;
|
|
|
+ ivReverseCamera.setOnClickListener(this);
|
|
|
+ ivLiveBeauty.setOnClickListener(this);
|
|
|
+ tvStartLive.setOnClickListener(this);
|
|
|
+ tvClose.setOnClickListener(this);
|
|
|
+ viewBinding.viewMainLayout.tvInput.setOnClickListener(this);
|
|
|
+ viewBinding.viewMainLayout.ivMic.setOnClickListener(this);
|
|
|
+ viewBinding.viewMainLayout.iconFinishLive.setOnClickListener(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected ActivityTeacherLiveRoomLayoutBinding getLayoutView() {
|
|
|
+ return ActivityTeacherLiveRoomLayoutBinding.inflate(getLayoutInflater());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setStatusBarColor() {
|
|
|
+ ImmersionBar.with(this)
|
|
|
+ .keyboardEnable(false)//为了防止软键盘顶起底部布局
|
|
|
+ .transparentStatusBar()
|
|
|
+ .statusBarDarkFont(false, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
|
|
|
+ .autoDarkModeEnable(false)
|
|
|
+ .flymeOSStatusBarFontColor(R.color.white) //修改flyme OS状态栏字体颜色
|
|
|
+ .init(); //必须调用方可沉浸
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void initData() {
|
|
|
+ super.initData();
|
|
|
+ mRoomId = getIntent().getStringExtra(ROOMID_KEY);
|
|
|
+ if (TextUtils.isEmpty(mRoomId)) {
|
|
|
+ ToastUtil.getInstance().show(this, "房间id不可为空");
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String userToken = UserHelper.getUserToken();
|
|
|
+ if (TextUtils.isEmpty(userToken)) {
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mUserId = UserHelper.getUserId();
|
|
|
+ mHandler.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ checkVideoViewManager();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ mRoomMicMemberHelper = new LiveRoomMicMemberHelper();
|
|
|
+ mMessageAdapter = new LiveRoomMessageAdapter(this);
|
|
|
+ mLinearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
|
|
|
+ recyclerMsg.setLayoutManager(mLinearLayoutManager);
|
|
|
+ recyclerMsg.setAdapter(mMessageAdapter);
|
|
|
+ checkNeedPermission();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initLiveConfig() {
|
|
|
+ initListener();
|
|
|
+ if (LiveConfig.isNeedReInitRTC) {
|
|
|
+ //检查是否需要重新初始化RTC
|
|
|
+ LiveRTCEngineInitHelper.initRTC();
|
|
|
+ }
|
|
|
+ //开启美颜
|
|
|
+ LiveRTCEngineInitHelper.openBeauty();
|
|
|
+ // 初始化音频路由管理类
|
|
|
+ RCRTCAudioRouteManager.getInstance().init(Utils.getApp());
|
|
|
+ prepareInitRoom();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkNeedPermission() {
|
|
|
+ Disposable disposable = new RxPermissions(TeacherLiveRoomActivity.this)
|
|
|
+ .request(Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
|
+ , Manifest.permission.CAMERA)
|
|
|
+ .subscribe(permission -> {
|
|
|
+ if (permission) {
|
|
|
+ initLiveConfig();
|
|
|
+ } else {
|
|
|
+ CommonConfirmDialog confirmDialog = new CommonConfirmDialog(TeacherLiveRoomActivity.this);
|
|
|
+ confirmDialog.show();
|
|
|
+ confirmDialog.setContent("直播需要麦克风、摄像头、储存权限,去设置?");
|
|
|
+ confirmDialog.setConfirmText("去设置");
|
|
|
+ confirmDialog.setOnConfirmClickListener(new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ PermissionUtils.toSelfSetting(TeacherLiveRoomActivity.this);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initListener() {
|
|
|
+ IMCenter.getInstance().addConnectionStatusListener(connectStatusListener);
|
|
|
+ SoftKeyboardUtil.registerSoftInputChangedListener(getWindow(), this);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void bindLiveStatusReport() {
|
|
|
+ //注册通话状态数据监听器 全局监听需要在重新加入房间之后重新设置(重新加入房间,角色属性变更,融云的全局监听都会失效)
|
|
|
+ RCRTCEngine.getInstance().registerStatusReportListener(new IRCRTCStatusReportListener() {
|
|
|
+ @Override
|
|
|
+ public void onConnectionStats(StatusReport statusReport) {
|
|
|
+ super.onConnectionStats(statusReport);
|
|
|
+ long lossRate = 0;
|
|
|
+ for (Map.Entry<String, StatusBean> entry : statusReport.statusVideoSends.entrySet()) {
|
|
|
+ StatusBean statusBean = entry.getValue();
|
|
|
+ //获取userID
|
|
|
+ String userId = statusBean.uid;
|
|
|
+ //获取视频 宽x高@帧率
|
|
|
+ String resolution = statusBean.frameWidth + "x" + statusBean.frameHeight + "@" + statusBean.frameRate;
|
|
|
+ //获取码率
|
|
|
+ long bitRate = statusBean.bitRate;
|
|
|
+ //丢包率:超过30,视频卡顿现象会很明显
|
|
|
+ lossRate = statusBean.packetLostRate;
|
|
|
+ }
|
|
|
+ if (statusReport != null) {
|
|
|
+ int rtt = statusReport.rtt;
|
|
|
+ if (rtt > 999) {
|
|
|
+ rtt = 999;
|
|
|
+ }
|
|
|
+ updateLiveDelayUI(rtt, lossRate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void prepareInitRoom() {
|
|
|
+ //根据融云的IM连接状态判断是否需要获取房间信息
|
|
|
+ RongIMClient.ConnectionStatusListener.ConnectionStatus currentConnectionStatus = RongIMClient.getInstance().getCurrentConnectionStatus();
|
|
|
+ if (currentConnectionStatus == RongIMClient.ConnectionStatusListener.ConnectionStatus.CONNECTED) {
|
|
|
+ isNeedRefresh = false;
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.init(mRoomId, true);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //如果IM未连接,等待connectStatusListener回调
|
|
|
+ isNeedRefresh = true;
|
|
|
+ presenter.connectIM();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 暂停直播
|
|
|
+ */
|
|
|
+ private void pauseLive() {
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_PAUSE_LIVE);
|
|
|
+ currentLiveStatus = LiveConfig.LIVE_STATUS_PAUSE;
|
|
|
+ presenter.cancelPublish(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查VideoViewManager是否未null;
|
|
|
+ */
|
|
|
+ private void checkVideoViewManager() {
|
|
|
+ if (mVideoViewManager == null) {
|
|
|
+ mVideoViewManager = new VideoViewManager(flLiveView, flLiveView.getWidth(), flLiveView.getHeight());
|
|
|
+ mVideoViewManager.setRetryClickListener(new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (presenter != null) {
|
|
|
+ //重新订阅房间的流信息
|
|
|
+// presenter.subscribeAVStream();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected LiveRoomPresenter createPresenter() {
|
|
|
+ return new LiveRoomPresenter();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onResume() {
|
|
|
+ super.onResume();
|
|
|
+ this.isOnResume = true;
|
|
|
+ if (isLiveMode() && isLivePause()) {
|
|
|
+ Log.i("pq", "onResume publish");
|
|
|
+ currentLiveMode = LiveConfig.LIVE_STATUS_NORMAL;
|
|
|
+ presenter.startPublish();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onPause() {
|
|
|
+ super.onPause();
|
|
|
+ this.isOnResume = false;
|
|
|
+ if (isLiveMode()) {
|
|
|
+ //退到后台,延迟2S发送检测消息,
|
|
|
+ android.os.Message obtain = android.os.Message.obtain();
|
|
|
+ obtain.what = SEND_APP_BACKGROUND_MSG;
|
|
|
+ mHandler.sendMessageDelayed(obtain, 2000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取房间信息成功
|
|
|
+ *
|
|
|
+ * @param roomInfoBean
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void getRoomInfoSuccess(LiveRoomInfoBean roomInfoBean) {
|
|
|
+ if (isFinishing() || isDestroyed()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (roomInfoBean == null) {
|
|
|
+ ToastUtils.showToast("获取房间信息失败,请退出重试");
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mRoomInfoBean = roomInfoBean;
|
|
|
+ if (mMessageAdapter != null) {
|
|
|
+ mMessageAdapter.setRoomAuthorId(roomInfoBean.speakerId);
|
|
|
+ }
|
|
|
+ int peopleCount = roomInfoBean.lookNum;
|
|
|
+ mTvNumPeople.setText(peopleCount + "人");
|
|
|
+ //同步点赞数
|
|
|
+ currentAddLikeCount = roomInfoBean.likeNum;
|
|
|
+ updateAddLikeCountView();
|
|
|
+ //创建人头像
|
|
|
+ Glide.with(TeacherLiveRoomActivity.this).load(roomInfoBean.speakerPic).placeholder(R.drawable.icon_teacher_default_head).error(R.drawable.icon_teacher_default_head).into(mIvAvatar);
|
|
|
+ //创建人昵称
|
|
|
+ mTvRoomCreateName.setText(roomInfoBean.speakerName);
|
|
|
+ if (presenter != null) {
|
|
|
+ //配置直播的config配置
|
|
|
+ presenter.initPublishConfig();
|
|
|
+ LiveEventHelper.getInstance().register(roomInfoBean.roomUid);
|
|
|
+ Log.i("pq", "initPublishConfig");
|
|
|
+ Log.i("pq", "isPreviewMode:" + isPreviewMode());
|
|
|
+ if (isPreviewMode()) {
|
|
|
+ openPreViewMode();
|
|
|
+ } else {
|
|
|
+ //加入房间
|
|
|
+ presenter.prepareJoinRoom(roomInfoBean.roomUid, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否是预览模式
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isPreviewMode() {
|
|
|
+ return currentLiveMode == LiveConfig.LIVE_MODE_PREVIEW;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * \
|
|
|
+ * 是否是直播中
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isLiveMode() {
|
|
|
+ return currentLiveMode == LiveConfig.LIVE_MODE_LIVE_START;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 直播暂停状态
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isLivePause() {
|
|
|
+ return currentLiveStatus == LiveConfig.LIVE_STATUS_PAUSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切换直播模式
|
|
|
+ *
|
|
|
+ * @param mode
|
|
|
+ */
|
|
|
+ private void switchLiveMode(int mode) {
|
|
|
+ //切换直播模式
|
|
|
+ currentLiveMode = mode;
|
|
|
+ if (mode == LiveConfig.LIVE_MODE_PREVIEW) {
|
|
|
+ //直播暂停模式,切换成预览模式
|
|
|
+ //通知关闭直播录像
|
|
|
+ switchOpsLiveVideoMode(LiveConfig.CLOSE_OPS_LIVE_VIDEO_TYPE);
|
|
|
+ openPreViewMode();
|
|
|
+ } else {
|
|
|
+ //直播模式
|
|
|
+ presenter.startPublish();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开启预览模式
|
|
|
+ */
|
|
|
+ private void openPreViewMode() {
|
|
|
+ if (presenter != null) {
|
|
|
+ showLoading();
|
|
|
+ switchMainUI();
|
|
|
+ presenter.openVideoPreview();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切换主场景
|
|
|
+ */
|
|
|
+ private void switchMainUI() {
|
|
|
+ if (currentLiveMode == LiveConfig.LIVE_MODE_PREVIEW) {
|
|
|
+ mFlCreateOptions.setVisibility(View.VISIBLE);
|
|
|
+ mCsMainLayout.setVisibility(View.GONE);
|
|
|
+ } else {
|
|
|
+ mFlCreateOptions.setVisibility(View.GONE);
|
|
|
+ mCsMainLayout.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ int id = v.getId();
|
|
|
+ if (id == R.id.tv_close) {
|
|
|
+ finish();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (id == R.id.iv_reverse_camera) {
|
|
|
+ //翻转摄像头
|
|
|
+ presenter.reverseCamera();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (id == R.id.iv_live_beauty) {
|
|
|
+ //美颜
|
|
|
+ showBeautyOptionsDialog();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id == R.id.tv_start_live) {
|
|
|
+ //开始直播
|
|
|
+ if (DoubleUtils.isFastDoubleClick()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (mRoomInfoBean != null) {
|
|
|
+ if (isLivePause()) {
|
|
|
+ //直播暂停模式,恢复直播
|
|
|
+ presenter.startPublish();
|
|
|
+ } else {
|
|
|
+ //预览模式,开启直播
|
|
|
+ //点开启直播之前再次验证一下房间信息
|
|
|
+ currentLiveMode = LiveConfig.LIVE_MODE_LIVE_START;
|
|
|
+ presenter.getRoomInfo(mRoomId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id == R.id.iv_mic) {
|
|
|
+ //连麦管理
|
|
|
+// showMicManagerDialog();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id == R.id.tv_input) {
|
|
|
+ //底部输入框
|
|
|
+ showInputDialog();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id == R.id.icon_finish_live) {
|
|
|
+ //显示直播间管理弹窗
|
|
|
+ showLiveRoomManagerDialog();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步点赞数并且
|
|
|
+ */
|
|
|
+ private void syncAddLikeNum() {
|
|
|
+ if (mHandler != null) {
|
|
|
+ mHandler.removeCallbacks(mRunnable);
|
|
|
+ //10S发送一次同步点赞兼心跳
|
|
|
+ mHandler.postDelayed(mRunnable, SYNC_ADD_LIKE_TIME);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateAddLikeCountView() {
|
|
|
+ if (mTvAddLikeCount != null) {
|
|
|
+ mTvAddLikeCount.setText(getString(R.string.live_room_add_like_count_str, currentAddLikeCount));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void syncMemberCount(String count) {
|
|
|
+ //同步成员数量
|
|
|
+ Log.i("pq", "syncMemberCount" + count);
|
|
|
+ if (isFinishing() || isDestroyed()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (mTvNumPeople != null) {
|
|
|
+ mTvNumPeople.setText(count + "人");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void receiveJoinMessage(RCChatJoinRoomMessage joinRoomMessage) {
|
|
|
+ //收到加入房间消息
|
|
|
+ if (checkActivityIsFinish()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (joinRoomMessage == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isCanShowBarrage()) {
|
|
|
+ mTvJoinBarrage.setText(getString(R.string.enter_live_tip_str, LiveMemberHelper.getMessageName(joinRoomMessage)));
|
|
|
+ showBarrageViewAnim(mFlJoinBarrage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否显示弹幕消息
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isCanShowBarrage() {
|
|
|
+ return mFlJoinBarrage.getVisibility() != View.VISIBLE && mFlSnapUpBarrage.getVisibility() != View.VISIBLE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示弹幕消息
|
|
|
+ */
|
|
|
+ private void showBarrageViewAnim(View targetView) {
|
|
|
+ if (mFlJoinBarrage.getVisibility() == View.VISIBLE || mFlSnapUpBarrage.getVisibility() == View.VISIBLE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ LiveRoomAnimatorHelper.getInstance().startBarrageViewAnimation(this, targetView);
|
|
|
+ hideBarrageView();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 隐藏弹幕消息
|
|
|
+ */
|
|
|
+ private void hideBarrageView() {
|
|
|
+ mHandler.postDelayed(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ if (mFlJoinBarrage != null) {
|
|
|
+ mFlJoinBarrage.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ if (mFlSnapUpBarrage != null) {
|
|
|
+ mFlSnapUpBarrage.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, LiveConfig.LIVE_HIDE_BARRAGE_VIEW_TIME);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void receiveSnapUpMessage(RCOnSnappingUpMessage onSnappingUpMessage) {
|
|
|
+ //收到抢购消息
|
|
|
+ if (checkActivityIsFinish()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (onSnappingUpMessage == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isCanShowBarrage()) {
|
|
|
+ mTvSnapUpBarrage.setText(getString(R.string.live_snap_up_tip_str, LiveMemberHelper.getMessageName(onSnappingUpMessage)));
|
|
|
+ showBarrageViewAnim(mFlSnapUpBarrage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void liveRoomOffline() {
|
|
|
+ if (isFinishing() || isDestroyed()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ToastUtil.getInstance().show(this, "直播已结束");
|
|
|
+ finish();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取房间信息失败
|
|
|
+ *
|
|
|
+ * @param throwable
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void getRoomInfoError(Throwable throwable) {
|
|
|
+ if (isFinishing() || isDestroyed()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (throwable instanceof ApiException) {
|
|
|
+ ApiException apiException = (ApiException) throwable;
|
|
|
+ ToastUtil.getInstance().show(TeacherLiveRoomActivity.this, apiException.getErrmsg());
|
|
|
+ }
|
|
|
+ finish();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void showFinishView() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 观众端发送的点赞消息
|
|
|
+ *
|
|
|
+ * @param addLikeMessage
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void onAddLikeMessage(RCUserAddLikeMessage addLikeMessage) {
|
|
|
+ if (isFinishing() || isDestroyed() || addLikeMessage == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Log.i("pq", "receive addlikeNum:" + addLikeMessage.getCounts());
|
|
|
+ currentAddLikeCount += addLikeMessage.getCounts();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addMessageList(List<MessageContent> messageContents, boolean isReset) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addMessageContent(Message message, boolean isReset) {
|
|
|
+ //添加单条消息至页面
|
|
|
+ Log.i("pq", "收到需要显示msg:" + message);
|
|
|
+ //只处理直播间消息,以及本直播间消息
|
|
|
+ if (mMessageAdapter != null) {
|
|
|
+ mMessageAdapter.addMessage(message);
|
|
|
+ if (mLinearLayoutManager != null) {
|
|
|
+ recyclerMsg.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ if (recyclerMsg != null) {
|
|
|
+ recyclerMsg.scrollToPosition(mMessageAdapter.getItemCount() - 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setRoomData(LiveRoomInfoBean roomInfoBean) {
|
|
|
+ if (presenter != null) {
|
|
|
+ bindLiveStatusReport();
|
|
|
+ startPublish();
|
|
|
+ syncAddLikeNum();
|
|
|
+ //通知加入房间成功
|
|
|
+ presenter.notifyJoinRoomAction(mRoomId, mUserId);
|
|
|
+ //加入聊天房间
|
|
|
+ presenter.joinChartRoom(roomInfoBean.roomUid, new IRongCoreCallback.OperationCallback() {
|
|
|
+ @Override
|
|
|
+ public void onSuccess() {
|
|
|
+ Log.i("pq", "加入聊天房间成功");
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM);
|
|
|
+ presenter.sendDefaultMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(IRongCoreEnum.CoreErrorCode coreErrorCode) {
|
|
|
+ Log.i("pq", "加入聊天房间fail:" + coreErrorCode);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开始推流
|
|
|
+ */
|
|
|
+ private void startPublish() {
|
|
|
+ //切换直播模式
|
|
|
+ currentLiveMode = LiveConfig.LIVE_MODE_LIVE_START;
|
|
|
+ if (isLivePause()) {
|
|
|
+ //直播暂停模式
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.startPublish();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onPublishSuccess() {
|
|
|
+ Log.i("pq", "onPublishSuccess");
|
|
|
+ //通知开启直播间回放
|
|
|
+ switchOpsLiveVideoMode(LiveConfig.OPEN_OPS_LIVE_VIDEO_TYPE);
|
|
|
+ refresh();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public View getContentView() {
|
|
|
+ return flLiveView;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 预览模式
|
|
|
+ *
|
|
|
+ * @param videoView
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void addVideoPreview(RCRTCVideoView videoView) {
|
|
|
+ checkVideoViewManager();
|
|
|
+ if (mVideoViewManager != null) {
|
|
|
+ ArrayList<RCRTCVideoView> videoViews = new ArrayList<>();
|
|
|
+ videoViews.add(videoView);
|
|
|
+ mVideoViewManager.update(videoViews, false);
|
|
|
+ } else {
|
|
|
+ Log.i("pq", "mVideoViewManager == null");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void openCameraSuccess(Boolean data) {
|
|
|
+ hideLoading();
|
|
|
+ Log.i("pq", "openCameraSuccess:" + data);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void openCameraError(String errorMsg) {
|
|
|
+ Log.i("pq", "openCameraError:" + errorMsg);
|
|
|
+ mHandler.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ ToastUtil.getInstance().show(TeacherLiveRoomActivity.this, errorMsg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onUserJoinRoom(RCRTCRemoteUser rcrtcRemoteUser) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onUserLeftRoomMic(RCRTCRemoteUser rcrtcRemoteUser) {
|
|
|
+ if (presenter != null && rcrtcRemoteUser != null) {
|
|
|
+ presenter.unSubscribeStream(rcrtcRemoteUser.getUserId(), null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onUserOfflineRoomMic(RCRTCRemoteUser rcrtcRemoteUser) {
|
|
|
+ if (presenter != null && rcrtcRemoteUser != null) {
|
|
|
+ presenter.unSubscribeStream(rcrtcRemoteUser.getUserId(), null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSwitchRole(String userId, RCRTCLiveRole role) {
|
|
|
+ Log.i("pq", "receive onSwitchRole:" + role.getType());
|
|
|
+ if (role.getType() == RCRTCLiveRole.AUDIENCE.getType()) {
|
|
|
+ //role转换为观众,主播取消订阅该用户的流
|
|
|
+ if (presenter != null) {
|
|
|
+ //取消订阅该成员消息
|
|
|
+ presenter.unSubscribeStream(userId, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSeatApplyMessage(RCUserSeatApplyMessage seatApplyMessage) {
|
|
|
+ //连麦申请消息
|
|
|
+ if (isFinishing() || isDestroyed() || seatApplyMessage == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!isOwn(seatApplyMessage.getTeacherId())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_SEAT_BY_USER) {
|
|
|
+ //观众申请
|
|
|
+ User user = new User();
|
|
|
+ user.setUserName(seatApplyMessage.getAudienceName());
|
|
|
+ user.setUserId(seatApplyMessage.getAudienceId());
|
|
|
+ user.setPortrait(seatApplyMessage.getAudienceAvatar());
|
|
|
+ mRoomMicMemberHelper.addApplyUser(user);
|
|
|
+// updateMicManagerData();
|
|
|
+ }
|
|
|
+ if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_USER) {
|
|
|
+ //观众取消
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateMicManagerData() {
|
|
|
+ if (mLiveMicManagerDialog != null) {
|
|
|
+ mLiveMicManagerDialog.setApplyListData(mRoomMicMemberHelper.getOnApplyMicUsers());
|
|
|
+ }
|
|
|
+ if (mTvOnMicNumTip != null) {
|
|
|
+ ArrayList<User> onApplyMicUsers = mRoomMicMemberHelper.getOnApplyMicUsers();
|
|
|
+ if (onApplyMicUsers != null && onApplyMicUsers.size() > 0) {
|
|
|
+ mTvOnMicNumTip.setVisibility(View.VISIBLE);
|
|
|
+ mTvOnMicNumTip.setText(String.valueOf(onApplyMicUsers.size()));
|
|
|
+ } else {
|
|
|
+ mTvOnMicNumTip.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 用户判断消息目标是否是自己
|
|
|
+ *
|
|
|
+ * @param targetId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isOwn(String targetId) {
|
|
|
+ return TextUtils.equals(targetId, mUserId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void refresh() {
|
|
|
+ List<RCRTCVideoOutputStream> outputStreams = new ArrayList<>();
|
|
|
+ List<RCRTCVideoInputStream> input = new ArrayList<>();
|
|
|
+ List<RCRTCAudioInputStream> audioinputstream = new ArrayList<>();
|
|
|
+ presenter.getVideoStream(outputStreams, input, audioinputstream);
|
|
|
+ updateVideoView(outputStreams, input, audioinputstream);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void updateVideoView(List<RCRTCVideoOutputStream> outputStreams, List<RCRTCVideoInputStream> inputStreams, List<RCRTCAudioInputStream> audioInputStreams) {
|
|
|
+ mHandler.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ currentLiveStatus = LiveConfig.LIVE_STATUS_NORMAL;
|
|
|
+ currentLiveMode = LiveConfig.LIVE_MODE_LIVE_START;
|
|
|
+ switchMainUI();
|
|
|
+ ArrayList<RCRTCVideoStream> videoStreams = new ArrayList<RCRTCVideoStream>();
|
|
|
+ videoStreams.addAll(outputStreams);
|
|
|
+ videoStreams.addAll(inputStreams);
|
|
|
+ ArrayList<RCRTCVideoView> list = new ArrayList<>();
|
|
|
+ ArrayList<String> otherAudioUserIds = new ArrayList<>();
|
|
|
+ boolean isNormalCreateAudioStatus = true;
|
|
|
+
|
|
|
+ //视频流
|
|
|
+ for (int i = 0; i < videoStreams.size(); i++) {
|
|
|
+ RCRTCVideoStream rcrtcVideoStream = videoStreams.get(i);
|
|
|
+ RCRTCVideoView rongRTCVideoView = new RCRTCVideoView(TeacherLiveRoomActivity.this);
|
|
|
+ rcrtcVideoStream.setVideoView(rongRTCVideoView);
|
|
|
+ list.add(rongRTCVideoView);
|
|
|
+ }
|
|
|
+
|
|
|
+ //音频流
|
|
|
+ for (int i = 0; i < audioInputStreams.size(); i++) {
|
|
|
+ RCRTCAudioInputStream audioInputStream = audioInputStreams.get(i);
|
|
|
+ if (audioInputStream.getMediaType() == RCRTCMediaType.AUDIO) {
|
|
|
+ //音频流判断显示上麦用户
|
|
|
+ String userId = audioInputStream.getUserId();
|
|
|
+ if (TextUtils.equals(mUserId, userId)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (mRoomInfoBean != null) {
|
|
|
+ if (!TextUtils.equals(mRoomInfoBean.speakerId, userId)) {
|
|
|
+ otherAudioUserIds.add(userId);
|
|
|
+ } else {
|
|
|
+ //主播的音频流
|
|
|
+ RCRTCResourceState resourceState = audioInputStream.getResourceState();
|
|
|
+ isNormalCreateAudioStatus = resourceState == RCRTCResourceState.NORMAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mVideoViewManager.update(list, true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示通用提示弹窗
|
|
|
+ *
|
|
|
+ * @param content
|
|
|
+ * @param confirmText
|
|
|
+ */
|
|
|
+ private void showCommonTipDialog(String content, String confirmText, View.OnClickListener listener) {
|
|
|
+ if (mConfirmDialog == null) {
|
|
|
+ mConfirmDialog = new CommonConfirmDialog(this);
|
|
|
+ }
|
|
|
+ if (!mConfirmDialog.isShowing()) {
|
|
|
+ mConfirmDialog.show();
|
|
|
+ }
|
|
|
+ mConfirmDialog.setContent(content);
|
|
|
+ mConfirmDialog.setConfirmText(confirmText);
|
|
|
+ mConfirmDialog.setOnConfirmClickListener(listener);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示直播间管理弹窗
|
|
|
+ */
|
|
|
+ private void showLiveRoomManagerDialog() {
|
|
|
+ if (mRoomManagerDialog == null) {
|
|
|
+ mRoomManagerDialog = new LiveRoomManagerDialog(this);
|
|
|
+ mRoomManagerDialog.setOnEventListener(new LiveRoomManagerDialog.OnEventListener() {
|
|
|
+ @Override
|
|
|
+ public void onPauseLive() {
|
|
|
+ //暂停直播
|
|
|
+ showCommonTipDialog(getString(R.string.live_pause_tip_str), getString(R.string.pause_live), new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (mConfirmDialog != null) {
|
|
|
+ mConfirmDialog.dismiss();
|
|
|
+ }
|
|
|
+ if (mRoomManagerDialog != null) {
|
|
|
+ mRoomManagerDialog.dismiss();
|
|
|
+ }
|
|
|
+ pauseLive();
|
|
|
+ switchLiveMode(LiveConfig.LIVE_MODE_PREVIEW);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFinishLive() {
|
|
|
+ //结束直播
|
|
|
+ showCommonTipDialog(getString(R.string.finish_live_tip_str), getString(R.string.live_finish_str), new View.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.notifyCloseLiveRoomAction(mRoomId);
|
|
|
+ }
|
|
|
+ finish();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!mRoomManagerDialog.isShowing()) {
|
|
|
+ mRoomManagerDialog.show();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示连麦控制弹窗
|
|
|
+ */
|
|
|
+ private void showMicManagerDialog() {
|
|
|
+ if (mLiveMicManagerDialog == null) {
|
|
|
+ mLiveMicManagerDialog = new LiveMicManagerDialog(this);
|
|
|
+ mLiveMicManagerDialog.setOnEventListener(new LiveMicManagerDialog.OnEventListener() {
|
|
|
+ @Override
|
|
|
+ public void onAgreeApply(User user) {
|
|
|
+ //同意连麦申请
|
|
|
+ presenter.handleAction(LiveRoomMsgConstants.ACTION_AGREE_MIC_APPLY, user);
|
|
|
+ if (mRoomMicMemberHelper != null) {
|
|
|
+ mRoomMicMemberHelper.delApplyUser(user);
|
|
|
+ }
|
|
|
+ updateMicManagerData();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onRefuseAllMicApply() {
|
|
|
+ if (mRoomMicMemberHelper != null) {
|
|
|
+ mRoomMicMemberHelper.delAllApplyUser();
|
|
|
+ }
|
|
|
+ updateMicManagerData();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSwitchMicMode(boolean isEnable) {
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!mLiveMicManagerDialog.isShowing()) {
|
|
|
+ mLiveMicManagerDialog.show();
|
|
|
+ }
|
|
|
+ mLiveMicManagerDialog.setApplyListData(mRoomMicMemberHelper.getOnApplyMicUsers());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showBeautyOptionsDialog() {
|
|
|
+ if (mOptionsDialog == null) {
|
|
|
+ mOptionsDialog = new LiveBeautyOptionsDialog(this);
|
|
|
+ mOptionsDialog.setFragmentActivity(this);
|
|
|
+ mOptionsDialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
|
|
+ @Override
|
|
|
+ public void onShow(DialogInterface dialog) {
|
|
|
+ mFlCreateOptions.setVisibility(View.GONE);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ mOptionsDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
|
|
+ @Override
|
|
|
+ public void onDismiss(DialogInterface dialog) {
|
|
|
+ mFlCreateOptions.setVisibility(View.VISIBLE);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!mOptionsDialog.isShowing()) {
|
|
|
+ mOptionsDialog.show();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showInputDialog() {
|
|
|
+ if (mRoomInfoBean == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (mInputBarDialog == null) {
|
|
|
+ mInputBarDialog = new InputBarDialog(TeacherLiveRoomActivity.this, new InputBar.InputBarListener() {
|
|
|
+ @Override
|
|
|
+ public boolean onClickSend(String message) {
|
|
|
+ //发送消息
|
|
|
+ if (TextUtils.isEmpty(message)) {
|
|
|
+ ToastUtil.getInstance().show(TeacherLiveRoomActivity.this, "消息不能为空");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (message.length() > LiveConfig.LIVE_MAX_INPUT_TEXT_LENGTH) {
|
|
|
+ ToastUtil.getInstance().show(TeacherLiveRoomActivity.this, "聊天消息需在40个字以内哦");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (LiveMessageHelper.isQuickAction()) {
|
|
|
+ ToastUtil.getInstance().show(TeacherLiveRoomActivity.this, "您说话太快啦");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ sendTextMessage(message);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean onClickEmoji() {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ mInputBarDialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
|
|
+ @Override
|
|
|
+ public void onShow(DialogInterface dialog) {
|
|
|
+ if (mInputBarDialog != null) {
|
|
|
+ mInputBarDialog.showInput();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!mInputBarDialog.isShowing()) {
|
|
|
+ mInputBarDialog.show();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendTextMessage(String message) {
|
|
|
+ if (presenter != null) {
|
|
|
+ TextMessage textMessage = TextMessage.obtain(message);
|
|
|
+ UserInfo userInfo = new UserInfo(mUserId, UserHelper.getUserName(), null);
|
|
|
+ textMessage.setUserInfo(userInfo);
|
|
|
+ presenter.sendMessage(textMessage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateLiveDelayUI(int delay, long lossRate) {
|
|
|
+ if (mHandler != null) {
|
|
|
+ mHandler.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ if (mTvLiveDelay == null || mIvLiveDelay == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (lossRate == 100) {
|
|
|
+ mTvLiveDelay.setText(getString(R.string.net_error_tip));
|
|
|
+ mIvLiveDelay.setImageResource(R.drawable.icon_live_delay_high);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mTvLiveDelay.setText(getString(R.string.live_delay_text, delay));
|
|
|
+ if (delay <= LiveConfig.LIVE_DELAY_NORMAL) {
|
|
|
+ //正常延迟模式
|
|
|
+ mIvLiveDelay.setImageResource(R.drawable.icon_live_delay_normal);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (delay <= LiveConfig.LIVE_DELAY_MIDDLE) {
|
|
|
+ //一般延迟模式
|
|
|
+ mIvLiveDelay.setImageResource(R.drawable.icon_live_delay_middle);
|
|
|
+ } else {
|
|
|
+ //一般延迟模式
|
|
|
+ mIvLiveDelay.setImageResource(R.drawable.icon_live_delay_high);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDestroy() {
|
|
|
+ if (presenter != null) {
|
|
|
+ presenter.notifyLeaveRoomAction();
|
|
|
+ }
|
|
|
+ switchOpsLiveVideoMode(LiveConfig.CLOSE_OPS_LIVE_VIDEO_TYPE);
|
|
|
+ super.onDestroy();
|
|
|
+ if (mVideoViewManager != null) {
|
|
|
+ mVideoViewManager.onRelease();
|
|
|
+ }
|
|
|
+ if (mHandler != null) {
|
|
|
+ mHandler.removeCallbacksAndMessages(null);
|
|
|
+ }
|
|
|
+ if (connectStatusListener != null) {
|
|
|
+ IMCenter.getInstance().removeConnectionStatusListener(connectStatusListener);
|
|
|
+ }
|
|
|
+ SoftKeyboardUtil.unregisterSoftInputChangedListener(getWindow());
|
|
|
+ LiveEventHelper.getInstance().unRegister();
|
|
|
+ RCRTCAudioRouteManager.getInstance().unInit();
|
|
|
+ //取消注册通话状态数据监听器
|
|
|
+ RCRTCEngine.getInstance().unregisterStatusReportListener();
|
|
|
+ LiveRoomAnimatorHelper.getInstance().releaseAnimator();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通知(开启/关闭)直播录像
|
|
|
+ *
|
|
|
+ * @param type
|
|
|
+ */
|
|
|
+ private void switchOpsLiveVideoMode(String type) {
|
|
|
+ //酷乐秀暂时先不需要这个流程,暂时先注释掉,后续考虑优化去掉
|
|
|
+// if (presenter != null) {
|
|
|
+// presenter.notifyOpenOpsLiveVideoAction(mRoomId, type, mUserId);
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
|
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return super.onKeyDown(keyCode, event);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSoftInputChanged(int height) {
|
|
|
+ Log.i("pq", "height" + height);
|
|
|
+ if (height == 0) {
|
|
|
+ //软键盘隐藏
|
|
|
+ Log.i("pq", "SoftInput hide");
|
|
|
+ if (mInputBarDialog != null && mInputBarDialog.isShowing()) {
|
|
|
+ mInputBarDialog.dismiss();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //软键盘弹出
|
|
|
+ Log.i("pq", "SoftInput show");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean checkActivityIsFinish() {
|
|
|
+ if (isFinishing() || isDestroyed()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onPointerCaptureChanged(boolean hasCapture) {
|
|
|
+ super.onPointerCaptureChanged(hasCapture);
|
|
|
+ }
|
|
|
+}
|