TCStudentLiveRoomActivity.java 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386
  1. package com.daya.tclive.ui;
  2. import android.Manifest;
  3. import android.animation.ObjectAnimator;
  4. import android.annotation.SuppressLint;
  5. import android.content.ComponentName;
  6. import android.content.Context;
  7. import android.content.DialogInterface;
  8. import android.content.Intent;
  9. import android.content.ServiceConnection;
  10. import android.content.pm.ActivityInfo;
  11. import android.content.res.Configuration;
  12. import android.graphics.Canvas;
  13. import android.graphics.Color;
  14. import android.net.Uri;
  15. import android.os.Bundle;
  16. import android.os.Handler;
  17. import android.os.IBinder;
  18. import android.os.Looper;
  19. import android.provider.Settings;
  20. import android.text.TextUtils;
  21. import android.util.Log;
  22. import android.view.View;
  23. import android.view.WindowManager;
  24. import android.widget.FrameLayout;
  25. import android.widget.ImageView;
  26. import android.widget.TextView;
  27. import com.airbnb.lottie.LottieAnimationView;
  28. import com.alibaba.android.arouter.facade.annotation.Route;
  29. import com.alibaba.android.arouter.launcher.ARouter;
  30. import com.bumptech.glide.Glide;
  31. import com.cooleshow.base.common.WebConstants;
  32. import com.cooleshow.base.router.RouterPath;
  33. import com.cooleshow.base.ui.activity.BaseMVPActivity;
  34. import com.cooleshow.base.utils.AppUtils;
  35. import com.cooleshow.base.utils.GsonUtils;
  36. import com.cooleshow.base.utils.LOG;
  37. import com.cooleshow.base.utils.PermissionUtils;
  38. import com.cooleshow.base.utils.SoftKeyboardUtil;
  39. import com.cooleshow.base.utils.ToastUtil;
  40. import com.cooleshow.base.utils.UiUtils;
  41. import com.cooleshow.base.widgets.DensityUtil;
  42. import com.cooleshow.base.widgets.DialogUtil;
  43. import com.cooleshow.base.widgets.InputBar;
  44. import com.cooleshow.base.widgets.dialog.CommonConfirmDialog;
  45. import com.cooleshow.base.widgets.dialog.InputBarDialog;
  46. import com.cooleshow.usercenter.helper.UserHelper;
  47. import com.daya.tclive.R;
  48. import com.daya.tclive.adapter.TTMessageAdapter;
  49. import com.daya.tclive.bean.FriendInfoBean;
  50. import com.daya.tclive.bean.LiveRoomInfoBean;
  51. import com.daya.tclive.bean.LiveStatusSEMIMsg;
  52. import com.daya.tclive.bean.SendUserInfo;
  53. import com.daya.tclive.bean.TTMessage;
  54. import com.daya.tclive.bean.TTUserInfo;
  55. import com.daya.tclive.constants.ARouterConstace;
  56. import com.daya.tclive.constants.LiveRoomMsgConstants;
  57. import com.daya.tclive.constants.TTLiveConfig;
  58. import com.daya.tclive.contract.TTLiveRoomContract;
  59. import com.daya.tclive.databinding.AcTtLiveroomLayoutBinding;
  60. import com.daya.tclive.helper.LiveMemberHelper;
  61. import com.daya.tclive.helper.LiveMessageHelper;
  62. import com.daya.tclive.helper.LiveRoomAddLikeHelper;
  63. import com.daya.tclive.helper.LiveRoomAnimatorHelper;
  64. import com.daya.tclive.helper.TTLiveHelper;
  65. import com.daya.tclive.manager.TCIMSdkManager;
  66. import com.daya.tclive.manager.TRTCSdkManager;
  67. import com.daya.tclive.message.TCKickOutUserMessage;
  68. import com.daya.tclive.message.TCLiveForceKickMessage;
  69. import com.daya.tclive.message.TCSyncAddLikeMessage;
  70. import com.daya.tclive.message.TCUserEnterMessage;
  71. import com.daya.tclive.message.TCUserLogOutUnNormalMessage;
  72. import com.daya.tclive.message.TCUserSeatApplyMessage;
  73. import com.daya.tclive.message.TCUserSeatResponseMessage;
  74. import com.daya.tclive.message.TCUserSnappingUpMessage;
  75. import com.daya.tclive.presenter.TTLiveRoomPresenter;
  76. import com.daya.tclive.ui.floatPop.FloatWindowHelper;
  77. import com.daya.tclive.ui.floatPop.FloatingWindowService;
  78. import com.daya.tclive.widget.TTLiveRoomMicIconView;
  79. import com.daya.tclive.widget.dialog.LiveRoomCloseMicTipDialog;
  80. import com.daya.tclive.widget.dialog.LiveRoomClosePageOnMicTipDialog;
  81. import com.daya.tclive.widget.dialog.LiveRoomExitTipDialog2;
  82. import com.daya.tclive.widget.dialog.LiveRoomInviteSeatMicTipDialog;
  83. import com.daya.tclive.widget.dialog.LiveRoomMicManagerDialog;
  84. import com.daya.tclive.widget.dialog.LiveRoomShopCarDialog;
  85. import com.daya.tclive.widget.dialog.OpenOverlayPermissionTipDialog;
  86. import com.gyf.immersionbar.ImmersionBar;
  87. import com.tbruyelle.rxpermissions3.RxPermissions;
  88. import com.tencent.imsdk.v2.V2TIMManager;
  89. import com.tencent.imsdk.v2.V2TIMSDKListener;
  90. import com.tencent.imsdk.v2.V2TIMUserFullInfo;
  91. import com.tencent.imsdk.v2.V2TIMUserStatus;
  92. import com.tencent.live2.V2TXLiveDef;
  93. import com.tencent.live2.V2TXLivePlayer;
  94. import com.tencent.live2.V2TXLivePlayerObserver;
  95. import com.tencent.live2.impl.V2TXLivePlayerImpl;
  96. import com.tencent.rtmp.ui.TXCloudVideoView;
  97. import com.tencent.trtc.TRTCStatistics;
  98. import org.json.JSONException;
  99. import org.json.JSONObject;
  100. import java.util.ArrayList;
  101. import java.util.List;
  102. import java.util.Locale;
  103. import java.util.Map;
  104. import androidx.annotation.NonNull;
  105. import androidx.constraintlayout.widget.ConstraintLayout;
  106. import androidx.constraintlayout.widget.ConstraintSet;
  107. import androidx.constraintlayout.widget.Group;
  108. import androidx.recyclerview.widget.LinearLayoutManager;
  109. import androidx.recyclerview.widget.RecyclerView;
  110. import static com.tencent.live2.V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0;
  111. /**
  112. * Author by pq, Date on 2023/2/22.
  113. */
  114. @Route(path = ARouterConstace.ACTIVITY_TT_LIVE_ROOM)
  115. public class TCStudentLiveRoomActivity extends BaseMVPActivity<AcTtLiveroomLayoutBinding, TTLiveRoomPresenter> implements TTLiveRoomContract.View, View.OnClickListener, SoftKeyboardUtil.OnSoftInputChangedListener {
  116. public static final String TAG = "TTLiveRoomActivity";
  117. ConstraintLayout content_view;
  118. TXCloudVideoView mVideoView;
  119. FrameLayout flVideoContainer;
  120. ConstraintLayout csVideoContainer;
  121. Group mGroupViews;
  122. FrameLayout mFlJoinBarrage;
  123. ImageView mIvClose;
  124. FrameLayout mFlSnapUpBarrage;
  125. ImageView mIvSwitchVideoOrientation;
  126. ImageView mIvSwitchVideoOrientationFull;
  127. ConstraintLayout cs_header_info;
  128. FrameLayout msgContainer;
  129. TextView tv_input;
  130. FrameLayout fl_input;
  131. RecyclerView mRecyclerMsg;
  132. ConstraintLayout mViewLiveStatus;
  133. ConstraintLayout viewLiveCameraStatus;
  134. ImageView mIvLiveStatusCameraCenterIcon;
  135. TextView mTvLiveCameraStatusTipText;
  136. ImageView mIvLiveStatusCenterIcon;
  137. TextView mTvLiveStatusTipText;
  138. TextView mTvJoinBarrage;
  139. TextView mTvSnapUpBarrage;
  140. TextView mTvAddLikeCount;
  141. TextView mTvNumPeople;
  142. ImageView iv_mic;
  143. LottieAnimationView mViewShopCarAnim;
  144. ImageView mIvShopCar;
  145. ImageView mIvAvatar;
  146. TextView mTvRoomCreateName;
  147. ImageView mIvVoiceSwitch;
  148. Group group_tip;
  149. Group group_loading;
  150. TextView tv_retry;
  151. TextView tv_loading;
  152. TTLiveRoomMicIconView mLlMicContainer;
  153. TXCloudVideoView subVideoView;
  154. private ServiceConnection serviceConnection;
  155. public static final int SEND_SHOW_FLOAT_WINDOW_TIME = 1000;//退到后台以后检查是否显示悬浮窗等待时长
  156. public static final int SEND_APP_BACKGROUND_MSG = 1001;//退到后台消息
  157. public static final int SEND_JUMP_OTHER_PAGE_MSG = 1002;//页面切换消息(购物车详情页等等)
  158. public static final int OPEN_SHOP_CAR_DIALOG = 1003;//打开购物车
  159. public static final int LIVE_STATUS_IS_REST = 1;//休息一下,马上回来
  160. public static final int LIVE_STATUS_IS_CLOSE_VIDEO = 2;//主持人关闭画面
  161. public static final int LIVE_STATUS_IS_OFFLINE = 3;//直播已结束
  162. public static final int LIVE_STATUS_LOADING = 4;//直播加载中
  163. public static final int LIVE_STATUS_ERROR = 5;//直播加载中出错
  164. private static final String ROOMID_KEY = "roomid_key";
  165. private static final String SUBJECT_ID_KEY = "subject_id_key";
  166. private String mRoomId = "";
  167. private String mUserId = "";
  168. private ObjectAnimator hideHeaderInfoAnim;
  169. private ObjectAnimator showHeaderInfoAnim;
  170. private boolean isEnableChat = false;//默认不禁止
  171. private boolean isEnableMic = false;//默认不禁止
  172. private boolean isEnableAll = false;//默认不禁止 黑名单状态
  173. private boolean isPcClientLive = true;//默认为PC端直播
  174. private boolean isMuteAllMic = false;//默认为不禁止麦克风
  175. private boolean isNeedRefresh = false;//是否需要重新刷新房间信息
  176. private boolean liveIsFinish = false;//直播间是否已结束
  177. private boolean liveIsPause = false;//直播间是否已暂停
  178. private long currentAddLikeCount = 0;//当前点赞数量
  179. private int currentSeatStatus = LiveRoomMsgConstants.MIC_STATUS_NORMAL;//1未连麦,2连麦中,3连麦成功
  180. private LiveRoomInfoBean roomInfo;
  181. private InputBarDialog mInputBarDialog;
  182. private LiveRoomMicManagerDialog mMicManagerDialog;
  183. private LiveRoomInviteSeatMicTipDialog mInviteSeatMicTipDialog;
  184. private LiveRoomShopCarDialog mShopCarDialog;
  185. private V2TXLivePlayer mMLivePlayer;
  186. private boolean isMuteAll = false;//是否静音
  187. private boolean isConnectImFailed = false;//IM状态是否异常
  188. private boolean isOnResume = true;
  189. private Handler mHandler = new Handler(Looper.myLooper()) {
  190. @Override
  191. public void handleMessage(@NonNull android.os.Message msg) {
  192. if (msg.what == SEND_APP_BACKGROUND_MSG) {
  193. //APP切换后台 isOnResume要等于false
  194. //开启悬浮窗
  195. if (!isOnResume && AppUtils.isApplicationInBackground(TCStudentLiveRoomActivity.this)) {
  196. startFloatWindowService();
  197. }
  198. return;
  199. }
  200. if (msg.what == SEND_JUMP_OTHER_PAGE_MSG) {
  201. //跳转其他页面时候
  202. //开启悬浮窗
  203. if (isOnResume) {
  204. //如果页面onResume了,就不开启service
  205. return;
  206. }
  207. startFloatWindowService();
  208. return;
  209. }
  210. if (msg.what == OPEN_SHOP_CAR_DIALOG) {
  211. showShopCarDialog();
  212. return;
  213. }
  214. }
  215. };
  216. private V2TIMSDKListener mTIMSDKListener = new V2TIMSDKListener() {
  217. @Override
  218. public void onConnecting() {
  219. super.onConnecting();
  220. Log.i(TAG, "onConnecting");
  221. }
  222. @Override
  223. public void onConnectSuccess() {
  224. super.onConnectSuccess();
  225. Log.i(TAG, "onConnectSuccess");
  226. if (isConnectImFailed) {
  227. if (isOnMic()) {
  228. handleCloseMicEvent();
  229. }
  230. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM);
  231. presenter.notifyJoinRoomAction(mRoomId, mUserId);
  232. presenter.getAllGroupAttributes(mRoomId);
  233. presenter.getAllGroupCounter(mRoomId);
  234. play();
  235. }
  236. isConnectImFailed = false;
  237. }
  238. @Override
  239. public void onConnectFailed(int code, String error) {
  240. super.onConnectFailed(code, error);
  241. Log.i(TAG, "onConnectFailed");
  242. isConnectImFailed = true;
  243. showLiveStatusView(LIVE_STATUS_ERROR);
  244. }
  245. @Override
  246. public void onKickedOffline() {
  247. super.onKickedOffline();
  248. Log.i(TAG, "onKickedOffline");
  249. finish();
  250. }
  251. @Override
  252. public void onUserSigExpired() {
  253. super.onUserSigExpired();
  254. Log.i(TAG, "onUserSigExpired");
  255. finish();
  256. }
  257. @Override
  258. public void onSelfInfoUpdated(V2TIMUserFullInfo info) {
  259. super.onSelfInfoUpdated(info);
  260. Log.i(TAG, "onSelfInfoUpdated");
  261. }
  262. @Override
  263. public void onUserStatusChanged(List<V2TIMUserStatus> userStatusList) {
  264. super.onUserStatusChanged(userStatusList);
  265. String myselfUserID = V2TIMManager.getInstance().getLoginUser();
  266. for (V2TIMUserStatus item : userStatusList) {
  267. Log.i(TAG, "onUserStatusChanged");
  268. if (item.getUserID().equals(myselfUserID)) {
  269. // 自己的状态发生变更
  270. int statusType = item.getStatusType();
  271. Log.i(TAG, "onUserStatusChanged statusType:" + statusType);
  272. if (statusType == V2TIMUserStatus.V2TIM_USER_STATUS_OFFLINE) {
  273. }
  274. } else {
  275. // 其他人的状态发生变更
  276. }
  277. }
  278. }
  279. };
  280. private TTMessageAdapter mMessageAdapter;
  281. private LinearLayoutManager mLinearLayoutManager;
  282. private boolean isAutoScrollToLast = true;
  283. private boolean anchorIsOnline = false;//主播是否在线
  284. private LiveRoomCloseMicTipDialog mRoomCloseMicTipDialog;
  285. private LiveRoomClosePageOnMicTipDialog mLiveRoomClosePageOnMicTipDialog;
  286. private String subjectId;
  287. @Override
  288. protected void onCreate(Bundle savedInstanceState) {
  289. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  290. super.onCreate(savedInstanceState);
  291. }
  292. @Override
  293. protected AcTtLiveroomLayoutBinding getLayoutView() {
  294. return AcTtLiveroomLayoutBinding.inflate(getLayoutInflater());
  295. }
  296. @Override
  297. protected void initView() {
  298. content_view = viewBinding.contentView;
  299. mVideoView = viewBinding.videoView;
  300. flVideoContainer = viewBinding.flVideoContainer;
  301. csVideoContainer = viewBinding.csVideoContainer;
  302. mGroupViews = viewBinding.groupViews;
  303. mFlJoinBarrage = viewBinding.flJoinBarrage;
  304. mIvClose = viewBinding.ivClose;
  305. mFlSnapUpBarrage = viewBinding.flSnapUpBarrage;
  306. mIvSwitchVideoOrientation = viewBinding.ivSwitchVideoOrientation;
  307. mIvSwitchVideoOrientationFull = viewBinding.ivSwitchVideoOrientationFull;
  308. cs_header_info = viewBinding.csHeaderInfo;
  309. msgContainer = viewBinding.flRecyclerContainer;
  310. tv_input = viewBinding.tvInput;
  311. fl_input = viewBinding.flInput;
  312. mRecyclerMsg = viewBinding.recyclerMsg;
  313. mViewLiveStatus = viewBinding.viewLiveStatus.csRoot;
  314. viewLiveCameraStatus = viewBinding.viewLiveCameraStatus.csRoot;
  315. mIvLiveStatusCameraCenterIcon = viewBinding.viewLiveCameraStatus.ivCameraCenterIcon;
  316. mTvLiveCameraStatusTipText = viewBinding.viewLiveCameraStatus.tvLiveCameraStatusTipText;
  317. mIvLiveStatusCenterIcon = viewBinding.viewLiveStatus.ivCenterIcon;
  318. mTvLiveStatusTipText = viewBinding.viewLiveStatus.tvLiveStatusTipText;
  319. mTvJoinBarrage = viewBinding.tvJoinBarrage;
  320. mTvSnapUpBarrage = viewBinding.tvSnapUpBarrage;
  321. mTvAddLikeCount = viewBinding.tvAddLikeCount;
  322. mTvNumPeople = viewBinding.tvNumPeople;
  323. iv_mic = viewBinding.ivMic;
  324. mViewShopCarAnim = viewBinding.viewShopCarAnim;
  325. mIvShopCar = viewBinding.ivShopCar;
  326. mIvAvatar = viewBinding.ivAvatar;
  327. mTvRoomCreateName = viewBinding.tvRoomAuthorName;
  328. mIvVoiceSwitch = viewBinding.ivVoiceSwitch;
  329. group_tip = viewBinding.viewLiveStatus.groupTip;
  330. group_loading = viewBinding.viewLiveStatus.groupLoading;
  331. tv_retry = viewBinding.viewLiveStatus.tvRetry;
  332. tv_loading = viewBinding.viewLiveStatus.tvLoading;
  333. mLlMicContainer = viewBinding.llMicContainer;
  334. subVideoView = viewBinding.subVideoView;
  335. mRoomId = getIntent().getStringExtra(ROOMID_KEY);
  336. if (getIntent().hasExtra(SUBJECT_ID_KEY)) {
  337. subjectId = getIntent().getStringExtra(SUBJECT_ID_KEY);
  338. }
  339. if (TextUtils.isEmpty(mRoomId)) {
  340. ToastUtil.getInstance().show(this, "房间id不可为空");
  341. finish();
  342. return;
  343. }
  344. mMessageAdapter = new TTMessageAdapter(this);
  345. mLinearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
  346. mRecyclerMsg.addItemDecoration(new RecyclerView.ItemDecoration() {
  347. @Override
  348. public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
  349. super.onDraw(c, parent, state);
  350. }
  351. });
  352. mRecyclerMsg.setLayoutManager(mLinearLayoutManager);
  353. mRecyclerMsg.setAdapter(mMessageAdapter);
  354. }
  355. public void setStatusBarColor() {
  356. ImmersionBar.with(this)
  357. .keyboardEnable(false)//为了防止软键盘顶起底部布局
  358. .transparentStatusBar()
  359. .statusBarDarkFont(false, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
  360. .autoDarkModeEnable(false)
  361. .flymeOSStatusBarFontColor(R.color.white) //修改flyme OS状态栏字体颜色
  362. .init(); //必须调用方可沉浸
  363. }
  364. @Override
  365. public void initData() {
  366. super.initData();
  367. initIMSdk();
  368. mUserId = UserHelper.getImUserId();
  369. //创建 player 对象
  370. mMLivePlayer = new V2TXLivePlayerImpl(this);
  371. mMLivePlayer.setRenderFillMode(V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill);
  372. // 设置画面渲染方向
  373. mMLivePlayer.setRenderRotation(V2TXLiveRotation0);
  374. //关键 player 对象与界面 view
  375. mMLivePlayer.setRenderView(mVideoView);
  376. mMLivePlayer.enableReceiveSeiMessage(true, TTLiveConfig.DEFAULT_PAYLOAD_TYPE);
  377. presenter.init(this, mRoomId);
  378. initListener();
  379. }
  380. private void initIMSdk() {
  381. TCIMSdkManager.getInstance().init(getApplication());
  382. }
  383. private void initListener() {
  384. initViewClickListener();
  385. TCIMSdkManager.getInstance().addEventListener(mTIMSDKListener);
  386. SoftKeyboardUtil.registerSoftInputChangedListener(getWindow(), this);
  387. mRecyclerMsg.addOnScrollListener(new RecyclerView.OnScrollListener() {
  388. @Override
  389. public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
  390. super.onScrollStateChanged(recyclerView, newState);
  391. if (mLinearLayoutManager == null || mMessageAdapter == null) {
  392. return;
  393. }
  394. int lastCompletelyVisibleItemPosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
  395. if (lastCompletelyVisibleItemPosition == mMessageAdapter.getMessageSize() - 1) {
  396. isAutoScrollToLast = true;
  397. } else {
  398. isAutoScrollToLast = false;
  399. }
  400. }
  401. });
  402. mMLivePlayer.setObserver(new V2TXLivePlayerObserver() {
  403. @Override
  404. public void onError(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
  405. super.onError(player, code, msg, extraInfo);
  406. Log.i("pq", "play error:code=" + code + "---msg:" + msg + "---Bundle:" + extraInfo.toString());
  407. if (anchorIsOnline) {
  408. showLiveStatusView(LIVE_STATUS_ERROR);
  409. }
  410. }
  411. @Override
  412. public void onWarning(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
  413. super.onWarning(player, code, msg, extraInfo);
  414. Log.i("pq", "play onWarning:code=" + code + "---msg:" + msg + "---Bundle:" + extraInfo.toString());
  415. }
  416. @Override
  417. public void onConnected(V2TXLivePlayer player, Bundle extraInfo) {
  418. super.onConnected(player, extraInfo);
  419. Log.i("pq", "play onConnected:" + extraInfo.toString());
  420. }
  421. @Override
  422. public void onRenderVideoFrame(V2TXLivePlayer player, V2TXLiveDef.V2TXLiveVideoFrame videoFrame) {
  423. super.onRenderVideoFrame(player, videoFrame);
  424. Log.i("pq", "play onRenderVideoFrame:" + videoFrame);
  425. hideLiveStatus();
  426. }
  427. @Override
  428. public void onVideoLoading(V2TXLivePlayer player, Bundle extraInfo) {
  429. super.onVideoLoading(player, extraInfo);
  430. Log.i("pq", "play onVideoLoading:" + extraInfo.toString());
  431. }
  432. @Override
  433. public void onVideoPlaying(V2TXLivePlayer player, boolean firstPlay, Bundle extraInfo) {
  434. super.onVideoPlaying(player, firstPlay, extraInfo);
  435. Log.i("pq", "play onVideoPlaying:" + extraInfo.toString() + "---isFirstPlay:" + firstPlay);
  436. hideLiveStatus();
  437. }
  438. @Override
  439. public void onReceiveSeiMessage(V2TXLivePlayer player, int payloadType, byte[] data) {
  440. super.onReceiveSeiMessage(player, payloadType, data);
  441. Log.i("pq", "play onReceiveSeiMessage:length" + data.length + "---" + payloadType + "---data:" + new String(data));
  442. if (data != null && data.length > 0) {
  443. parseSeiMessage(new String(data));
  444. }
  445. }
  446. @Override
  447. public void onStatisticsUpdate(V2TXLivePlayer player, V2TXLiveDef.V2TXLivePlayerStatistics statistics) {
  448. super.onStatisticsUpdate(player, statistics);
  449. // Log.i("pq", "play videoBitrate:" + statistics.videoBitrate);
  450. // Log.i("pq", "play audioBitrate:" + statistics.audioBitrate);
  451. // Log.i("pq", "play videoPacketLoss:" + statistics.videoPacketLoss);
  452. // Log.i("pq", "play audioPacketLoss:" + statistics.audioPacketLoss);
  453. // Log.i("pq", "play videoBlockRate:" + statistics.videoBlockRate);
  454. // Log.i("pq", "play aul dioBlockRate:" + statistics.audioBlockRate);
  455. // Log.i("pq", "play videoTotalBlockTime:" + statistics.videoTotalBlockTime);
  456. // Log.i("pq", "play audioTotalBlockTime:" + statistics.audioTotalBlockTime);
  457. // Log.i("pq", "play rtt:" + statistics.rtt);
  458. }
  459. });
  460. mLlMicContainer.setOnEventListener(new TTLiveRoomMicIconView.OnEventListener() {
  461. @Override
  462. public void getUserInfoByUserId(String userId) {
  463. if (presenter != null) {
  464. presenter.getUserInfoByUserId(userId);
  465. }
  466. }
  467. @Override
  468. public void onMicStatusUpdate(String userId, String currentMicStatus) {
  469. boolean isOpen = !TextUtils.equals(currentMicStatus, TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
  470. changeMicStatus(userId, isOpen);
  471. }
  472. });
  473. }
  474. private void changeMicStatus(String userId, boolean isOpenCloseMode) {
  475. mLlMicContainer.post(new Runnable() {
  476. @Override
  477. public void run() {
  478. if (isOpenCloseMode) {
  479. //开启闭麦模式
  480. mLlMicContainer.updateTargetUserMicStatus(userId, TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
  481. presenter.setMicrophoneDisable(true);
  482. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_MIC_STATUS_CHANGE, mUserId, true);
  483. } else {
  484. //关闭闭麦模式
  485. mLlMicContainer.updateTargetUserMicStatus(userId, TTLiveConfig.LIVE_ROOM_MIC_STATUS_OFF_VALUE);
  486. presenter.setMicrophoneDisable(false);
  487. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_MIC_STATUS_CHANGE, mUserId, false);
  488. }
  489. }
  490. });
  491. }
  492. private void parseSeiMessage(String s) {
  493. try {
  494. Log.i("pq", "parseSeiMessage:" + s);
  495. LiveStatusSEMIMsg semiMsg = GsonUtils.fromJson(s, LiveStatusSEMIMsg.class);
  496. List<LiveStatusSEMIMsg.UserStatusBean> seatUser = semiMsg.getSeatUser();
  497. mLlMicContainer.refreshAll(seatUser);
  498. } catch (Exception e) {
  499. e.printStackTrace();
  500. }
  501. }
  502. private void notifyMicContainerDel(String userId) {
  503. mLlMicContainer.post(new Runnable() {
  504. @Override
  505. public void run() {
  506. mLlMicContainer.deleteMicUser(userId);
  507. }
  508. });
  509. }
  510. private void notifyMicContainerAdd(String userId) {
  511. Log.i("pq", "notifyMicContainerAdd:" + userId);
  512. List<String> seatUser = new ArrayList<>();
  513. seatUser.add(userId);
  514. mLlMicContainer.addOnMicUser(seatUser);
  515. }
  516. private void hideLiveStatus() {
  517. if (mViewLiveStatus != null) {
  518. mViewLiveStatus.setVisibility(View.GONE);
  519. }
  520. }
  521. private void hideLiveCameraStatus() {
  522. if (viewLiveCameraStatus != null) {
  523. viewLiveCameraStatus.setVisibility(View.GONE);
  524. }
  525. }
  526. private void initViewClickListener() {
  527. viewBinding.ivClose.setOnClickListener(this);
  528. viewBinding.ivSwitchVideoOrientation.setOnClickListener(this);
  529. viewBinding.flInput.setOnClickListener(this);
  530. viewBinding.ivMic.setOnClickListener(this);
  531. viewBinding.iconAddLike.setOnClickListener(this);
  532. viewBinding.ivSwitchVideoOrientationFull.setOnClickListener(this);
  533. viewBinding.viewLiveStatus.csRoot.setOnClickListener(this);
  534. viewBinding.viewShopCarAnim.setOnClickListener(this);
  535. viewBinding.flVideoContainer.setOnClickListener(this);
  536. viewBinding.ivVoiceSwitch.setOnClickListener(this);
  537. viewBinding.viewLiveStatus.tvRetry.setOnClickListener(this);
  538. }
  539. @Override
  540. public void onClick(View view) {
  541. int id = view.getId();
  542. if (id == viewBinding.viewLiveStatus.csRoot.getId()) {
  543. return;
  544. }
  545. if (id == R.id.iv_close) {
  546. if (currentSeatStatus != LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
  547. showPageCloseOnMicTipDialog();
  548. } else {
  549. close();
  550. }
  551. return;
  552. }
  553. if (id == R.id.iv_switch_video_orientation) {
  554. //切换横竖屏
  555. if (UiUtils.isFastClick()) {
  556. return;
  557. }
  558. if (mShopCarDialog != null && mShopCarDialog.isShowing()) {
  559. return;
  560. }
  561. changeOrientation();
  562. return;
  563. }
  564. if (id == R.id.iv_switch_video_orientation_full) {
  565. //横屏切换竖屏
  566. changeOrientation();
  567. return;
  568. }
  569. if (id == R.id.fl_input) {
  570. //底部输入框
  571. showInputDialog();
  572. return;
  573. }
  574. if (id == R.id.iv_mic) {
  575. //连麦
  576. toCheckMicPermission();
  577. return;
  578. }
  579. if (id == R.id.icon_add_like) {
  580. if (checkAddLikeMode()) {
  581. return;
  582. }
  583. //点赞
  584. LiveRoomAddLikeHelper.getInstance().handleClick(new LiveRoomAddLikeHelper.OnAddLikeResultCallBack() {
  585. @Override
  586. public void onResult(int count) {
  587. if (presenter != null) {
  588. presenter.updateGroupAddLike(mRoomId, count);
  589. // presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_ADD_LIKE_COUNT, count);
  590. }
  591. }
  592. });
  593. LiveRoomAnimatorHelper.getInstance().startAddLikeAnimation(TCStudentLiveRoomActivity.this, content_view);
  594. return;
  595. }
  596. if (id == R.id.view_shop_car_anim) {
  597. if (liveIsFinish) {
  598. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
  599. return;
  600. }
  601. //购物车
  602. if (isFullScreen()) {
  603. changeOrientation();
  604. android.os.Message message = android.os.Message.obtain();
  605. message.what = OPEN_SHOP_CAR_DIALOG;
  606. mHandler.sendMessageDelayed(message, 500);
  607. } else {
  608. showShopCarDialog();
  609. }
  610. return;
  611. }
  612. if (id == R.id.fl_video_container) {
  613. //点击隐藏头部信息
  614. if (isFullScreen()) {
  615. //全屏模式下
  616. handleHeaderAnim();
  617. }
  618. return;
  619. }
  620. if (id == R.id.iv_voice_switch) {
  621. // //静音
  622. if (isMuteAll) {
  623. this.isMuteAll = false;
  624. mIvVoiceSwitch.setImageResource(R.drawable.icon_live_voice_on);
  625. muteAll(false);
  626. } else {
  627. mIvVoiceSwitch.setImageResource(R.drawable.icon_live_voice_off);
  628. this.isMuteAll = true;
  629. muteAll(true);
  630. }
  631. }
  632. if (id == R.id.tv_retry) {
  633. play();
  634. return;
  635. }
  636. }
  637. @SuppressLint("CheckResult")
  638. private void toCheckMicPermission() {
  639. new RxPermissions(this)
  640. .request(Manifest.permission.RECORD_AUDIO,
  641. Manifest.permission.WRITE_EXTERNAL_STORAGE)
  642. .subscribe(permission -> {
  643. if (permission) {
  644. handleMicClick();
  645. } else {
  646. DialogUtil.showInCenter(getSupportFragmentManager(), com.cooleshow.base.R.layout.common_popu, (holder, dialog) -> {
  647. TextView tvTitle = holder.getView(com.cooleshow.base.R.id.tv_title);
  648. TextView tvContent = holder.getView(com.cooleshow.base.R.id.tv_content);
  649. TextView btncancel = holder.getView(com.cooleshow.base.R.id.btn_cancel);
  650. TextView btnCommit = holder.getView(com.cooleshow.base.R.id.btn_commit);
  651. tvTitle.setText("提示");
  652. tvContent.setText("连麦需要麦克风、储存权限,去设置?");
  653. btncancel.setOnClickListener(view1 -> {
  654. dialog.dismiss();
  655. });
  656. btnCommit.setOnClickListener(view1 -> {
  657. PermissionUtils.toSelfSetting(getApplicationContext());
  658. dialog.dismiss();
  659. });
  660. });
  661. }
  662. });
  663. }
  664. private void handleMicClick() {
  665. if (!isOnMic()) {
  666. //非连麦中才判断模式
  667. if (checkMicMode()) {
  668. return;
  669. }
  670. if (isConnectImFailed) {
  671. //连接状态异常,暂停连麦
  672. return;
  673. }
  674. }
  675. showMicManagerDialog();
  676. }
  677. /**
  678. * 是否静音全部
  679. *
  680. * @param isMute
  681. */
  682. private void muteAll(boolean isMute) {
  683. mMLivePlayer.setPlayoutVolume(isMute ? 0 : 100);
  684. if (presenter != null) {
  685. presenter.muteTRTC(isMute);
  686. }
  687. }
  688. private void showPageCloseOnMicTipDialog() {
  689. if (mLiveRoomClosePageOnMicTipDialog == null) {
  690. mLiveRoomClosePageOnMicTipDialog = new LiveRoomClosePageOnMicTipDialog(this);
  691. mLiveRoomClosePageOnMicTipDialog.setConfirmClickListener(new View.OnClickListener() {
  692. @Override
  693. public void onClick(View v) {
  694. finish();
  695. }
  696. });
  697. }
  698. if (!mLiveRoomClosePageOnMicTipDialog.isShowing()) {
  699. mLiveRoomClosePageOnMicTipDialog.show();
  700. }
  701. mLiveRoomClosePageOnMicTipDialog.setTitle("提示");
  702. mLiveRoomClosePageOnMicTipDialog.setContent("连麦中,是否退出房间?");
  703. }
  704. private void close() {
  705. //断开连接,结束页面
  706. onBackPressed();
  707. }
  708. @Override
  709. public void onBackPressed() {
  710. if (liveIsFinish) {
  711. super.onBackPressed();
  712. return;
  713. }
  714. if (isFullScreen()) {
  715. changeOrientation();
  716. } else {
  717. boolean permissionOverlay = FloatWindowHelper.requestOverlayPermission(this);
  718. if (!permissionOverlay) {
  719. showOpenOverlayPermissionTipDialog();
  720. } else {
  721. showExitLiveTipDialog();
  722. }
  723. }
  724. }
  725. private void showOpenOverlayPermissionTipDialog() {
  726. OpenOverlayPermissionTipDialog overlayPermissionTipDialog = new OpenOverlayPermissionTipDialog(this);
  727. overlayPermissionTipDialog.setConfirmClickListener(new View.OnClickListener() {
  728. @Override
  729. public void onClick(View v) {
  730. overlayPermissionTipDialog.dismiss();
  731. Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
  732. startActivityForResult(intent, FloatWindowHelper.REQUEST_OVERLAY_CODE);
  733. }
  734. });
  735. overlayPermissionTipDialog.show();
  736. overlayPermissionTipDialog.setCancelClickListener(new View.OnClickListener() {
  737. @Override
  738. public void onClick(View v) {
  739. overlayPermissionTipDialog.dismiss();
  740. finish();
  741. }
  742. });
  743. }
  744. /**
  745. * 退出直播间提示弹窗
  746. */
  747. private void showExitLiveTipDialog() {
  748. LiveRoomExitTipDialog2 liveRoomExitTipDialog2 = new LiveRoomExitTipDialog2(this);
  749. liveRoomExitTipDialog2.setConfirmClickListener(new View.OnClickListener() {
  750. @Override
  751. public void onClick(View v) {
  752. finish();
  753. }
  754. });
  755. liveRoomExitTipDialog2.show();
  756. }
  757. private void showInputDialog() {
  758. if (roomInfo == null) {
  759. return;
  760. }
  761. if (checkChatMode()) return;
  762. if (mInputBarDialog == null) {
  763. mInputBarDialog = new InputBarDialog(TCStudentLiveRoomActivity.this, new InputBar.InputBarListener() {
  764. @Override
  765. public boolean onClickSend(String message) {
  766. //发送消息
  767. if (checkChatMode()) {
  768. return false;
  769. }
  770. if (TextUtils.isEmpty(message)) {
  771. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "消息不能为空");
  772. return false;
  773. }
  774. if (message.length() > TTLiveConfig.LIVE_MAX_INPUT_TEXT_LENGTH) {
  775. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "聊天消息需在40个字以内哦");
  776. return false;
  777. }
  778. if (LiveMessageHelper.isQuickAction()) {
  779. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您说话太快啦");
  780. return false;
  781. }
  782. sendTextMessage(message);
  783. return true;
  784. }
  785. @Override
  786. public boolean onClickEmoji() {
  787. return false;
  788. }
  789. });
  790. mInputBarDialog.setOnShowListener(new DialogInterface.OnShowListener() {
  791. @Override
  792. public void onShow(DialogInterface dialog) {
  793. if (mInputBarDialog != null) {
  794. mInputBarDialog.showInput();
  795. }
  796. }
  797. });
  798. }
  799. if (!mInputBarDialog.isShowing()) {
  800. mInputBarDialog.show();
  801. }
  802. }
  803. private void sendTextMessage(String message) {
  804. presenter.sendTextMessage(message);
  805. }
  806. /**
  807. * 检查点赞按钮是否可用
  808. *
  809. * @return
  810. */
  811. private boolean checkAddLikeMode() {
  812. if (liveIsFinish) {
  813. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
  814. return true;
  815. }
  816. // if (isEnableAll) {
  817. // ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
  818. // return true;
  819. // }
  820. if (isConnectImFailed) {
  821. //连接状态异常,暂停点赞
  822. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "网络连接状态异常");
  823. return true;
  824. }
  825. return false;
  826. }
  827. private void changeOrientation() {
  828. int currentOrientation = getCurrentOrientation();
  829. boolean isNeedFullScreen = currentOrientation != Configuration.ORIENTATION_LANDSCAPE;
  830. if (isNeedFullScreen) {
  831. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  832. } else {
  833. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  834. }
  835. }
  836. private void startFloatWindowService() {
  837. boolean hasPermission = FloatWindowHelper.requestOverlayPermission(this);
  838. if (hasPermission) {
  839. Intent intent = new Intent(this, FloatingWindowService.class);
  840. initServiceConnection();
  841. intent.putExtra("isPc", isPcClientLive);
  842. bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
  843. }
  844. }
  845. private void initServiceConnection() {
  846. if (serviceConnection == null) {
  847. serviceConnection = new ServiceConnection() {
  848. @Override
  849. public void onServiceConnected(ComponentName name, IBinder service) {
  850. if (service instanceof FloatingWindowService.MyBinder) {
  851. FloatingWindowService.MyBinder mBinder = (FloatingWindowService.MyBinder) service;
  852. ArrayList<View> list = new ArrayList();
  853. list.add(getVideoView());
  854. mBinder.addTTVideoView(list);
  855. mBinder.setOnEventListener(new FloatingWindowService.OnEventListener() {
  856. @Override
  857. public void onServiceDestroy() {
  858. if (flVideoContainer != null) {
  859. flVideoContainer.addView(getVideoView());
  860. }
  861. }
  862. @Override
  863. public void onUnbindService() {
  864. muteAll(true);
  865. unbindService();
  866. }
  867. });
  868. }
  869. }
  870. @Override
  871. public void onServiceDisconnected(ComponentName name) {
  872. if (flVideoContainer != null) {
  873. flVideoContainer.addView(getVideoView());
  874. }
  875. }
  876. };
  877. }
  878. }
  879. /**
  880. * 销毁悬浮窗service
  881. */
  882. private void unbindService() {
  883. if (serviceConnection != null) {
  884. try {
  885. boolean isExist = AppUtils.isServiceWork(this, FloatingWindowService.CLASS_PATH);
  886. if (isExist) {
  887. unbindService(serviceConnection);
  888. }
  889. } catch (Exception e) {
  890. e.printStackTrace();
  891. }
  892. }
  893. }
  894. public View getVideoView() {
  895. return csVideoContainer;
  896. }
  897. private boolean isFullScreen() {
  898. return getCurrentOrientation() == Configuration.ORIENTATION_LANDSCAPE;
  899. }
  900. private int getCurrentOrientation() {
  901. return getResources().getConfiguration().orientation;
  902. }
  903. @Override
  904. public void onConfigurationChanged(@NonNull Configuration newConfig) {
  905. super.onConfigurationChanged(newConfig);
  906. //改变videoView容器布局尺寸
  907. resetVideoContainer(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
  908. }
  909. private void resetVideoContainer(boolean isFullScreen) {
  910. if (isFullScreen) {
  911. if (isPcClientLive) {
  912. //隐藏消息列表
  913. mGroupViews.setVisibility(View.GONE);
  914. mIvClose.setVisibility(View.GONE);
  915. //隐藏弹幕消息
  916. mFlJoinBarrage.clearAnimation();
  917. mFlJoinBarrage.setVisibility(View.GONE);
  918. mFlSnapUpBarrage.clearAnimation();
  919. mFlSnapUpBarrage.setVisibility(View.GONE);
  920. //隐藏竖屏全屏按钮
  921. mIvSwitchVideoOrientation.setVisibility(View.GONE);
  922. mIvSwitchVideoOrientationFull.setVisibility(View.VISIBLE);
  923. } else {
  924. //不是PC端直播
  925. mIvSwitchVideoOrientation.setVisibility(View.GONE);
  926. mIvSwitchVideoOrientationFull.setVisibility(View.GONE);
  927. }
  928. ConstraintSet set = new ConstraintSet();
  929. set.clone(content_view);
  930. set.clear(flVideoContainer.getId());
  931. if (!isPcClientLive) {
  932. //如果是非PC端直播,还需要设置下消息列表控件位置
  933. set.clear(msgContainer.getId());
  934. set.connect(msgContainer.getId(), ConstraintSet.TOP, R.id.view_center, ConstraintSet.BOTTOM, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 50));
  935. set.connect(msgContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
  936. set.connect(msgContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
  937. set.connect(msgContainer.getId(), ConstraintSet.BOTTOM, fl_input.getId(), ConstraintSet.TOP, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 10));
  938. }
  939. set.connect(flVideoContainer.getId(), ConstraintSet.TOP, content_view.getId(), ConstraintSet.TOP, 0);
  940. set.connect(flVideoContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
  941. set.connect(flVideoContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
  942. set.connect(flVideoContainer.getId(), ConstraintSet.BOTTOM, content_view.getId(), ConstraintSet.BOTTOM, 0);
  943. set.applyTo(content_view);
  944. } else {
  945. //pc端直播,控制居中显示,以及videoview容器的宽高
  946. if (cs_header_info.getTranslationY() != 0) {
  947. //还原显示头部信息
  948. handleHeaderAnim();
  949. }
  950. if (isPcClientLive) {
  951. mGroupViews.setVisibility(View.VISIBLE);
  952. mIvClose.setVisibility(View.VISIBLE);
  953. mIvSwitchVideoOrientation.setVisibility(View.VISIBLE);
  954. mIvSwitchVideoOrientationFull.setVisibility(View.GONE);
  955. }
  956. ConstraintSet set = new ConstraintSet();
  957. set.clone(content_view);
  958. set.clear(flVideoContainer.getId());
  959. set.connect(flVideoContainer.getId(), ConstraintSet.TOP, cs_header_info.getId(), ConstraintSet.BOTTOM, DensityUtil.dp2px(TCStudentLiveRoomActivity.this, 121));
  960. set.connect(flVideoContainer.getId(), ConstraintSet.LEFT, content_view.getId(), ConstraintSet.LEFT, 0);
  961. set.connect(flVideoContainer.getId(), ConstraintSet.RIGHT, content_view.getId(), ConstraintSet.RIGHT, 0);
  962. int maxHeightAtRatio16_9 = UiUtils.getMaxHeightAtRatio16_9(TCStudentLiveRoomActivity.this);
  963. set.constrainHeight(flVideoContainer.getId(), maxHeightAtRatio16_9);
  964. set.applyTo(content_view);
  965. }
  966. }
  967. private void handleHeaderAnim() {
  968. float animOffset = cs_header_info.getTranslationY();
  969. if (animOffset == 0) {
  970. //隐藏头部信息
  971. int bottom = cs_header_info.getBottom();
  972. if (hideHeaderInfoAnim == null) {
  973. hideHeaderInfoAnim = ObjectAnimator.ofFloat(cs_header_info, "translationY", 0, -bottom);
  974. hideHeaderInfoAnim.setDuration(500);
  975. }
  976. hideHeaderInfoAnim.start();
  977. } else {
  978. //显示头部信息
  979. if (showHeaderInfoAnim == null) {
  980. showHeaderInfoAnim = ObjectAnimator.ofFloat(cs_header_info, "translationY", animOffset, 0);
  981. showHeaderInfoAnim.setDuration(500);
  982. }
  983. showHeaderInfoAnim.start();
  984. }
  985. }
  986. /**
  987. * 控制聊天模式
  988. *
  989. * @param isEnableChat
  990. */
  991. @Override
  992. public void switchChatMode(boolean isEnableChat) {
  993. //控制聊天模式
  994. Log.i("pq", "聊天禁止:" + isEnableChat);
  995. this.isEnableChat = isEnableChat;
  996. }
  997. @Override
  998. public void changeMicControlMode(boolean isEnableMic) {
  999. //禁止连麦模式
  1000. if (isFinishing() || isDestroyed()) {
  1001. return;
  1002. }
  1003. Log.i("pq", "receive mic mode control msg 禁麦模式:" + isEnableMic);
  1004. this.isEnableMic = isEnableMic;
  1005. if (isEnableMic && isOnApplyMic()) {
  1006. handleCloseMicEvent();
  1007. }
  1008. }
  1009. @Override
  1010. public void liveRoomOffline() {
  1011. //关闭直播间
  1012. ToastUtil.getInstance().show(this, "直播已结束");
  1013. this.liveIsFinish = true;
  1014. //取消连麦
  1015. if (mMicManagerDialog != null) {
  1016. mMicManagerDialog.dismiss();
  1017. }
  1018. presenter.exitRoom();
  1019. showLiveStatusView(LIVE_STATUS_IS_OFFLINE);
  1020. hideDialog();
  1021. }
  1022. @Override
  1023. public void receiveJoinMessage(TCUserEnterMessage joinRoomMessage) {
  1024. if (!checkActivityExist()) {
  1025. return;
  1026. }
  1027. if (joinRoomMessage == null) {
  1028. return;
  1029. }
  1030. if (isCanShowBarrage()) {
  1031. mTvJoinBarrage.setText(getString(R.string.enter_live_tip_str, TTLiveHelper.getMessageName(joinRoomMessage)));
  1032. showBarrageViewAnim(mFlJoinBarrage);
  1033. }
  1034. }
  1035. /**
  1036. * 显示弹幕消息
  1037. */
  1038. private void showBarrageViewAnim(View targetView) {
  1039. if (mFlJoinBarrage.getVisibility() == View.VISIBLE || mFlSnapUpBarrage.getVisibility() == View.VISIBLE) {
  1040. return;
  1041. }
  1042. LiveRoomAnimatorHelper.getInstance().startBarrageViewAnimation(this, targetView);
  1043. hideBarrageView();
  1044. }
  1045. /**
  1046. * 隐藏弹幕消息
  1047. */
  1048. private void hideBarrageView() {
  1049. mHandler.postDelayed(new Runnable() {
  1050. @Override
  1051. public void run() {
  1052. if (mFlJoinBarrage != null) {
  1053. mFlJoinBarrage.setVisibility(View.GONE);
  1054. }
  1055. if (mFlSnapUpBarrage != null) {
  1056. mFlSnapUpBarrage.setVisibility(View.GONE);
  1057. }
  1058. }
  1059. }, TTLiveConfig.LIVE_HIDE_BARRAGE_VIEW_TIME);
  1060. }
  1061. /**
  1062. * 判断是否显示弹幕消息
  1063. *
  1064. * @return
  1065. */
  1066. private boolean isCanShowBarrage() {
  1067. if (isFullScreen()) {
  1068. return false;
  1069. }
  1070. return mFlJoinBarrage.getVisibility() != View.VISIBLE && mFlSnapUpBarrage.getVisibility() != View.VISIBLE;
  1071. }
  1072. @Override
  1073. public void receiveSnapUpMessage(TCUserSnappingUpMessage onSnappingUpMessage) {
  1074. //收到抢购消息
  1075. if (!checkActivityExist()) {
  1076. return;
  1077. }
  1078. if (onSnappingUpMessage == null) {
  1079. return;
  1080. }
  1081. if (isCanShowBarrage()) {
  1082. mTvSnapUpBarrage.setText(getString(R.string.live_snap_up_tip_str, TTLiveHelper.getMessageName(onSnappingUpMessage)));
  1083. showBarrageViewAnim(mFlSnapUpBarrage);
  1084. }
  1085. }
  1086. @Override
  1087. public void liveGoodsChange(String goodsContent) {
  1088. //直播间商品发生变化
  1089. if (!checkActivityExist()) {
  1090. return;
  1091. }
  1092. if (mShopCarDialog != null) {
  1093. mShopCarDialog.changeGoods(goodsContent);
  1094. }
  1095. }
  1096. @Override
  1097. public void onAddLikeMessage(TCSyncAddLikeMessage addLikeMessage) {
  1098. if (isFinishing() || isDestroyed()) {
  1099. return;
  1100. }
  1101. if (addLikeMessage == null) {
  1102. return;
  1103. }
  1104. SendUserInfo sendUserInfo = addLikeMessage.getSendUserInfo();
  1105. if (sendUserInfo != null && isOwn(sendUserInfo.getSendUserId())) {
  1106. return;
  1107. }
  1108. // if (addLikeMessage != null) {
  1109. // if (mTvAddLikeCount != null) {
  1110. // currentAddLikeCount = addLikeMessage.getCount();
  1111. // updateAddLikeCountView();
  1112. // }
  1113. // }
  1114. }
  1115. private void updateAddLikeCountView(long count) {
  1116. this.currentAddLikeCount = count;
  1117. if (mTvAddLikeCount != null) {
  1118. mTvAddLikeCount.setText(getString(R.string.live_room_add_like_count_str, LiveMemberHelper.getStarsCountText(currentAddLikeCount)));
  1119. }
  1120. }
  1121. @Override
  1122. public void syncMemberCount(int count) {
  1123. //同步成员数量
  1124. Log.i("pq", "syncMemberCount" + count);
  1125. if (isFinishing() || isDestroyed()) {
  1126. return;
  1127. }
  1128. // setPeopleCount(String.valueOf(count));
  1129. }
  1130. public void setPeopleCount(String count) {
  1131. if (mTvNumPeople != null) {
  1132. mTvNumPeople.setText(String.format(Locale.getDefault(), "%s人", LiveMemberHelper.getMemberCountText(count)));
  1133. }
  1134. }
  1135. @Override
  1136. public void onUserKickOutMsg(TCKickOutUserMessage userKickOutMessage) {
  1137. //用户被踢出消息
  1138. if (!checkActivityExist()) {
  1139. return;
  1140. }
  1141. if (userKickOutMessage == null || !isOwn(userKickOutMessage.getTargetId())) {
  1142. return;
  1143. }
  1144. String targetId = userKickOutMessage.getTargetId();
  1145. Log.i("pq", "receive kickOut msg targetId:" + targetId);
  1146. finish();
  1147. }
  1148. private boolean isOwn(String targetUserId) {
  1149. return TextUtils.equals(mUserId, targetUserId);
  1150. }
  1151. @Override
  1152. public void seatResponse(TCUserSeatResponseMessage rcUserSeatResponseMessage) {
  1153. if (isFinishing() || isDestroyed()) {
  1154. return;
  1155. }
  1156. if (rcUserSeatResponseMessage == null || !isOwn(rcUserSeatResponseMessage.getAudienceId())) {
  1157. return;
  1158. }
  1159. if (rcUserSeatResponseMessage != null) {
  1160. int type = rcUserSeatResponseMessage.getType();
  1161. if (type == LiveRoomMsgConstants.MIC_RESPONSE_AGREE) {
  1162. //主播同意
  1163. // ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "主播同意连麦");
  1164. if (presenter != null) {
  1165. presenter.joinMic(mUserId, roomInfo.getUserSig());
  1166. }
  1167. return;
  1168. }
  1169. if (type == LiveRoomMsgConstants.MIC_RESPONSE_DISAGREE) {
  1170. //主播拒绝
  1171. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
  1172. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_refuse_seat_tip));
  1173. return;
  1174. }
  1175. }
  1176. }
  1177. @Override
  1178. public void onInviteSeatMic(TCUserSeatApplyMessage seatApplyMessage) {
  1179. if (isFinishing() || isDestroyed()) {
  1180. return;
  1181. }
  1182. if (seatApplyMessage == null || !isOwn(seatApplyMessage.getAudienceId())) {
  1183. return;
  1184. }
  1185. if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_INVITE_SEAT_BY_CREATE) {
  1186. //主讲人邀请观众上麦
  1187. showInviteSeatDialog();
  1188. return;
  1189. }
  1190. if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_CANCEL_INVITE_SEAT_BY_CREATE) {
  1191. //主讲人取消邀请观众上麦
  1192. if (mInviteSeatMicTipDialog != null) {
  1193. mInviteSeatMicTipDialog.dismiss();
  1194. }
  1195. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_recall_seat_invite_tip));
  1196. return;
  1197. }
  1198. if (seatApplyMessage.getType() == LiveRoomMsgConstants.MIC_ACTION_CANCEL_SEAT_BY_CREATE) {
  1199. //主讲人讲观众抱下麦
  1200. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "主讲人断开连麦");
  1201. if (presenter != null) {
  1202. presenter.exitRoom();
  1203. }
  1204. }
  1205. }
  1206. private void showShopCarDialog() {
  1207. if (roomInfo == null || TextUtils.isEmpty(roomInfo.getShopCarUrl())) {
  1208. return;
  1209. }
  1210. if (mShopCarDialog == null) {
  1211. mShopCarDialog = new LiveRoomShopCarDialog(this);
  1212. mShopCarDialog.setOnEventListener(new LiveRoomShopCarDialog.OnEventListener() {
  1213. @Override
  1214. public void onOpenDetail(String url) {
  1215. mShopCarDialog.dismiss();
  1216. //发送XXX正在抢购消息
  1217. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_ON_SNAP_UP);
  1218. sendShowFloatWindowAction(SEND_JUMP_OTHER_PAGE_MSG);
  1219. ARouter.getInstance()
  1220. .build(RouterPath.WebCenter.ACTIVITY_HTML)
  1221. .withString(WebConstants.WEB_URL, url)
  1222. .withString(WebConstants.WEB_TITLE, "商品详情")
  1223. .navigation();
  1224. }
  1225. });
  1226. }
  1227. if (!mShopCarDialog.isShowing()) {
  1228. mShopCarDialog.show();
  1229. }
  1230. mShopCarDialog.setRoomId(mRoomId, roomInfo.getShopCarUrl());
  1231. }
  1232. private void showInviteSeatDialog() {
  1233. if (mInviteSeatMicTipDialog == null) {
  1234. mInviteSeatMicTipDialog = new LiveRoomInviteSeatMicTipDialog(this);
  1235. mInviteSeatMicTipDialog.setCancelable(false);
  1236. mInviteSeatMicTipDialog.setCanceledOnTouchOutside(false);
  1237. mInviteSeatMicTipDialog.setViewClickListener(new View.OnClickListener() {
  1238. @Override
  1239. public void onClick(View v) {
  1240. if (v.getId() == R.id.tv_sure) {
  1241. //被邀请连麦->同意连麦
  1242. if (presenter != null && roomInfo != null) {
  1243. if (!checkMicMode2()) {
  1244. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_AGREE_RESPONSE, getSpeakerId(), getSpeakerName());
  1245. presenter.joinMic(mUserId, roomInfo.getUserSig());
  1246. }
  1247. }
  1248. }
  1249. if (v.getId() == R.id.tv_cancel) {
  1250. //被邀请连麦->拒绝连麦
  1251. if (presenter != null) {
  1252. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_DISAGREE_RESPONSE, getSpeakerId(), getSpeakerName());
  1253. }
  1254. //重置一下连麦状态
  1255. handleCloseMicEvent();
  1256. }
  1257. mInviteSeatMicTipDialog.dismiss();
  1258. }
  1259. });
  1260. }
  1261. if (!mInviteSeatMicTipDialog.isShowing()) {
  1262. mInviteSeatMicTipDialog.show();
  1263. }
  1264. String defaultNick = "主讲人";
  1265. if (roomInfo != null && !TextUtils.isEmpty(roomInfo.speakerName)) {
  1266. defaultNick = roomInfo.speakerName;
  1267. }
  1268. mInviteSeatMicTipDialog.setContent(defaultNick);
  1269. }
  1270. @Override
  1271. public void onUserUnusualLogout(TCUserLogOutUnNormalMessage loginOutUnusualMessage) {
  1272. if (isFinishing() || isDestroyed()) {
  1273. return;
  1274. }
  1275. if (loginOutUnusualMessage == null || !isOwn(loginOutUnusualMessage.getTargetId())) {
  1276. return;
  1277. }
  1278. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播加载异常,请退出重试");
  1279. Log.i("pq", "unusual logout");
  1280. finish();
  1281. }
  1282. @Override
  1283. public void showLoading() {
  1284. showLiveStatusView(LIVE_STATUS_LOADING);
  1285. }
  1286. @Override
  1287. public void hideLoading() {
  1288. hideLiveStatus();
  1289. }
  1290. @Override
  1291. public void onLivePause() {
  1292. if (isFinishing() || isDestroyed()) {
  1293. return;
  1294. }
  1295. showLiveStatusView(LIVE_STATUS_IS_REST);
  1296. this.liveIsPause = true;
  1297. // ToastUtil.getInstance().show(this, getString(R.string.live_is_pause_str));
  1298. handleCloseMicEvent();
  1299. if (mMicManagerDialog != null) {
  1300. mMicManagerDialog.dismiss();
  1301. }
  1302. }
  1303. @Override
  1304. public void changeBlackUserStatus(String userId, boolean isAddBlack) {
  1305. if (isFinishing() || isDestroyed()) {
  1306. return;
  1307. }
  1308. if (isOwn(userId)) {
  1309. isEnableAll = isAddBlack;
  1310. if (isEnableAll) {
  1311. //取消连麦
  1312. if (currentSeatStatus != LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
  1313. handleCloseMicEvent();
  1314. }
  1315. }
  1316. updateInputTip();
  1317. }
  1318. }
  1319. private void updateInputTip() {
  1320. if (tv_input == null) {
  1321. return;
  1322. }
  1323. if (isEnableAll) {
  1324. tv_input.setText(getString(R.string.unable_input_tip_str));
  1325. } else {
  1326. tv_input.setText(getString(R.string.live_input_tips_str));
  1327. }
  1328. }
  1329. @Override
  1330. public void onUnderAllMic() {
  1331. if (isFinishing() || isDestroyed()) {
  1332. return;
  1333. }
  1334. if (isOnMic()) {
  1335. if (presenter != null) {
  1336. presenter.exitRoom();
  1337. }
  1338. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.down_mic_by_create_tip));
  1339. if (presenter != null && roomInfo != null) {
  1340. presenter.buildUnderMicResponseMessage(mUserId, roomInfo.speakerId, roomInfo.speakerName);
  1341. }
  1342. }
  1343. }
  1344. @Override
  1345. public void onRefuseAllMicApply() {
  1346. if (isFinishing() || isDestroyed()) {
  1347. return;
  1348. }
  1349. if (mMicManagerDialog != null) {
  1350. mMicManagerDialog.dismiss();
  1351. }
  1352. if (isOnApplyMic()) {
  1353. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
  1354. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, getString(R.string.create_refuse_seat_tip));
  1355. if (roomInfo != null) {
  1356. presenter.buildResponseMessage(mUserId, roomInfo.speakerImUserId, roomInfo.speakerName);
  1357. }
  1358. }
  1359. }
  1360. @Override
  1361. public void onUserStartPublish() {
  1362. if (!checkActivityExist()) {
  1363. return;
  1364. }
  1365. }
  1366. @Override
  1367. public void enterLiveRoomSuccess() {
  1368. //重置记录状态,等待回调触发准确值
  1369. hasMainStream = false;
  1370. hasSubStream = false;
  1371. if (mMLivePlayer != null) {
  1372. mMLivePlayer.stopPlay();
  1373. }
  1374. config3AParamsIfNeed();
  1375. muteAll(isMuteAll);
  1376. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS);
  1377. if (mMicManagerDialog != null) {
  1378. mMicManagerDialog.dismiss();
  1379. }
  1380. presenter.startPublish(mUserId);
  1381. notifyMicContainerAdd(mUserId);
  1382. changeMicStatus(mUserId, isMuteAllMic);
  1383. }
  1384. private void config3AParamsIfNeed() {
  1385. if (!TextUtils.isEmpty(subjectId)) {
  1386. presenter.config3AParamsFromSubject(subjectId);
  1387. }
  1388. }
  1389. private boolean hasMainStream = false;//是否有主路流
  1390. private boolean hasSubStream = false;//是否有辅路流
  1391. @Override
  1392. public void onUserVideoAvailable(String userId, boolean available) {
  1393. if (TextUtils.equals(userId, getSpeakerId())) {
  1394. Log.i(TAG, "onUserVideoAvailable:" + available);
  1395. hasMainStream = available;
  1396. startRemote();
  1397. }
  1398. }
  1399. @Override
  1400. public void onUserSubStreamAvailable(String userId, boolean available) {
  1401. if (TextUtils.equals(userId, getSpeakerId())) {
  1402. Log.i(TAG, "onUserSubStreamAvailable:" + available);
  1403. hasSubStream = available;
  1404. startRemote();
  1405. }
  1406. }
  1407. public void startRemote() {
  1408. if (hasMainStream && hasSubStream) {
  1409. //主辅流都有的情况
  1410. subVideoView.setVisibility(View.VISIBLE);
  1411. presenter.startMainRemoteView(getSpeakerId(), isPcClientLive, subVideoView);
  1412. presenter.startSubRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
  1413. return;
  1414. }
  1415. if (hasMainStream) {
  1416. //主流情况
  1417. subVideoView.setVisibility(View.GONE);
  1418. presenter.stopSubRemoteView(getSpeakerId());
  1419. presenter.startMainRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
  1420. return;
  1421. }
  1422. if (hasSubStream) {
  1423. //单辅流情况
  1424. subVideoView.setVisibility(View.GONE);
  1425. presenter.stopMainRemoteView(getSpeakerId());
  1426. presenter.startSubRemoteView(getSpeakerId(), isPcClientLive, mVideoView);
  1427. return;
  1428. }
  1429. }
  1430. @Override
  1431. public void enterLiveRoomError() {
  1432. }
  1433. @Override
  1434. public void onExitRoomSuccess() {
  1435. Log.i("pq", "onExitRoomSuccess");
  1436. currentSeatStatus = LiveRoomMsgConstants.MIC_STATUS_NORMAL;
  1437. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
  1438. if (!TextUtils.isEmpty(mUserId)) {
  1439. notifyMicContainerDel(mUserId);
  1440. }
  1441. if (presenter != null) {
  1442. presenter.stopAllRemoteView(getSpeakerId());
  1443. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_DOWN_SEAT_MIC);
  1444. }
  1445. play();
  1446. }
  1447. @Override
  1448. public void onStopPublishing() {
  1449. }
  1450. @Override
  1451. public void onPublishSuccess() {
  1452. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS);
  1453. if (mMicManagerDialog != null) {
  1454. mMicManagerDialog.dismiss();
  1455. }
  1456. }
  1457. @Override
  1458. public void onRemoteUserEnterRoom(String userId) {
  1459. if (!TextUtils.equals(userId, getSpeakerId())) {
  1460. Log.i("pq", "onRemoteUserEnterRoom:" + userId);
  1461. notifyMicContainerAdd(userId);
  1462. }
  1463. }
  1464. @Override
  1465. public void onRemoteUserLeaveRoom(String userId, int reason) {
  1466. if (!TextUtils.equals(userId, getSpeakerId())) {
  1467. Log.i("pq", "onRemoteUserLeaveRoom:" + userId);
  1468. notifyMicContainerDel(userId);
  1469. }
  1470. }
  1471. @Override
  1472. public void onStatistics(TRTCStatistics statistics) {
  1473. }
  1474. @Override
  1475. public void getFriendInfoSuccess(FriendInfoBean friendInfoBean) {
  1476. if (isFinishing() || isDestroyed()) {
  1477. return;
  1478. }
  1479. if (mLlMicContainer != null && friendInfoBean != null) {
  1480. String friendAvatar = friendInfoBean.getFriendAvatar();
  1481. mLlMicContainer.updateTargetUserInfo(new TTUserInfo(friendInfoBean.getImFriendId(), friendInfoBean.friendNickname, !TextUtils.isEmpty(friendAvatar) ? Uri.parse(friendAvatar) : null));
  1482. }
  1483. }
  1484. @Override
  1485. public void receiveSEIMsg(String userId, byte[] data) {
  1486. if (TextUtils.equals(userId, getSpeakerId())) {
  1487. // parseSeiMessage(new String(data));
  1488. }
  1489. }
  1490. @Override
  1491. public void onGroupAttributeChanged(String groupID, Map<String, String> groupAttributeMap) {
  1492. if (TextUtils.equals(groupID, mRoomId)) {
  1493. JSONObject jsonObject = new JSONObject(groupAttributeMap);
  1494. parseGroupAttribute(jsonObject);
  1495. }
  1496. }
  1497. @Override
  1498. public void onGroupCounterChanged(String groupID, String key, long newValue) {
  1499. if (TextUtils.equals(groupID, mRoomId)) {
  1500. if (TextUtils.equals(TTLiveConfig.LIVE_ROOM_LIKES_KEY, key)) {
  1501. //点赞数同步
  1502. Log.i("pq", "likes newValue:" + newValue);
  1503. updateAddLikeCountView(newValue);
  1504. }
  1505. }
  1506. }
  1507. @Override
  1508. public void getAllGroupCounterSuccess(Map<String, Long> map) {
  1509. if (!checkActivityExist()) {
  1510. return;
  1511. }
  1512. if (map != null && map.size() > 0) {
  1513. //获取群点赞数
  1514. if (map.containsKey(TTLiveConfig.LIVE_ROOM_LIKES_KEY)) {
  1515. Long result = map.get(TTLiveConfig.LIVE_ROOM_LIKES_KEY);
  1516. if (result != null) {
  1517. updateAddLikeCountView(result);
  1518. }
  1519. }
  1520. }
  1521. }
  1522. @Override
  1523. public void onMicStatusControl(String userId, boolean muteMic) {
  1524. if (!checkActivityExist()) {
  1525. return;
  1526. }
  1527. if (!isOwn(userId)) {
  1528. return;
  1529. }
  1530. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, muteMic ? "主讲人已将您的麦克风关闭" : "主讲人已将您的麦克风开启");
  1531. changeMicStatus(userId, muteMic);
  1532. }
  1533. @Override
  1534. public void onUserAudioAvailable(String userId, boolean available) {
  1535. if (!checkActivityExist()) {
  1536. return;
  1537. }
  1538. if (mLlMicContainer != null) {
  1539. mLlMicContainer.updateTargetUserMicStatus(userId, available ? TTLiveConfig.LIVE_ROOM_MIC_STATUS_OFF_VALUE : TTLiveConfig.LIVE_ROOM_MIC_STATUS_ON_VALUE);
  1540. }
  1541. }
  1542. @Override
  1543. public void onLiveForceKick(TCLiveForceKickMessage messageContent) {
  1544. if (!checkActivityExist()) {
  1545. return;
  1546. }
  1547. if (messageContent != null) {
  1548. ArrayList<String> targetIds = messageContent.getTargetIds();
  1549. if (targetIds != null && targetIds.size() > 0) {
  1550. //判断个人
  1551. for (int i = 0; i < targetIds.size(); i++) {
  1552. boolean isContainerOwner = isOwn(targetIds.get(i));
  1553. if (isContainerOwner) {
  1554. liveRoomOffline();
  1555. showLiveCourseStatusChangeTip(messageContent.getReason());
  1556. return;
  1557. }
  1558. }
  1559. } else {
  1560. //全体
  1561. liveRoomOffline();
  1562. showLiveCourseStatusChangeTip(messageContent.getReason());
  1563. }
  1564. }
  1565. }
  1566. private void showLiveCourseStatusChangeTip(String tip) {
  1567. if (TextUtils.isEmpty(tip)) {
  1568. tip = "当前课程已调整,请退出直播间";
  1569. }
  1570. CommonConfirmDialog confirmDialog = new CommonConfirmDialog(this);
  1571. confirmDialog.show();
  1572. confirmDialog.setOnConfirmClickListener(new View.OnClickListener() {
  1573. @Override
  1574. public void onClick(View v) {
  1575. finish();
  1576. }
  1577. });
  1578. confirmDialog.setContent(tip);
  1579. confirmDialog.hideCancel();
  1580. confirmDialog.setCancelable(false);
  1581. confirmDialog.setCanceledOnTouchOutside(false);
  1582. }
  1583. @Override
  1584. public void getAllGroupAttributesSuccess(Object o) {
  1585. Log.i("pq", "getAllGroupAttributesSuccess:" + o.toString());
  1586. if (o == null) {
  1587. return;
  1588. }
  1589. try {
  1590. JSONObject jsonObject = new JSONObject(o.toString());
  1591. parseGroupAttribute(jsonObject);
  1592. } catch (JSONException e) {
  1593. e.printStackTrace();
  1594. }
  1595. }
  1596. private void parseGroupAttribute(JSONObject groupAttributeJson) {
  1597. Log.i("pq", "group:" + groupAttributeJson.toString());
  1598. if (groupAttributeJson != null) {
  1599. //主播状态
  1600. checkAnchorStatus(groupAttributeJson);
  1601. // //点赞数
  1602. // getLikesFromAttributes(groupAttributeJson);
  1603. //人数
  1604. getMemberCountFromAttributes(groupAttributeJson);
  1605. //全局禁言状态
  1606. getGlobalBanStatus(groupAttributeJson);
  1607. //全员闭麦模式
  1608. getMuteAllMicStatus(groupAttributeJson);
  1609. }
  1610. }
  1611. private void getMuteAllMicStatus(JSONObject groupAttributeJson) {
  1612. String muteAllMicStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_MIC_STATUS_MODE_KEY);
  1613. if (!TextUtils.isEmpty(muteAllMicStatus)) {
  1614. Log.i("pq", " groupAttribute muteAllMicStatus:" + muteAllMicStatus);
  1615. boolean result = TextUtils.equals(muteAllMicStatus, TTLiveConfig.STATUS_ON);
  1616. if (result != isMuteAllMic) {
  1617. //有变化
  1618. if (isOnMic()) {
  1619. changeMicStatus(mUserId, result);
  1620. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, result ? "主讲人已将您的麦克风关闭" : "主讲人已将您的麦克风开启");
  1621. }
  1622. }
  1623. isMuteAllMic = result;
  1624. }
  1625. }
  1626. private void getGlobalBanStatus(JSONObject groupAttributeJson) {
  1627. String globalBanStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_GLOBAL_BAN_KEY);
  1628. if (!TextUtils.isEmpty(globalBanStatus)) {
  1629. Log.i("pq", " groupAttribute globalBanStatus:" + globalBanStatus);
  1630. if (TextUtils.equals(globalBanStatus, TTLiveConfig.STATUS_ON)) {
  1631. //全局禁言开启
  1632. isEnableChat = true;
  1633. } else {
  1634. isEnableChat = false;
  1635. }
  1636. }
  1637. }
  1638. private void getCameraStatus(JSONObject groupAttributeJson) {
  1639. String cameraStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_ANCHOR_CAMERA_KEY);
  1640. if (!TextUtils.isEmpty(cameraStatus)) {
  1641. Log.i("pq", " groupAttribute cameraStatus:" + cameraStatus);
  1642. if (TextUtils.equals(cameraStatus, TTLiveConfig.STATUS_OFF)) {
  1643. //主播关闭摄像头
  1644. showLiveStatusView(LIVE_STATUS_IS_CLOSE_VIDEO);
  1645. } else {
  1646. hideLiveCameraStatus();
  1647. }
  1648. }
  1649. }
  1650. private void getMemberCountFromAttributes(JSONObject groupAttributeMap) {
  1651. String member_online = groupAttributeMap.optString(TTLiveConfig.LIVE_ROOM_MEMBER_ONLINE_KEY);
  1652. Log.i("pq", "member_online:" + member_online);
  1653. if (!TextUtils.isEmpty(member_online)) {
  1654. setPeopleCount(member_online);
  1655. }
  1656. }
  1657. private void getLikesFromAttributes(JSONObject groupAttributeJson) {
  1658. String likes = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_LIKES_KEY);
  1659. Log.i("pq", "likes:" + likes);
  1660. if (!TextUtils.isEmpty(likes)) {
  1661. try {
  1662. int i = Integer.parseInt(likes);
  1663. updateAddLikeCountView(i);
  1664. } catch (Exception e) {
  1665. e.printStackTrace();
  1666. }
  1667. }
  1668. }
  1669. private void checkAnchorStatus(JSONObject groupAttributeJson) {
  1670. if (liveIsFinish) {
  1671. return;
  1672. }
  1673. String anchorStatus = groupAttributeJson.optString(TTLiveConfig.LIVE_ROOM_LIVE_STATUS_KEY);
  1674. Log.i("pq", "checkAnchorStatus:" + anchorStatus);
  1675. if (TextUtils.isEmpty(anchorStatus)) {
  1676. return;
  1677. }
  1678. if (TextUtils.equals(anchorStatus, TTLiveConfig.STATUS_ON)) {
  1679. //如果在线
  1680. anchorIsOnline = true;
  1681. TCStudentLiveRoomActivity.this.liveIsPause = false;
  1682. play();
  1683. //主播摄像头状态
  1684. getCameraStatus(groupAttributeJson);
  1685. } else {
  1686. //不在线
  1687. anchorIsOnline = false;
  1688. showLiveStatusView(LIVE_STATUS_IS_REST);
  1689. mLlMicContainer.delAll();
  1690. handleCloseMicEvent();
  1691. }
  1692. }
  1693. private void updateMicIcon(int micStatus) {
  1694. //主线程更新
  1695. iv_mic.post(new Runnable() {
  1696. @Override
  1697. public void run() {
  1698. currentSeatStatus = micStatus;
  1699. if (micStatus == LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
  1700. iv_mic.setImageResource(R.drawable.icon_mic_unconnect);
  1701. }
  1702. if (micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING) {
  1703. iv_mic.setImageResource(R.drawable.icon_mic_connecting);
  1704. }
  1705. if (micStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS) {
  1706. iv_mic.setImageResource(R.drawable.icon_mic_conected);
  1707. }
  1708. }
  1709. });
  1710. }
  1711. /**
  1712. * 关闭一些交互弹窗
  1713. */
  1714. private void hideDialog() {
  1715. //关闭邀请弹窗
  1716. if (mInviteSeatMicTipDialog != null && mInviteSeatMicTipDialog.isShowing()) {
  1717. mInviteSeatMicTipDialog.dismiss();
  1718. }
  1719. //关闭商品弹窗
  1720. if (mShopCarDialog != null && mShopCarDialog.isShowing()) {
  1721. mShopCarDialog.dismiss();
  1722. }
  1723. }
  1724. private void showLiveStatusView(int status) {
  1725. Log.i("pq", "showLiveStatusView:" + status);
  1726. if (isFinishing() || isDestroyed()) {
  1727. return;
  1728. }
  1729. if (mViewLiveStatus == null) {
  1730. return;
  1731. }
  1732. //显示视频画面已经关闭页面
  1733. mViewLiveStatus.post(new Runnable() {
  1734. @Override
  1735. public void run() {
  1736. mViewLiveStatus.setVisibility(status == LIVE_STATUS_IS_CLOSE_VIDEO ? View.GONE : View.VISIBLE);
  1737. if (status == LIVE_STATUS_IS_REST) {
  1738. group_loading.setVisibility(View.GONE);
  1739. tv_retry.setVisibility(View.GONE);
  1740. group_tip.setVisibility(View.VISIBLE);
  1741. hideLiveCameraStatus();
  1742. stopPlay();
  1743. mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_room_rest_bg);
  1744. mTvLiveStatusTipText.setText("休息一下,马上回来!");
  1745. mTvLiveStatusTipText.setTextSize(12);
  1746. mTvLiveStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
  1747. } else if (status == LIVE_STATUS_IS_CLOSE_VIDEO) {
  1748. viewLiveCameraStatus.setVisibility(View.VISIBLE);
  1749. mIvLiveStatusCameraCenterIcon.setImageResource(R.drawable.icon_live_room_close_video);
  1750. mTvLiveCameraStatusTipText.setText("主讲人已关闭画面!");
  1751. mTvLiveCameraStatusTipText.setTextSize(12);
  1752. mTvLiveCameraStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
  1753. } else if (status == LIVE_STATUS_IS_OFFLINE) {
  1754. group_loading.setVisibility(View.GONE);
  1755. tv_retry.setVisibility(View.GONE);
  1756. group_tip.setVisibility(View.VISIBLE);
  1757. hideLiveCameraStatus();
  1758. stopPlay();
  1759. mLlMicContainer.delAll();
  1760. mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_end_tip);
  1761. mTvLiveStatusTipText.setText("直播已结束!");
  1762. mTvLiveStatusTipText.setTextSize(14);
  1763. mTvLiveStatusTipText.setBackgroundColor(Color.TRANSPARENT);
  1764. } else if (status == LIVE_STATUS_LOADING) {
  1765. group_loading.setVisibility(View.VISIBLE);
  1766. group_tip.setVisibility(View.GONE);
  1767. tv_retry.setVisibility(View.GONE);
  1768. tv_loading.setText("视频加载中");
  1769. } else if (status == LIVE_STATUS_ERROR) {
  1770. group_loading.setVisibility(View.GONE);
  1771. tv_retry.setVisibility(View.VISIBLE);
  1772. group_tip.setVisibility(View.VISIBLE);
  1773. hideLiveCameraStatus();
  1774. stopPlay();
  1775. mIvLiveStatusCenterIcon.setImageResource(R.drawable.icon_live_room_close_video);
  1776. mTvLiveStatusTipText.setText("视频加载失败");
  1777. mTvLiveStatusTipText.setTextSize(14);
  1778. mTvLiveStatusTipText.setBackgroundResource(R.drawable.shape_gray_14dp);
  1779. }
  1780. }
  1781. });
  1782. }
  1783. private void stopPlay() {
  1784. if (mMLivePlayer != null) {
  1785. mMLivePlayer.stopPlay();
  1786. }
  1787. }
  1788. /**
  1789. * 取消连麦
  1790. */
  1791. private void handleCloseMicEvent() {
  1792. if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING) {
  1793. //连接中取消连接
  1794. if (presenter != null) {
  1795. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_CANCEL_SEAT_APPLY, getSpeakerId(), getSpeakerName());
  1796. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_NORMAL);
  1797. }
  1798. }
  1799. if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS) {
  1800. if (presenter != null) {
  1801. presenter.exitRoom();
  1802. }
  1803. }
  1804. }
  1805. @Override
  1806. protected void onResume() {
  1807. super.onResume();
  1808. this.isOnResume = true;
  1809. unbindService();
  1810. //取消全部静音
  1811. if (!isMuteAll) {
  1812. muteAll(false);
  1813. }
  1814. // if (mMLivePlayer != null) {
  1815. // mMLivePlayer.resumeAudio();
  1816. // mMLivePlayer.resumeVideo();
  1817. // }
  1818. }
  1819. @Override
  1820. protected void onPause() {
  1821. super.onPause();
  1822. isOnResume = false;
  1823. sendShowFloatWindowAction(SEND_APP_BACKGROUND_MSG);
  1824. // if (mMLivePlayer != null) {
  1825. // mMLivePlayer.pauseVideo();
  1826. // mMLivePlayer.pauseAudio();
  1827. // }
  1828. }
  1829. private void sendShowFloatWindowAction(int what) {
  1830. android.os.Message message = android.os.Message.obtain();
  1831. message.what = what;
  1832. mHandler.sendMessageDelayed(message, SEND_SHOW_FLOAT_WINDOW_TIME);
  1833. }
  1834. @Override
  1835. protected TTLiveRoomPresenter createPresenter() {
  1836. return new TTLiveRoomPresenter();
  1837. }
  1838. @Override
  1839. public void getRoomInfoSuccess(LiveRoomInfoBean roomInfo) {
  1840. if (!checkActivityExist()) {
  1841. return;
  1842. }
  1843. if (roomInfo != null) {
  1844. this.roomInfo = roomInfo;
  1845. LOG.i(TAG, "getRoomInfoSuccess:" + roomInfo.toString());
  1846. String userSig = roomInfo.getUserSig();
  1847. if (!TextUtils.isEmpty(userSig)) {
  1848. presenter.connectIM(mUserId, userSig);
  1849. // play();
  1850. }
  1851. isPcClientLive = TextUtils.equals(roomInfo.getOs(), "pc") || TextUtils.equals(roomInfo.getOs(), "client");
  1852. mMLivePlayer.setRenderFillMode(isPcClientLive ? V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit : V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill);
  1853. resetVideoContainer(!isPcClientLive);
  1854. // if (!TextUtils.isEmpty(roomInfo.roomConfig)) {
  1855. // try {
  1856. // JSONObject jsonObject = new JSONObject(roomInfo.roomConfig);
  1857. // //聊天模式
  1858. // int chatCtrlMode = jsonObject.optInt("whether_chat", 0);
  1859. // //连麦模式
  1860. // int micCtrlMode = jsonObject.optInt("whether_mic", 0);
  1861. // //购物车是否显示
  1862. // int shopCarMode = jsonObject.optInt("whether_view_shop_cart", 0);
  1863. // isEnableChat = chatCtrlMode == 1;
  1864. // isEnableMic = micCtrlMode == 1;
  1865. //
  1866. //
  1867. // } catch (JSONException e) {
  1868. // e.printStackTrace();
  1869. // }
  1870. // }
  1871. if (TextUtils.isEmpty(roomInfo.getShopCarUrl())) {
  1872. //隐藏购物车
  1873. mViewShopCarAnim.setVisibility(View.GONE);
  1874. mIvShopCar.setVisibility(View.GONE);
  1875. } else {
  1876. //显示购物车
  1877. mViewShopCarAnim.setVisibility(View.VISIBLE);
  1878. mIvShopCar.setVisibility(View.INVISIBLE);
  1879. }
  1880. //黑名单模式
  1881. isEnableAll = roomInfo.blacklistFlag == 1;//1是黑名单 0否
  1882. updateInputTip();
  1883. updateAddLikeCountView(roomInfo.likeNum);
  1884. if (mTvNumPeople != null) {
  1885. // int peopleCount = roomInfo.lookNum + 1;//加上自己
  1886. setPeopleCount(String.valueOf(roomInfo.lookNum));
  1887. }
  1888. if (mIvAvatar != null) {
  1889. //创建人头像
  1890. Glide.with(TCStudentLiveRoomActivity.this).load(roomInfo.speakerPic).placeholder(R.drawable.icon_default_head).error(R.drawable.icon_default_head).into(mIvAvatar);
  1891. }
  1892. if (mTvRoomCreateName != null) {
  1893. //创建人昵称
  1894. mTvRoomCreateName.setText(roomInfo.speakerName);
  1895. }
  1896. if (mMessageAdapter != null) {
  1897. mMessageAdapter.setRoomAuthorId(roomInfo.speakerId);
  1898. }
  1899. }
  1900. }
  1901. @Override
  1902. public void getRoomInfoError(Throwable throwable) {
  1903. if (!checkActivityExist()) {
  1904. return;
  1905. }
  1906. finish();
  1907. }
  1908. @Override
  1909. public void connectIMError(int errorCode, String errorMsg) {
  1910. hideLoading();
  1911. ToastUtil.getInstance().show(this, "加入直播间群聊异常,请退出重试");
  1912. }
  1913. @Override
  1914. public void loginIMSuccess() {
  1915. if (presenter != null) {
  1916. presenter.joinGroup(mRoomId);
  1917. }
  1918. }
  1919. @Override
  1920. public void joinGroupSuccess() {
  1921. hideLoading();
  1922. presenter.bindGroupListener();
  1923. presenter.getAllGroupAttributes(mRoomId);
  1924. presenter.getAllGroupCounter(mRoomId);
  1925. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_JOIN_ROOM);
  1926. presenter.notifyJoinRoomAction(mRoomId, mUserId);
  1927. }
  1928. private void play() {
  1929. if (roomInfo != null && roomInfo.getLiveRoomConfig() != null) {
  1930. if (isOnMic()) {
  1931. return;
  1932. }
  1933. if (liveIsPause || liveIsFinish || !anchorIsOnline) {
  1934. return;
  1935. }
  1936. if (mMLivePlayer.isPlaying() == 1) {
  1937. return;
  1938. }
  1939. //关键 player 对象与界面 view
  1940. mMLivePlayer.setRenderView(mVideoView);
  1941. LiveRoomInfoBean.LiveRoomConfigBean liveRoomConfig = roomInfo.getLiveRoomConfig();
  1942. String playUrl = getPlayUrl(liveRoomConfig.getPlayUrl(), roomInfo.getRoomId(), roomInfo.speakerImUserId);
  1943. Log.i("pq", "playUrl:" + playUrl);
  1944. showLiveStatusView(LIVE_STATUS_LOADING);
  1945. subVideoView.setVisibility(View.GONE);
  1946. mMLivePlayer.startLivePlay(playUrl);
  1947. }
  1948. }
  1949. private String getPlayUrl(String domain, String roomId, String targetId) {
  1950. StringBuilder stringBuilder = new StringBuilder();
  1951. stringBuilder.append("rtmp://")
  1952. .append(domain)
  1953. .append("/live/")
  1954. .append(roomId)
  1955. .append("_")
  1956. .append(targetId);
  1957. // String url = "rtmp://cdn1.dayaedu.com/live/12233333_LIVE?12233333_LIVE";
  1958. return stringBuilder.toString();
  1959. }
  1960. @Override
  1961. public void joinGroupError(int code, String des) {
  1962. hideLoading();
  1963. Log.i(TAG, "joinGroupError code:" + code + "des" + des);
  1964. ToastUtil.getInstance().show(this, "加入直播群组失败,请退出重试");
  1965. }
  1966. @Override
  1967. public void addMessageContent(TTMessage ttMessage) {
  1968. //添加单条消息至页面
  1969. Log.i("pq", "收到需要显示msg:" + ttMessage);
  1970. //只处理直播间消息,以及本直播间消息
  1971. if (mMessageAdapter != null) {
  1972. mMessageAdapter.addMessage(ttMessage);
  1973. if (mRecyclerMsg != null && mLinearLayoutManager != null) {
  1974. mRecyclerMsg.post(new Runnable() {
  1975. @Override
  1976. public void run() {
  1977. if (isAutoScrollToLast) {
  1978. if (mRecyclerMsg != null) {
  1979. mRecyclerMsg.scrollToPosition(mMessageAdapter.getItemCount() - 1);
  1980. }
  1981. } else {
  1982. Log.i("pq", "收到消息,不自动滚动");
  1983. }
  1984. }
  1985. });
  1986. }
  1987. }
  1988. }
  1989. private boolean isOnApplyMic() {
  1990. return currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING;
  1991. }
  1992. private boolean isOnMic() {
  1993. return currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECT_SUCCESS;
  1994. }
  1995. private void showMicManagerDialog() {
  1996. if (mMicManagerDialog == null) {
  1997. mMicManagerDialog = new LiveRoomMicManagerDialog(this);
  1998. mMicManagerDialog.setOnEventListener(new LiveRoomMicManagerDialog.OnEventListener() {
  1999. @Override
  2000. public void onApplyMic() {
  2001. //申请连麦
  2002. handleMicEvent();
  2003. mMicManagerDialog.setMicStatus(LiveRoomMsgConstants.MIC_STATUS_CONNECTING);
  2004. mMicManagerDialog.dismiss();
  2005. }
  2006. @Override
  2007. public void onApplyCancel() {
  2008. //取消申请连麦
  2009. handleMicEvent();
  2010. }
  2011. @Override
  2012. public void onCloseMic() {
  2013. //关闭连麦
  2014. handleMicEvent();
  2015. }
  2016. });
  2017. }
  2018. if (!mMicManagerDialog.isShowing()) {
  2019. mMicManagerDialog.show();
  2020. }
  2021. if (roomInfo != null) {
  2022. mMicManagerDialog.setLiveTeacherInfo(roomInfo.speakerPic);
  2023. }
  2024. mMicManagerDialog.setMicStatus(currentSeatStatus);
  2025. }
  2026. private void handleMicEvent() {
  2027. if (currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_NORMAL) {
  2028. //未连麦状态 申请连麦
  2029. if (presenter != null) {
  2030. presenter.handleAction(LiveRoomMsgConstants.ACTION_SEND_SEAT_APPLY, getSpeakerId(), getSpeakerName());
  2031. }
  2032. updateMicIcon(LiveRoomMsgConstants.MIC_STATUS_CONNECTING);
  2033. } else {
  2034. //取消连麦
  2035. showCloseMicTipDialog();
  2036. }
  2037. }
  2038. public String getSpeakerId() {
  2039. if (roomInfo != null) {
  2040. return roomInfo.speakerImUserId;
  2041. }
  2042. return "";
  2043. }
  2044. public String getSpeakerName() {
  2045. if (roomInfo != null) {
  2046. return roomInfo.speakerName;
  2047. }
  2048. return "";
  2049. }
  2050. private void showCloseMicTipDialog() {
  2051. if (mRoomCloseMicTipDialog == null) {
  2052. mRoomCloseMicTipDialog = new LiveRoomCloseMicTipDialog(this);
  2053. mRoomCloseMicTipDialog.setConfirmClickListener(new View.OnClickListener() {
  2054. @Override
  2055. public void onClick(View v) {
  2056. handleCloseMicEvent();
  2057. mRoomCloseMicTipDialog.dismiss();
  2058. if (mMicManagerDialog != null) {
  2059. mMicManagerDialog.dismiss();
  2060. }
  2061. }
  2062. });
  2063. }
  2064. if (!mRoomCloseMicTipDialog.isShowing()) {
  2065. mRoomCloseMicTipDialog.show();
  2066. }
  2067. mRoomCloseMicTipDialog.setContent(getString(currentSeatStatus == LiveRoomMsgConstants.MIC_STATUS_CONNECTING ? R.string.cancel_seat_on_connecting : R.string.cancel_seat_on_connected));
  2068. }
  2069. /**
  2070. * 检查聊天模式
  2071. */
  2072. public boolean checkChatMode() {
  2073. if (liveIsFinish) {
  2074. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
  2075. return true;
  2076. }
  2077. if (isEnableAll) {
  2078. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
  2079. return true;
  2080. }
  2081. if (isEnableChat) {
  2082. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "管理员关闭聊天");
  2083. return true;
  2084. }
  2085. return false;
  2086. }
  2087. /**
  2088. * 检查mic模式
  2089. */
  2090. public boolean checkMicMode() {
  2091. if (!anchorIsOnline) {
  2092. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
  2093. return true;
  2094. }
  2095. if (liveIsPause) {
  2096. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
  2097. return true;
  2098. }
  2099. if (liveIsFinish) {
  2100. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
  2101. return true;
  2102. }
  2103. if (isEnableAll) {
  2104. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
  2105. return true;
  2106. }
  2107. if (isEnableMic) {
  2108. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "管理员关闭连麦申请");
  2109. return true;
  2110. }
  2111. return false;
  2112. }
  2113. /**
  2114. * 检查mic模式
  2115. */
  2116. public boolean checkMicMode2() {
  2117. if (!anchorIsOnline) {
  2118. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
  2119. return true;
  2120. }
  2121. if (liveIsPause) {
  2122. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "老师暂停中,暂时无法接受申请");
  2123. return true;
  2124. }
  2125. if (liveIsFinish) {
  2126. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "直播已结束");
  2127. return true;
  2128. }
  2129. if (isEnableAll) {
  2130. ToastUtil.getInstance().show(TCStudentLiveRoomActivity.this, "您已被管理员禁言");
  2131. return true;
  2132. }
  2133. return false;
  2134. }
  2135. @Override
  2136. public void finish() {
  2137. super.finish();
  2138. //前置通知离开接口
  2139. notifyLeave();
  2140. }
  2141. private void notifyLeave() {
  2142. if (presenter != null) {
  2143. //通知离开房间
  2144. presenter.notifyLeaveRoomAction();
  2145. }
  2146. }
  2147. @Override
  2148. public void onSoftInputChanged(int height) {
  2149. Log.i("pq", "height" + height);
  2150. if (height == 0) {
  2151. //软键盘隐藏
  2152. Log.i("pq", "SoftInput hide");
  2153. if (mInputBarDialog != null && mInputBarDialog.isShowing()) {
  2154. mInputBarDialog.dismiss();
  2155. }
  2156. } else {
  2157. //软键盘弹出
  2158. Log.i("pq", "SoftInput show");
  2159. }
  2160. }
  2161. @Override
  2162. public void onDestroy() {
  2163. if (presenter != null) {
  2164. presenter.release();
  2165. }
  2166. super.onDestroy();
  2167. if (mHandler != null) {
  2168. mHandler.removeCallbacksAndMessages(null);
  2169. }
  2170. if (mMLivePlayer != null) {
  2171. mMLivePlayer.stopPlay();
  2172. }
  2173. //取消动画
  2174. if (hideHeaderInfoAnim != null) {
  2175. hideHeaderInfoAnim.cancel();
  2176. hideHeaderInfoAnim = null;
  2177. }
  2178. if (showHeaderInfoAnim != null) {
  2179. showHeaderInfoAnim.cancel();
  2180. showHeaderInfoAnim = null;
  2181. }
  2182. SoftKeyboardUtil.unregisterSoftInputChangedListener(getWindow());
  2183. LiveRoomAnimatorHelper.getInstance().releaseAnimator();
  2184. LiveRoomAddLikeHelper.getInstance().release();
  2185. TRTCSdkManager.getInstance().release();
  2186. TCIMSdkManager.getInstance().quitGroup(mRoomId);
  2187. TCIMSdkManager.getInstance().release(mTIMSDKListener);
  2188. }
  2189. }