diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 6f4c447c6..1a522d0c3 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -292,3 +292,5 @@ rx.internal.util.atomic.LinkedQueueNode* consumerNode;
-keep class com.shayu.lib_google.**{*;}
-keep class com.shayu.lib_huawei.**{*;}
+
+-keep class io.agora.**{*;}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ded4c2c0f..8d8a3325c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -89,6 +89,11 @@
+
+
+
+
+
diff --git a/common/build.gradle b/common/build.gradle
index d59049c32..b69c7b668 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -225,6 +225,7 @@ dependencies {
api 'com.github.FlyJingFish:GradientTextView:1.2.4'
//轮播 一屏显示多个
api 'com.github.xiaohaibin:XBanner:androidx_v1.2.6'
-
+ //声网SDK
+ api 'io.agora.rtc:agora-special-full:4.1.1.28'
}
diff --git a/common/src/main/java/com/yunbao/common/CommonAppConfig.java b/common/src/main/java/com/yunbao/common/CommonAppConfig.java
index 6b1a7119d..2f447a77e 100644
--- a/common/src/main/java/com/yunbao/common/CommonAppConfig.java
+++ b/common/src/main/java/com/yunbao/common/CommonAppConfig.java
@@ -77,7 +77,6 @@ public class CommonAppConfig {
public static int alert_time = 1;
public static int alert_end_time = 1;
-
private CommonAppConfig() {
}
diff --git a/common/src/main/java/com/yunbao/common/manager/SWAuManager.java b/common/src/main/java/com/yunbao/common/manager/SWAuManager.java
new file mode 100644
index 000000000..7a3b9741e
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/manager/SWAuManager.java
@@ -0,0 +1,147 @@
+package com.yunbao.common.manager;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.SurfaceView;
+import android.widget.FrameLayout;
+
+import com.yunbao.common.CommonAppContext;
+import com.yunbao.common.manager.base.BaseCacheManager;
+import com.yunbao.common.utils.StringUtil;
+
+import io.agora.rtc2.ChannelMediaOptions;
+import io.agora.rtc2.Constants;
+import io.agora.rtc2.IRtcEngineEventHandler;
+import io.agora.rtc2.RtcEngine;
+import io.agora.rtc2.RtcEngineConfig;
+import io.agora.rtc2.video.VideoCanvas;
+
+/**
+ * 声网主播管理类
+ */
+public class SWAuManager extends BaseCacheManager {
+
+ // 填写项目的 App ID,可在声网控制台中生成
+ public static final String shengwang_appId = "4cf0376582d742ac8a96778b25b1079e";
+ // 填写频道名
+ public static final String shengwang_channelName = "12";
+ // 填写声网控制台中生成的临时 Token
+ public static final String shengwang_token = "007eJxSYJi477Xju22xV7ov7GfzzOnbtCU0IuK9+YuwWf2uLPGnl8xRYDBJTjMwNjcztTBKMTcxSky2SLQ0Mze3SDIyTTI0MLdMPWQrltYQyMjw/4kCCyMDBIL4TAyGRiwMlpaWloAAAAD//w/TIFY=";
+ private Activity mContext;
+ public static SWAuManager manager;
+ private RtcEngine mRtcEngine;
+ private FrameLayout audienceContainer; //主播视图
+ private FrameLayout pkContainer1; //pk主播视图1
+ private FrameLayout pkContainer2; //pk主播视图2
+ private FrameLayout pkContainer3; //pk主播视图3
+ private FrameLayout linkUserContainer;//连麦用户视图
+
+ public SWAuManager(Context context) {
+ super(context);
+ }
+
+ /**
+ * 获取单列
+ *
+ * @return
+ */
+ public static SWAuManager get() {
+ if (null == manager) {
+ manager = new SWAuManager(CommonAppContext.sInstance.getBaseContext());
+ }
+ return manager;
+ }
+
+ /**
+ * 初始化声网SDK
+ */
+ public void initRtcEngine(Activity mContext) {
+ this.mContext = mContext;
+ try {
+ // 创建 RtcEngineConfig 对象,并进行配置
+ RtcEngineConfig config = new RtcEngineConfig();
+ config.mContext = mContext;
+ config.mAppId = SWAuManager.shengwang_appId;
+ config.mEventHandler = mRtcEventHandler;
+ // 创建并初始化 RtcEngine
+ mRtcEngine = RtcEngine.create(config);
+ } catch (Exception e) {
+ throw new RuntimeException("Check the error.");
+ }
+ mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING); // 直播模式,引擎級別
+ // 启用视频模块
+ mRtcEngine.enableVideo();
+ // 开启本地预览
+ //mRtcEngine.startPreview();
+ }
+
+ /**
+ * guanzhong
+ * 加入房间
+ */
+ public void joinRoom(String strUid, String token, String channelName) {
+ int uid;
+ if (StringUtil.isEmpty(strUid)) {
+ uid = 0;
+ } else {
+ uid = Integer.parseInt(strUid);
+ }
+ // 创建一个 SurfaceView 对象,并将其作为 FrameLayout 的子对象
+ SurfaceView surfaceView = new SurfaceView(mContext);
+ audienceContainer.addView(surfaceView);
+
+ // 创建 ChannelMediaOptions 对象,并进行配置
+ ChannelMediaOptions options = new ChannelMediaOptions();
+ // 根据场景将用户角色设置为 AUDIENCE (观众)
+ options.clientRoleType = Constants.CLIENT_ROLE_AUDIENCE;
+ // 直播场景下,设置频道场景为 BROADCASTING (直播场景)
+ options.audienceLatencyLevel = Constants.AUDIENCE_LATENCY_LEVEL_LOW_LATENCY; // 觀眾走極速直播
+
+ // 使用临时 Token 加入频道,自行指定用户 ID 并确保其在频道内的唯一性
+ mRtcEngine.joinChannel(token, channelName, uid, options);
+ }
+
+ //远程监听
+ private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
+ @Override
+ // 监听频道内的远端用户,获取用户的 uid 信息
+ public void onUserJoined(int uid, int elapsed) {
+ mContext.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // 获取 uid 后,设置远端视频视图
+ setupRemoteVideo(uid);
+ }
+ });
+ }
+ };
+
+ //设置对方主播视图
+ public void setupRemoteVideo(int uid) {
+ SurfaceView surfaceView = new SurfaceView(mContext);
+ surfaceView.setZOrderMediaOverlay(true);
+ audienceContainer.addView(surfaceView);
+ // 将 SurfaceView 对象传入声网实时互动 SDK,设置远端视图
+ mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
+ }
+
+ public void setAudienceContainer(FrameLayout audienceContainer) {
+ this.audienceContainer = audienceContainer;
+ }
+
+ public void setPkContainer1(FrameLayout pkContainer1) {
+ this.pkContainer1 = pkContainer1;
+ }
+
+ public void setPkContainer2(FrameLayout pkContainer2) {
+ this.pkContainer2 = pkContainer2;
+ }
+
+ public void setPkContainer3(FrameLayout pkContainer3) {
+ this.pkContainer3 = pkContainer3;
+ }
+
+ public void setLinkUserContainer(FrameLayout linkUserContainer) {
+ this.linkUserContainer = linkUserContainer;
+ }
+}
diff --git a/common/src/main/java/com/yunbao/common/manager/SWManager.java b/common/src/main/java/com/yunbao/common/manager/SWManager.java
new file mode 100644
index 000000000..a97d85b9b
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/manager/SWManager.java
@@ -0,0 +1,207 @@
+package com.yunbao.common.manager;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.SurfaceView;
+import android.widget.FrameLayout;
+
+import com.yunbao.common.CommonAppContext;
+import com.yunbao.common.manager.base.BaseCacheManager;
+import com.yunbao.common.utils.StringUtil;
+import com.yunbao.common.utils.ToastUtil;
+
+import cn.rongcloud.rtc.base.RCRTCParamsType;
+import io.agora.rtc2.ChannelMediaOptions;
+import io.agora.rtc2.Constants;
+import io.agora.rtc2.IRtcEngineEventHandler;
+import io.agora.rtc2.RtcEngine;
+import io.agora.rtc2.RtcEngineConfig;
+import io.agora.rtc2.video.VideoCanvas;
+import io.agora.rtc2.video.VideoEncoderConfiguration;
+
+/**
+ * 声网主播管理类
+ */
+public class SWManager extends BaseCacheManager {
+
+ // 填写项目的 App ID,可在声网控制台中生成
+ public static final String shengwang_appId = "4cf0376582d742ac8a96778b25b1079e";
+ // 填写频道名
+ public static final String shengwang_channelName = "12";
+ // 填写声网控制台中生成的临时 Token
+ public static final String shengwang_token = "007eJxTYOD6Iv3buTHm6666BKY1Cr7mUZU3tY0eHH5qbF4jv5nNukqBwSQ5zcDY3MzUwijF3MQoMdki0dLM3Nwiycg0ydDA3DL1xX/RtIZARgb+3ExWRgYIBPGZGAyNGBgAhDMb8Q==";
+ private Activity mContext;
+ public static SWManager manager;
+ private RtcEngine mRtcEngine;
+ private int uid;
+ VideoEncoderConfiguration cfg;
+ private FrameLayout anchorContainer; //主播视图
+ private FrameLayout pkContainer1; //pk主播视图1
+ private FrameLayout pkContainer2; //pk主播视图2
+ private FrameLayout pkContainer3; //pk主播视图3
+ private FrameLayout linkUserContainer;//连麦用户视图
+ private onRtcEngineListener onRtcEngineListener;
+
+ public void setOnRtcEngineListener(SWManager.onRtcEngineListener onRtcEngineListener) {
+ this.onRtcEngineListener = onRtcEngineListener;
+ }
+
+ public SWManager(Context context) {
+ super(context);
+ }
+
+ /**
+ * 获取单列
+ *
+ * @return
+ */
+ public static SWManager get() {
+ if (null == manager) {
+ manager = new SWManager(CommonAppContext.sInstance.getBaseContext());
+ }
+ return manager;
+ }
+
+ /**
+ * 初始化声网SDK
+ */
+ public void initRtcEngine(Activity mContext, String strUid) {
+ this.mContext = mContext;
+ if (StringUtil.isEmpty(strUid)) {
+ uid = 0;
+ } else {
+ uid = Integer.parseInt(strUid);
+ }
+ try {
+ // 创建 RtcEngineConfig 对象,并进行配置
+ RtcEngineConfig config = new RtcEngineConfig();
+ config.mContext = mContext;
+ config.mAppId = SWManager.shengwang_appId;
+ config.mEventHandler = mRtcEventHandler;
+ // 创建并初始化 RtcEngine
+ mRtcEngine = RtcEngine.create(config);
+ } catch (Exception e) {
+ throw new RuntimeException("Check the error.");
+ }
+ mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
+ // 启用视频模块
+ mRtcEngine.enableVideo();
+ // 开启本地预览
+ mRtcEngine.startPreview();
+
+ cfg = new VideoEncoderConfiguration();
+ //设置默认分辨率
+ switch (IMLoginManager.get(mContext).getSelectClarity()) {
+ case 0:
+ cfg.dimensions = VideoEncoderConfiguration.VD_840x480;
+ break;
+ case 1:
+ cfg.dimensions = VideoEncoderConfiguration.VD_1280x720;
+ break;
+ case 2:
+ cfg.dimensions = VideoEncoderConfiguration.VD_1920x1080;
+ break;
+ }
+ cfg.frameRate = 24;
+ cfg.bitrate = 0;
+ cfg.mirrorMode = VideoEncoderConfiguration.MIRROR_MODE_TYPE.MIRROR_MODE_ENABLED; //镜像
+ mRtcEngine.setVideoEncoderConfiguration(cfg);
+
+ // 创建一个 SurfaceView 对象,并将其作为 FrameLayout 的子对象
+ SurfaceView surfaceView = new SurfaceView(mContext);
+ anchorContainer.addView(surfaceView);
+ // 设置视图
+ mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
+ }
+
+ public void setDimensions(int selectClarity) {
+ if (cfg != null && mRtcEngine != null) {
+ switch (selectClarity) {
+ case 0:
+ cfg.dimensions = VideoEncoderConfiguration.VD_840x480;
+ break;
+ case 1:
+ cfg.dimensions = VideoEncoderConfiguration.VD_1280x720;
+ break;
+ case 2:
+ cfg.dimensions = VideoEncoderConfiguration.VD_1920x1080;
+ break;
+ }
+ mRtcEngine.setVideoEncoderConfiguration(cfg);
+ }
+ }
+
+
+ /**
+ * 创建房间
+ */
+ public void createRoom(String token, String channelName) {
+ ChannelMediaOptions options = new ChannelMediaOptions();
+ // 设置角色 BROADCASTER (主播) 或 AUDIENCE (观众)
+ options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
+ // 加入频道
+ mRtcEngine.joinChannel(token, channelName, uid, options);
+ }
+
+ //远程监听
+ private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
+ @Override
+ // 监听频道内的远端用户,获取用户的 uid 信息
+ public void onUserJoined(int uid, int elapsed) {
+ mContext.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // 获取 uid 后,设置远端视频视图
+ setupRemoteVideo(uid);
+ }
+ });
+ }
+
+ @Override
+ public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
+ super.onJoinChannelSuccess(channel, uid, elapsed);
+ if (onRtcEngineListener != null) {
+ onRtcEngineListener.onOpenSuccess(channel, uid);
+ }
+ }
+
+ @Override
+ public void onError(int err) {
+ super.onError(err);
+ ToastUtil.show("onError:" + err);
+ }
+ };
+
+ //设置对方主播视图
+ private void setupRemoteVideo(int uid) {
+ SurfaceView surfaceView = new SurfaceView(mContext);
+ surfaceView.setZOrderMediaOverlay(true);
+ pkContainer1.addView(surfaceView);
+ // 将 SurfaceView 对象传入声网实时互动 SDK,设置远端视图
+ mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid));
+ }
+
+ public void setAnchorContainer(FrameLayout anchorContainer) {
+ this.anchorContainer = anchorContainer;
+ }
+
+ public interface onRtcEngineListener {
+ void onOpenSuccess(String channel, int uid);
+ }
+
+ public void setPkContainer1(FrameLayout pkContainer1) {
+ this.pkContainer1 = pkContainer1;
+ }
+
+ public void setPkContainer2(FrameLayout pkContainer2) {
+ this.pkContainer2 = pkContainer2;
+ }
+
+ public void setPkContainer3(FrameLayout pkContainer3) {
+ this.pkContainer3 = pkContainer3;
+ }
+
+ public void setLinkUserContainer(FrameLayout linkUserContainer) {
+ this.linkUserContainer = linkUserContainer;
+ }
+}
diff --git a/live/src/main/AndroidManifest.xml b/live/src/main/AndroidManifest.xml
index 1af89a691..6c664cb33 100644
--- a/live/src/main/AndroidManifest.xml
+++ b/live/src/main/AndroidManifest.xml
@@ -124,6 +124,10 @@
+
+
\ No newline at end of file
diff --git a/live/src/main/java/com/yunbao/live/activity/NewLiveActivity.java b/live/src/main/java/com/yunbao/live/activity/NewLiveActivity.java
new file mode 100644
index 000000000..6dfb2bbf5
--- /dev/null
+++ b/live/src/main/java/com/yunbao/live/activity/NewLiveActivity.java
@@ -0,0 +1,139 @@
+package com.yunbao.live.activity;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.view.SurfaceView;
+import android.widget.FrameLayout;
+
+import android.os.Bundle;
+
+import com.yunbao.common.manager.SWManager;
+import com.yunbao.live.R;
+
+import io.agora.rtc2.ChannelMediaOptions;
+import io.agora.rtc2.Constants;
+import io.agora.rtc2.IRtcEngineEventHandler;
+import io.agora.rtc2.RtcEngine;
+import io.agora.rtc2.RtcEngineConfig;
+import io.agora.rtc2.video.VideoCanvas;
+
+
+public class NewLiveActivity extends AppCompatActivity {
+ private RtcEngine mRtcEngine;
+
+ private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
+ @Override
+ // 监听频道内的远端用户,获取用户的 uid 信息
+ public void onUserJoined(int uid, int elapsed) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // 获取 uid 后,设置远端视频视图
+ setupRemoteVideo(uid);
+ }
+ });
+ }
+ };
+
+ private void initializeAndJoinChannel() {
+ try {
+ // 创建 RtcEngineConfig 对象,并进行配置
+ RtcEngineConfig config = new RtcEngineConfig();
+ config.mContext = getBaseContext();
+ config.mAppId = SWManager.shengwang_appId;
+ config.mEventHandler = mRtcEventHandler;
+ // 创建并初始化 RtcEngine
+ mRtcEngine = RtcEngine.create(config);
+ } catch (Exception e) {
+ throw new RuntimeException("Check the error.");
+ }
+ // 启用视频模块
+ mRtcEngine.enableVideo();
+ // 开启本地预览
+ mRtcEngine.startPreview();
+
+ // 创建一个 SurfaceView 对象,并将其作为 FrameLayout 的子对象
+ FrameLayout container = findViewById(R.id.local_video_view_container);
+ SurfaceView surfaceView = new SurfaceView(getBaseContext());
+ container.addView(surfaceView);
+ // 将 SurfaceView 对象传入声网实时互动 SDK,设置本地视图
+ mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, 0));
+
+ // 创建 ChannelMediaOptions 对象,并进行配置
+ ChannelMediaOptions options = new ChannelMediaOptions();
+ // 根据场景将用户角色设置为 BROADCASTER (主播) 或 AUDIENCE (观众)
+ options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
+ // 直播场景下,设置频道场景为 BROADCASTING (直播场景)
+ options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
+
+ // 使用临时 Token 加入频道,自行指定用户 ID 并确保其在频道内的唯一性
+ mRtcEngine.joinChannel(SWManager.shengwang_token, SWManager.shengwang_channelName, 0, options);
+ }
+
+ private void setupRemoteVideo(int uid) {
+ FrameLayout container = findViewById(R.id.remote_video_view_container);
+ SurfaceView surfaceView = new SurfaceView(getBaseContext());
+ surfaceView.setZOrderMediaOverlay(true);
+ container.addView(surfaceView);
+ // 将 SurfaceView 对象传入声网实时互动 SDK,设置远端视图
+ mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid));
+ }
+
+ private static final int PERMISSION_REQ_ID = 22;
+
+ // 获取体验实时音视频互动所需的录音、摄像头等权限
+ private String[] getRequiredPermissions() {
+ // 判断 targetSDKVersion 31 及以上时所需的权限
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
+ return new String[]{
+ Manifest.permission.RECORD_AUDIO, // 录音权限
+ Manifest.permission.CAMERA, // 摄像头权限
+ Manifest.permission.READ_PHONE_STATE, // 读取电话状态权限
+ Manifest.permission.BLUETOOTH_CONNECT // 蓝牙连接权限
+ };
+ } else {
+ return new String[]{
+ Manifest.permission.RECORD_AUDIO,
+ Manifest.permission.CAMERA
+ };
+ }
+ }
+
+ private boolean checkPermissions() {
+ for (String permission : getRequiredPermissions()) {
+ int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
+ if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.acticity_new_live);
+ // 如果已经授权,则初始化 RtcEngine 并加入频道
+ initializeAndJoinChannel();
+ if (checkPermissions()) {
+ initializeAndJoinChannel();
+ } else {
+ ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSION_REQ_ID);
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ // 停止本地视频预览
+ mRtcEngine.stopPreview();
+
+ // 离开频道
+ mRtcEngine.leaveChannel();
+ }
+}
diff --git a/live/src/main/java/com/yunbao/live/views/LiveNewReadyRyViewHolder.java b/live/src/main/java/com/yunbao/live/views/LiveNewReadyRyViewHolder.java
index c40b07bf1..5863c3b91 100644
--- a/live/src/main/java/com/yunbao/live/views/LiveNewReadyRyViewHolder.java
+++ b/live/src/main/java/com/yunbao/live/views/LiveNewReadyRyViewHolder.java
@@ -44,6 +44,7 @@ import com.yunbao.common.interfaces.CommonCallback;
import com.yunbao.common.interfaces.ImageResultCallback;
import com.yunbao.common.interfaces.OnItemClickListener;
import com.yunbao.common.manager.IMLoginManager;
+import com.yunbao.common.manager.SWManager;
import com.yunbao.common.utils.Bus;
import com.yunbao.common.utils.DialogUitl;
import com.yunbao.common.utils.L;
@@ -327,7 +328,10 @@ public class LiveNewReadyRyViewHolder extends AbsViewHolder implements View.OnCl
if (liveOpenCustomPopup != null) {
liveOpenCustomPopup.setSelectClarity(selectClarity);
}
- //設置開播分辨率
+ SWManager.get().setDimensions(selectClarity);
+
+
+ /*//設置開播分辨率
RCRTCParamsType.RCRTCVideoResolution rcrtcVideoResolution = RCRTCParamsType.RCRTCVideoResolution.RESOLUTION_480_848;
int minRate = 200;
int maxRate = 900;
@@ -355,7 +359,7 @@ public class LiveNewReadyRyViewHolder extends AbsViewHolder implements View.OnCl
.setVideoFps(RCRTCParamsType.RCRTCVideoFps.Fps_15)
.setVideoResolution(rcrtcVideoResolution)
.build();
- RCRTCEngine.getInstance().getDefaultVideoStream().setVideoConfig(config);
+ RCRTCEngine.getInstance().getDefaultVideoStream().setVideoConfig(config);*/
Log.e("切换分辨率", "时间戳" + System.currentTimeMillis());
//重新发布一下流
Bus.get().post(new LivePushRyEvent());
diff --git a/live/src/main/java/com/yunbao/live/views/LivePlayRyViewHolder.java b/live/src/main/java/com/yunbao/live/views/LivePlayRyViewHolder.java
index 126ec891c..5c4b48ab3 100644
--- a/live/src/main/java/com/yunbao/live/views/LivePlayRyViewHolder.java
+++ b/live/src/main/java/com/yunbao/live/views/LivePlayRyViewHolder.java
@@ -3,6 +3,7 @@ package com.yunbao.live.views;
import static com.lzy.okgo.utils.HttpUtils.runOnUiThread;
import android.Manifest;
+import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
@@ -36,6 +37,7 @@ import com.yunbao.common.http.HttpCallback;
import com.yunbao.common.http.HttpClient;
import com.yunbao.common.interfaces.OnItemClickListener;
import com.yunbao.common.manager.IMLoginManager;
+import com.yunbao.common.manager.SWAuManager;
import com.yunbao.common.utils.Bus;
import com.yunbao.common.utils.DialogUitl;
import com.yunbao.common.utils.DpUtil;
@@ -97,6 +99,8 @@ public class LivePlayRyViewHolder extends LiveRoomPlayViewHolder {
private RelativeLayout mPkContainer;
public StyledPlayerView mVideoView;
+ private FrameLayout playFrameLayout;
+
private View mLoading, mLoading2;
private ImageView mCover;
private boolean mPaused;//是否切后台了
@@ -122,6 +126,7 @@ public class LivePlayRyViewHolder extends LiveRoomPlayViewHolder {
//0未申请1申请中2连麦中
RCRTCRoom rcrtcRoom;
String purl, srcUrl;
+ SWAuManager swAuManager;
public int getLandscape() {
return landscape;
@@ -146,6 +151,7 @@ public class LivePlayRyViewHolder extends LiveRoomPlayViewHolder {
EventBus.getDefault().register(this);
Bus.getOn(this);
mRoot = (ViewGroup) findViewById(R.id.root);
+ playFrameLayout = (FrameLayout) findViewById(R.id.playView);
mSmallContainer = (ViewGroup) findViewById(R.id.small_container);
mLeftContainer = (ViewGroup) findViewById(R.id.left_container);
mRightContainer = (ViewGroup) findViewById(R.id.right_container);
@@ -167,6 +173,13 @@ public class LivePlayRyViewHolder extends LiveRoomPlayViewHolder {
mPlayer = new LiveExoPlayerManager(mContext);
mPlayer.setMainView(mVideoView);
mPlayer.setListener(new ExoPlayerListener());
+
+ swAuManager = SWAuManager.get();
+ swAuManager.setAudienceContainer(playFrameLayout);
+ swAuManager.initRtcEngine((Activity) mContext);
+ swAuManager.setupRemoteVideo(11);
+ swAuManager.joinRoom("9999", SWAuManager.shengwang_token, SWAuManager.shengwang_channelName);
+
debugView = new TextView(mContext);
debugView.setBackgroundColor(Color.WHITE);
diff --git a/live/src/main/java/com/yunbao/live/views/LivePlaySwViewHolder.java b/live/src/main/java/com/yunbao/live/views/LivePlaySwViewHolder.java
new file mode 100644
index 000000000..f421d920f
--- /dev/null
+++ b/live/src/main/java/com/yunbao/live/views/LivePlaySwViewHolder.java
@@ -0,0 +1,1374 @@
+package com.yunbao.live.views;
+
+import static com.lzy.okgo.utils.HttpUtils.runOnUiThread;
+
+import android.Manifest;
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.google.android.exoplayer2.PlaybackException;
+import com.google.android.exoplayer2.Player;
+import com.google.android.exoplayer2.ui.StyledPlayerView;
+import com.google.android.exoplayer2.video.VideoSize;
+import com.lxj.xpopup.XPopup;
+import com.lxj.xpopup.core.BasePopupView;
+import com.lxj.xpopup.interfaces.XPopupCallback;
+import com.lzf.easyfloat.EasyFloat;
+import com.lzy.okserver.OkDownload;
+import com.yunbao.common.bean.EnterRoomNewModel;
+import com.yunbao.common.dialog.LiveFontSizeSettingDialog;
+import com.yunbao.common.http.HttpCallback;
+import com.yunbao.common.http.HttpClient;
+import com.yunbao.common.interfaces.OnItemClickListener;
+import com.yunbao.common.manager.IMLoginManager;
+import com.yunbao.common.utils.Bus;
+import com.yunbao.common.utils.DialogUitl;
+import com.yunbao.common.utils.DpUtil;
+import com.yunbao.common.utils.L;
+import com.yunbao.common.utils.MicStatusManager;
+import com.yunbao.common.utils.ScreenDimenUtil;
+import com.yunbao.common.utils.SpUtil;
+import com.yunbao.common.utils.ToastUtil;
+import com.yunbao.common.utils.WordUtil;
+import com.yunbao.common.views.LiveClarityCustomPopup;
+import com.yunbao.live.R;
+import com.yunbao.live.activity.LiveActivity;
+import com.yunbao.live.activity.LiveAudienceActivity;
+import com.yunbao.live.event.LiveAudienceEvent;
+import com.yunbao.live.utils.LiveExoPlayerManager;
+
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import cn.rongcloud.rtc.api.RCRTCEngine;
+import cn.rongcloud.rtc.api.RCRTCRemoteUser;
+import cn.rongcloud.rtc.api.RCRTCRoom;
+import cn.rongcloud.rtc.api.RCRTCRoomConfig;
+import cn.rongcloud.rtc.api.callback.IRCRTCResultCallback;
+import cn.rongcloud.rtc.api.callback.IRCRTCResultDataCallback;
+import cn.rongcloud.rtc.api.callback.IRCRTCRoomEventsListener;
+import cn.rongcloud.rtc.api.callback.IRCRTCSwitchRoleCallback;
+import cn.rongcloud.rtc.api.callback.IRCRTCSwitchRoleDataCallback;
+import cn.rongcloud.rtc.api.callback.IRCRTCVideoInputFrameListener;
+import cn.rongcloud.rtc.api.stream.RCRTCInputStream;
+import cn.rongcloud.rtc.api.stream.RCRTCLiveInfo;
+import cn.rongcloud.rtc.api.stream.RCRTCOutputStream;
+import cn.rongcloud.rtc.api.stream.RCRTCVideoInputStream;
+import cn.rongcloud.rtc.api.stream.RCRTCVideoStreamConfig;
+import cn.rongcloud.rtc.api.stream.RCRTCVideoView;
+import cn.rongcloud.rtc.base.RCRTCLiveRole;
+import cn.rongcloud.rtc.base.RCRTCMediaType;
+import cn.rongcloud.rtc.base.RCRTCParamsType;
+import cn.rongcloud.rtc.base.RCRTCRemoteVideoFrame;
+import cn.rongcloud.rtc.base.RCRTCRoomType;
+import cn.rongcloud.rtc.base.RCRTCStreamType;
+import cn.rongcloud.rtc.base.RTCErrorCode;
+import cn.rongcloud.rtc.core.RendererCommon;
+
+public class LivePlaySwViewHolder extends LiveRoomPlayViewHolder {
+
+ private static final String TAG = "LivePlayViewHolder";
+ private ViewGroup mRoot;
+ private ViewGroup mSmallContainer;
+ private ViewGroup mLeftContainer;
+ private ViewGroup mRightContainer;
+ private RelativeLayout mPkContainer;
+ public StyledPlayerView mVideoView;
+
+ private View mLoading, mLoading2;
+ private ImageView mCover;
+ private boolean mPaused;//是否切后台了
+ private boolean mStarted;//是否开始了播放
+ private boolean mEnd;//是否结束了播放
+ public static ImageView leave;
+
+ private boolean mPausedPlay;//是否被动暂停了播放
+ public int landscape; //1h 2s
+ public Context contexts;
+ public FrameLayout ry_view;
+
+ private static final int VIDEO_VERTICAL = 2;
+ private static final int VIDEO_HORIZONTAL = 1;
+ int videoLandscape = -1; // 视频方向,2=竖屏,1=横屏
+
+ static int vHeight;//视频高
+ private TextView debugView;
+ private LiveExoPlayerManager mPlayer;
+ private boolean isPk = false;
+ private boolean userJoinLinkMic = false;//用户是否已加入房间
+
+ //0未申请1申请中2连麦中
+ RCRTCRoom rcrtcRoom;
+ String purl, srcUrl;
+
+ public int getLandscape() {
+ return landscape;
+ }
+
+ public LivePlaySwViewHolder(Context context, ViewGroup parentView, int landscapes) {
+ super(context, parentView);
+ contexts = context;
+ landscape = landscapes;
+ Log.i("收收收", landscape + "");
+ }
+
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.view_live_play_ksy;
+ }
+
+ @Override
+ public void init() {
+ Log.i(TAG, "init: 初始化播放器ViewHolder");
+ EventBus.getDefault().register(this);
+ Bus.getOn(this);
+ mRoot = (ViewGroup) findViewById(R.id.root);
+ mSmallContainer = (ViewGroup) findViewById(R.id.small_container);
+ mLeftContainer = (ViewGroup) findViewById(R.id.left_container);
+ mRightContainer = (ViewGroup) findViewById(R.id.right_container);
+ mPkContainer = (RelativeLayout) findViewById(R.id.pk_container);
+ mVideoView = (StyledPlayerView) findViewById(R.id.video_view);
+ ry_view = (FrameLayout) findViewById(R.id.ry_view);
+ leave = (ImageView) findViewById(R.id.leave);
+ mLoading = findViewById(R.id.loading);
+ mLoading2 = findViewById(R.id.loading2);
+ mCover = (ImageView) findViewById(R.id.cover);
+ ScreenDimenUtil util = ScreenDimenUtil.getInstance();
+ int mScreenWdith = util.getScreenWdith();
+ vHeight = mScreenWdith * 720 / 960;
+
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mPkContainer.getLayoutParams();
+ params.height = vHeight;
+ mPkContainer.requestLayout();
+
+ mPlayer = new LiveExoPlayerManager(mContext);
+ mPlayer.setMainView(mVideoView);
+ mPlayer.setListener(new ExoPlayerListener());
+ debugView = new TextView(mContext);
+ debugView.setBackgroundColor(Color.WHITE);
+
+ }
+
+ @Override
+ public void hideCover() {
+// if (mCover != null) {
+// if (mCover.getVisibility()==View.VISIBLE){
+//// new Handler().postDelayed(new Runnable() {
+//// @Override
+//// public void run() {
+////
+//// }
+//// },200);
+// mCover.setVisibility(View.GONE);
+// mLoading2.setVisibility(View.GONE);
+// }
+//
+//
+// }
+ }
+
+ @Override
+ public void setCover(String coverUrl) {
+// if (mCover != null) {
+// mCover.setVisibility(View.VISIBLE);
+// mLoading2.setVisibility(View.VISIBLE);
+// ImgLoader.displayBlurLive(mContext, coverUrl, mCover, 400, 600);
+//
+// }
+ }//
+
+ @Override
+ public synchronized void setLiveBeanLandscape(int landscape) {
+// landscape=1;
+ Log.i(TAG, "setLiveBeanLandscape: " + landscape + " isPk: " + isPk);
+ this.landscape = landscape;
+ this.videoLandscape = landscape;
+ if (mPlayer != null) {
+ mPlayer.setViewResizeMode(landscape == VIDEO_VERTICAL);
+ }
+
+ if (landscape == 2) {
+ Log.i(TAG, "还原9:16");
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
+ params.topMargin = 0;
+ mVideoView.setLayoutParams(params);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = RelativeLayout.LayoutParams.MATCH_PARENT;
+ params1.topMargin = 0;
+ ry_view.setLayoutParams(params1);
+ ry_view.requestLayout();
+ RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
+ params2.height = RelativeLayout.LayoutParams.MATCH_PARENT;
+ params2.topMargin = 0;
+ mCover.setLayoutParams(params2);
+ mCover.requestLayout();
+
+ } else {
+ Log.i(TAG, "还原16:9");
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.setLayoutParams(params);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = vHeight;
+ params1.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params1.addRule(RelativeLayout.ALIGN_TOP);
+ ry_view.setLayoutParams(params1);
+ ry_view.requestLayout();
+ RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
+ params2.height = DpUtil.dp2px(270);
+ params2.topMargin = DpUtil.dp2px(120);
+ mCover.setLayoutParams(params2);
+ mCover.requestLayout();
+ }
+ }
+
+ @Override
+ public void setLiveEnterRoomNewModel(EnterRoomNewModel data) {
+ super.setLiveEnterRoomNewModel(data);
+ isPk = data.getEnterRoomInfo().getIsconnection().equals("1");
+ if (isPk) {
+ setLiveBeanLandscape(1);
+ }
+ }
+
+ /**
+ * 暂停播放
+ */
+ @Override
+ public void pausePlay() {
+
+ }
+
+ /**
+ * 暂停播放后恢复
+ */
+ @Override
+ public void resumePlay() {
+ if (!mPlayer.isPlaying()) {
+ new Handler(Looper.getMainLooper())
+ .postDelayed(() -> {
+ mPlayer.replay();
+ // ToastUtil.show("强制播放" + val);
+ }, 100);
+ }
+ }
+
+ /**
+ * 开始播放
+ *
+ * @param url 流地址
+ */
+ @Override
+ public void play(String url, int playModel) {
+ srcUrl = url;
+ PLAY_MODEL = playModel;
+ waitNextUrl = null;
+ Log.i(TAG, "play" + " url:" + url + " playModel: " + playModel + " landscape: " + landscape + " videoLandscape" + videoLandscape);
+ if (playModel != PLAY_MODEL_DEF && !url.contains(videoFps[0] + ".flv")) {
+ mPlayer.setViewResizeMode(landscape == VIDEO_VERTICAL);
+ if (landscape == VIDEO_VERTICAL && !isPk) {
+ url = url.replace(".flv", videoRatioVertical[playModel] + videoFps[0] + ".flv");
+ } else if (landscape == VIDEO_HORIZONTAL || isPk) {
+ url = url.replace(".flv", videoRatioHorizontal[playModel] + videoFps[0] + ".flv");
+ }
+ } else if (!url.contains(videoFps[0] + ".flv")) {
+ mPlayer.setViewResizeMode(false);
+ }
+ Log.e("purl121", url);
+
+ if (TextUtils.isEmpty(url) || mVideoView == null) {
+ return;
+ }
+
+ if (TextUtils.isEmpty(url) || mVideoView == null) {
+ return;
+ }
+ if (mPlayer.isPlaying()) {
+ mPlayer.stop();
+ mPlayer.clearUrl();
+ }
+ mPlayer.startUrl(url);
+ purl = url;
+ onPrepared();
+ }
+
+ @Override
+ public void switchStream(String url, int playModel) {
+ srcUrl = url;
+ PLAY_MODEL = playModel;
+ Log.i(TAG, "switchStream: " + " url:" + url + " playModel: " + playModel + " landscape: " + landscape + " videoLandscape = " + videoLandscape + " ispk = " + isPk + " bean = " + roomModel.getEnterRoomInfo().getIsconnection());
+ if (playModel != PLAY_MODEL_DEF && !url.contains(videoFps[0] + ".flv")) {
+ mPlayer.setViewResizeMode(landscape == VIDEO_VERTICAL);
+ if (landscape == VIDEO_VERTICAL && !isPk) {
+ url = url.replace(".flv", videoRatioVertical[playModel] + videoFps[0] + ".flv");
+ } else if (landscape == VIDEO_HORIZONTAL || isPk) {
+ url = url.replace(".flv", videoRatioHorizontal[playModel] + videoFps[0] + ".flv");
+ }
+ } else if (!url.contains(videoFps[0] + ".flv")) {
+ mPlayer.setViewResizeMode(false);
+ }
+ Log.e("purl121", url);
+
+ if (TextUtils.isEmpty(url) || mVideoView == null) {
+ return;
+ }
+
+
+ if (TextUtils.isEmpty(url) || mVideoView == null) {
+ return;
+ }
+ mPlayer.switchUrl(url);
+ purl = url;
+ }
+
+ boolean tmpPk = false;
+ String waitNextUrl = null;
+
+ @Override
+ public void switchStreamPk(boolean isPk) {
+ super.switchStreamPk(isPk);
+ Log.i(TAG, "switchStreamPk: isPk1" + isPk + " tmp = " + !tmpPk + " isPk2 = " + this.isPk);
+ if (this.isPk && tmpPk) return;
+ if (isPk && !tmpPk || this.isPk) {
+ mPlayer.setViewResizeMode(false);
+ String url;
+ if (PLAY_MODEL != -1) {
+ url = srcUrl.replace(".flv", videoRatioHorizontal[PLAY_MODEL] + videoFps[0] + ".flv");
+ } else {
+ url = srcUrl.replace(".flv", videoRatioHorizontal[1] + videoFps[0] + ".flv");
+ }
+ if (!tmpPk) {
+ waitNextUrl = url;
+ }
+ mPlayer.switchUrl(srcUrl);
+ tmpPk = true;
+ } else if (!isPk) {
+ tmpPk = false;
+ if (landscape == VIDEO_VERTICAL && PLAY_MODEL != -1) {
+ waitNextUrl = srcUrl.replace(".flv", videoRatioVertical[PLAY_MODEL] + videoFps[0] + ".flv");
+ } else if (landscape == VIDEO_HORIZONTAL && PLAY_MODEL != -1) {
+ waitNextUrl = srcUrl.replace(".flv", videoRatioHorizontal[PLAY_MODEL] + videoFps[0] + ".flv");
+ } else {
+ waitNextUrl = null;
+ }
+ mPlayer.switchUrl(srcUrl);
+ }
+ }
+
+ @Override
+ public void clearFrame() {
+ super.clearFrame();
+ mPlayer.clearFrame();
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.setLayoutParams(params);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ params1.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params1.addRule(RelativeLayout.ALIGN_TOP);
+ ry_view.setLayoutParams(params1);
+ ry_view.requestLayout();
+ RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
+ params2.height = DpUtil.dp2px(270);
+ params2.topMargin = DpUtil.dp2px(120);
+ mCover.setLayoutParams(params2);
+ mCover.requestLayout();
+ }
+
+ @Override
+ public void release() {
+ mEnd = true;
+ mStarted = false;
+ if (mPlayer != null) {
+ mPlayer.stop();
+ mPlayer.release();
+ }
+ Bus.getOff(this);
+ EventBus.getDefault().unregister(this);
+ L.e(TAG, "release------->");
+ }
+
+ @Override
+ public void stopPlay() {
+ Log.i(TAG, "stopPlay: ");
+ if (mCover != null) {
+ mCover.setAlpha(1f);
+ if (mCover.getVisibility() != View.VISIBLE) {
+ mCover.setVisibility(View.VISIBLE);
+ }
+ }
+ if (mPlayer != null) {
+ mPlayer.stop();
+ }
+ stopPlay2();
+ }
+
+ @Override
+ public void stopPlay2() {
+
+ }
+
+ @Override
+ public void setViewUP(int i) {
+ if (mVideoView == null) return;
+ Log.e("PK状态", "" + i);
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+ params.topMargin = contexts.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = vHeight;
+ params1.topMargin = contexts.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params1.addRule(RelativeLayout.ALIGN_TOP);
+ ry_view.requestLayout();
+ isPk = true;
+ if (mPlayer.getUrl().contains("848_24.flv") || mPlayer.getUrl().contains("1280_24.flv")) {
+ tmpPk = false;
+ switchStreamPk(true);
+ }
+ }
+
+ /**
+ * 播放开始
+ */
+ public void onPrepared() {
+ if (mEnd) {
+ release();
+ return;
+ }
+ int height;
+ if (videoLandscape == VIDEO_VERTICAL) {
+ height = ViewGroup.LayoutParams.MATCH_PARENT;
+ } else {
+ height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ }
+ mPlayer.setViewResizeMode(landscape == VIDEO_VERTICAL);
+ if (landscape == 2) {
+ Log.i(TAG, "onPrepared:还原9:16 land=" + videoLandscape);
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = height;
+ params.topMargin = 0;
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.setLayoutParams(params);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = height;
+ params1.topMargin = 0;
+ ry_view.setLayoutParams(params1);
+ ry_view.requestLayout();
+ RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
+ params2.height = height;
+ params2.topMargin = 0;
+ mCover.setLayoutParams(params2);
+ mCover.requestLayout();
+ } else {
+ Log.i(TAG, "onPrepared:还原16:9");
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = height;
+ params.topMargin = 0;
+ if (videoLandscape == VIDEO_HORIZONTAL) {
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ }
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.setLayoutParams(params);
+ mVideoView.requestLayout();
+
+ RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) ry_view.getLayoutParams();
+ params1.height = height;
+ params1.topMargin = 0;
+ params1.addRule(RelativeLayout.ALIGN_TOP);
+ if (videoLandscape == VIDEO_HORIZONTAL) {
+ params1.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ }
+ ry_view.setLayoutParams(params1);
+ ry_view.requestLayout();
+ RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
+ params2.height = height;
+ params2.topMargin = DpUtil.dp2px(120);
+ mCover.setLayoutParams(params2);
+ mCover.requestLayout();
+ }
+ }
+
+ @Override
+ public void setPkview() {
+ Log.i("收到socket--->", "变成16:9");
+ String url = srcUrl;
+ isPk = true;
+ switchStreamPk(true);
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+ }
+
+ @Override
+ public synchronized void setPkEndview() {
+
+ Log.i("收收收", landscape + "");
+ isPk = false;
+ tmpPk = false;
+ switchStreamPk(false);
+ if (landscape == 2) {
+ Log.i("收到socket--->", "还原9:16");
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
+ params.topMargin = 0;
+ mVideoView.requestLayout();
+
+ } else {
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+ }
+// if (detailsView != null) {
+// mVideoView.removeView(detailsView);
+// detailsView = null;
+// }
+ }
+
+ public void removeDetailView() {
+// if (detailsView != null) {
+// mVideoView.removeView(detailsView);
+// detailsView = null;
+// }
+ }
+
+ @Override
+ public ViewGroup getSmallContainer() {
+ return mSmallContainer;
+ }
+
+
+ @Override
+ public ViewGroup getRightContainer() {
+ return mRightContainer;
+ }
+
+ @Override
+ public ViewGroup getPkContainer() {
+ return mPkContainer;
+ }
+
+ @Override
+ public void changeToLeft() {
+ if (mVideoView != null) {
+
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+// params.height = mContext.getResources().getDimensionPixelOffset(R.dimen.live_view);
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+
+ }
+ if (mLoading != null && mLeftContainer != null) {
+ ViewParent viewParent = mLoading.getParent();
+ if (viewParent != null) {
+ ((ViewGroup) viewParent).removeView(mLoading);
+ }
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(DpUtil.dp2px(24), DpUtil.dp2px(24));
+ params.gravity = Gravity.CENTER;
+ mLoading.setLayoutParams(params);
+ mLeftContainer.addView(mLoading);
+ }
+ }
+
+ @Override
+ public void changeToBig() {
+ if (mVideoView != null) {
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ mVideoView.setLayoutParams(params);
+
+ }
+ if (mLoading != null && mRoot != null) {
+ ViewParent viewParent = mLoading.getParent();
+ if (viewParent != null) {
+ ((ViewGroup) viewParent).removeView(mLoading);
+ }
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(DpUtil.dp2px(24), DpUtil.dp2px(24));
+ params.addRule(RelativeLayout.CENTER_IN_PARENT);
+ mLoading.setLayoutParams(params);
+ mRoot.addView(mLoading);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ if (!mPausedPlay && mPaused && mVideoView != null) {
+// mVideoView.runInForeground();
+// mVideoView.start();
+ }
+ mPaused = false;
+// if (mPlayer.isPlaying() == 1) {
+// mPlayer.resumeVideo();
+// mPlayer.resumeAudio();
+// }
+ }
+
+ @Override
+ public void onPause() {
+// if (!mPausedPlay && mVideoView != null) {
+// mVideoView.runInBackground(false);
+// }
+// mPaused = true;
+// mPlayer.pauseVideo();
+// mPlayer.pauseAudio();
+ }
+
+ @Override
+ public void onDestroy() {
+ release();
+ }
+
+ //全屏
+ @Override
+ public void fullScreen() {
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = RelativeLayout.LayoutParams.MATCH_PARENT;
+ params.topMargin = 0;
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+ }
+
+ //小屏
+ @Override
+ public void smallScreen() {
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mVideoView.getLayoutParams();
+ params.height = vHeight;
+ params.topMargin = mContext.getResources().getDimensionPixelOffset(R.dimen.live_top);
+ // mPlayer.setRenderRotation(V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0);
+ params.addRule(RelativeLayout.ALIGN_TOP);
+ mVideoView.requestLayout();
+ }
+
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onUpdata(String str) {
+ if ("UsertoRY".equals(str)) {
+ DialogUitl.showSimpleDialog(mContext, mContext.getString(R.string.mic_tag), new DialogUitl.SimpleCallback() {
+ @Override
+ public void onConfirmClick(Dialog dialog, String content) {
+ UsertoRY();
+ dialog = null;
+ }
+ });
+
+ } else if ("inviteMic".equals(str)) {
+ String content = "邀請您進行語音連麥";
+ String confirm = "接受";
+ String cancel = "拒絕";
+ if (!WordUtil.isNewZh()) {
+ content = "You are invited to join the voice connection";
+ confirm = "accept";
+ cancel = "cancel";
+ }
+ DialogUitl.Builder builder = new DialogUitl.Builder(mContext)
+ .setContent(content)
+ .setTitle(mLiveBean.getUserNiceName())
+ .setConfirmString(confirm)
+ .setCancelString(cancel)
+ .setView(R.layout.dialog_live_mic_invite)
+ .setClickCallback(new DialogUitl.SimpleCallback() {
+ @Override
+ public void onConfirmClick(Dialog dialog, String content) {
+ String[] permissions;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ permissions = new String[]{
+ Manifest.permission.READ_MEDIA_IMAGES,
+ Manifest.permission.RECORD_AUDIO
+ };
+ } else {
+ permissions = new String[]{
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.RECORD_AUDIO
+ };
+ }
+ LiveAudienceActivity.mProcessResultUtil.requestPermissions(permissions, new Runnable() {
+ @Override
+ public void run() {
+ UsertoRY();
+
+ }
+ });
+ }
+ });
+ builder.build().show();
+
+ } else if ("endMic".equals(str)) {
+ if (rcrtcRoom != null) {
+ // 开始切换为观众身份
+ RCRTCEngine.getInstance().getRoom().getLocalUser().switchToAudience(new IRCRTCSwitchRoleCallback() {
+
+ /**
+ * 当切换失败且SDK处于无法回退状态时回调,该角色已经无法使用当前角色继续进行音视频。
+ * SDK内部会退出房间并清理所有资源,该用户只能重新加入房间才能继续音视频。
+ */
+ @Override
+ public void onKicked() {
+
+ }
+
+ @Override
+ public void onSuccess() {
+ Log.e("ry", "下麦成功");
+ // 该用户切换为观众成功,可以以观众身份进行音视频
+ //退出rtc播放
+ leaveRoom();
+ }
+
+ /**
+ * 当切换失败且不影响当前角色继续音视频时回调
+ * @param errorCode 失败错误码
+ */
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+ Log.e("ry", "下麦失败" + errorCode);
+ leaveRoom();
+ }
+
+ private void leaveRoom() {
+ RCRTCEngine.getInstance().leaveRoom(new IRCRTCResultCallback() {
+ @Override
+ public void onSuccess() {
+ userJoinLinkMic = false;
+ Log.e("ry", "退出多人房间成功");
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ public void run() {
+ if (WordUtil.isNewZh()) {
+ ToastUtil.show("已成功退出語音連麥");
+ } else {
+ ToastUtil.show("You have successfully exited the voice connection");
+ }
+ if (mPlayer.getNowPlayer() != null) {
+ mPlayer.play();
+ Log.e("ry", mPlayer.isPlaying() + "purl" + purl);
+ if (!mPlayer.isPlaying()) {
+ mPlayer.switchUrl(purl);
+ }
+ ry_view.removeAllViews();
+ ry_view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ onPrepared();
+ rcrtcRoom = null;
+ MicStatusManager.getInstance().clear();
+
+ resumePlay();
+ }
+
+ if (onMicCallback != null) {
+ onMicCallback.onMikUpdate();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+ Log.e("ry", errorCode + "退出多人房间成功");
+ userJoinLinkMic = false;
+ }
+ });
+
+ }
+ });
+ }
+ } else if ("Debug".equals(str)) {
+ if (EasyFloat.isShow("Debug")) {
+ EasyFloat.dismiss("Debug");
+ return;
+ }
+ EasyFloat.with(mContext)
+ .setDragEnable(true)
+ .setTag("Debug")
+ .setLayout(debugView)
+ .show();
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onOpenDrawer(LiveAudienceEvent event) {
+ if (event.getType() == LiveAudienceEvent.LiveAudienceType.LIVE_VIDEO) {
+ int ban = 0;//全模式都可以选择
+ switch (roomModel.getClarityType() - 1) {
+ case PLAY_MODEL_720://仅允许720(高清),ban掉1080(超高清)模式
+ ban = LiveClarityCustomPopup.BAN_1080;
+ break;
+ case -1://没有该字段
+ case PLAY_MODEL_480://仅允许480(流畅),ban掉1080(超高清)和720(高清)模式
+ ban = LiveClarityCustomPopup.BAN_720;
+ break;
+
+ }
+ LiveClarityCustomPopup liveClarityCustomPopup = new LiveClarityCustomPopup(mContext,
+ IMLoginManager.get(mContext).getInt(PLAY_MODEL_KEY, PLAY_MODEL_ANCHOR),
+ ban,
+ true);
+ new XPopup.Builder(mContext)
+ .setPopupCallback(new XPopupCallback() {
+ @Override
+ public void onCreated(BasePopupView popupView) {
+
+ }
+
+ @Override
+ public void beforeShow(BasePopupView popupView) {
+
+ }
+
+ @Override
+ public void onShow(BasePopupView popupView) {
+
+ }
+
+ @Override
+ public void onDismiss(BasePopupView popupView) {
+ int selectClarity = liveClarityCustomPopup.getSelectClarity();
+ if (selectClarity == PLAY_MODEL || selectClarity == IMLoginManager.get(mContext).getInt(LiveRoomPlayViewHolder.PLAY_MODEL_KEY, PLAY_MODEL_ANCHOR))
+ return;
+ if (selectClarity == PLAY_MODEL_ANCHOR) {
+ switchStream(srcUrl, PLAY_MODEL_DEF);
+ setAudiencePlayModel(selectClarity);
+ } else {
+ switchStream(srcUrl, selectClarity);
+ }
+ IMLoginManager.get(mContext).put(LiveRoomPlayViewHolder.PLAY_MODEL_KEY, selectClarity);
+ showToast();
+ }
+
+ private void showToast() {
+ if (WordUtil.isNewZh()) {
+ DialogUitl.showToast(mContext, "設置成功\n" +
+ "正在為你轉換中", 3000);
+ } else {
+ DialogUitl.showToast(mContext, "successful\n" +
+ "It's being converted for you", 3000);
+ }
+ }
+
+ @Override
+ public void beforeDismiss(BasePopupView popupView) {
+
+ }
+
+ @Override
+ public boolean onBackPressed(BasePopupView popupView) {
+ return false;
+ }
+
+ @Override
+ public void onKeyBoardStateChanged(BasePopupView popupView, int height) {
+
+ }
+
+ @Override
+ public void onDrag(BasePopupView popupView, int value, float percent, boolean upOrLeft) {
+
+ }
+
+ @Override
+ public void onClickOutside(BasePopupView popupView) {
+
+ }
+ })
+ .asCustom(liveClarityCustomPopup)
+ .show();
+ } else if (event.getType() == LiveAudienceEvent.LiveAudienceType.FONT_SIZE) {
+ int fount = 0;
+ try {
+ fount = Integer.parseInt(SpUtil.getStringValue("pd_live_room_fount_size"));
+ } catch (Exception ignored) {
+
+ }
+ new LiveFontSizeSettingDialog(mContext, fount).setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(Integer bean, int position) {
+ EventBus.getDefault().post(new LiveAudienceEvent()
+ .setNums(bean)
+ .setType(LiveAudienceEvent.LiveAudienceType.LIVE_FONT_SIZE));
+ }
+ }).showDialog();
+ }
+ }
+
+ /**
+ * 把观众转换成主播
+ */
+ public List userinputStreamList = new ArrayList<>();
+
+
+ public void UsertoRY() {
+ userinputStreamList.clear();
+ Log.e("ry", "主播同意了UsertoRY");
+ if (userJoinLinkMic) {//已经在房间内,不再joinRoom直接去连麦
+ subscribeMic(rcrtcRoom);
+ return;
+ }
+ RCRTCRoomConfig roomConfig = RCRTCRoomConfig.Builder.create()
+ // 根据实际场景,选择音视频直播:LIVE_AUDIO_VIDEO 或音频直播:LIVE_AUDIO
+ .setRoomType(RCRTCRoomType.LIVE_AUDIO_VIDEO)
+ .setLiveRole(RCRTCLiveRole.AUDIENCE)
+ .build();
+ RCRTCEngine.getInstance().joinRoom(LiveActivity.mLiveUid, roomConfig, new IRCRTCResultDataCallback() {
+
+
+ @Override
+ public void onSuccess(RCRTCRoom data) {
+ userJoinLinkMic = true;
+ rcrtcRoom = data;
+ subscribeMic(data);
+
+ }
+
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+ Log.e("ry", LiveActivity.mLiveUid + errorCode + "");
+ if (errorCode.getValue() == 50007) {//userJoinLinkMic可能失效,直接leaveRoom
+ userJoinLinkMic = false;
+ RCRTCEngine.getInstance().leaveRoom(new IRCRTCResultCallback() {
+
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+
+ }
+
+ @Override
+ public void onSuccess() {
+ UsertoRY();
+ }
+ });
+ } else {
+ ToastUtil.show("房间失败" + errorCode);
+ }
+
+ }
+ });
+
+
+ }
+
+ private void subscribeMic(RCRTCRoom data) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ RCRTCEngine.getInstance().enableSpeaker(true);
+ //遍历远端用户发布的资源列表
+ Log.i(TAG, "软件资源数量:" + data.getLiveStreams().size());
+ for (RCRTCInputStream stream : data.getLiveStreams()) {
+ Log.i(TAG, "资源流 type: " + stream.getMediaType());
+ if (stream.getMediaType() == RCRTCMediaType.VIDEO) {
+ //暂停播放
+ mPlayer.stop();
+ //如果远端用户发布的是视频流,创建显示视图RCRTCVideoView,并添加到布局中显示
+
+ //如果远端用户发布的是视频流,创建显示视图RCRTCVideoView,并添加到布局中显示
+ RCRTCVideoView remoteView = new RCRTCVideoView(contexts);
+ ((RCRTCVideoInputStream) stream).setVideoView(remoteView);
+ //todo 本demo只演示添加1个远端用户的视图
+ remoteView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ remoteView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
+ ry_view.addView(remoteView);
+ Log.e("ry", stream.getMediaType() + "rcrtcOtherRoom成功 :" + data.getLiveStreams().size());
+ }
+ userinputStreamList.add(stream);
+ }
+ rcrtcRoom.getLocalUser().subscribeStreams(userinputStreamList, new IRCRTCResultCallback() {
+
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+ Log.e("ry", userinputStreamList.size() + LiveActivity.mLiveUid + "订阅失败" + errorCode.toString());
+ ToastUtil.show(mContext.getString(R.string.live_pk_link_error));
+ }
+
+ @Override
+ public void onSuccess() {
+ Log.e("ry", "订阅资源成功");
+// new Handler().postDelayed(new Runnable() {
+// @Override
+// public void run() {
+ toMic();
+// }
+// }, 3000);
+
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * 主房间事件监听
+ * 详细说明请参考文档:https://www.rongcloud.cn/docs/api/android/rtclib_v4/cn/rongcloud/rtc/api/callback/IRCRTCRoomEventsListener.html
+ */
+ public IRCRTCRoomEventsListener roomEventsListener = new IRCRTCRoomEventsListener() {
+ @Override
+ public void onRemoteUserPublishResource(RCRTCRemoteUser rcrtcRemoteUser, List list) {
+ Log.e("ry", "远端来了" + list.size());
+ //TODO 按需在此订阅远端用户发布的资源
+ rcrtcRoom.getLocalUser().subscribeStreams(list, new IRCRTCResultCallback() {
+ @Override
+ public void onSuccess() {
+ Log.e("ry", "远端成功" + list.size());
+
+ }
+
+ @Override
+ public void onFailed(RTCErrorCode rtcErrorCode) {
+ Log.e("ry", "远端失败" + list.size());
+ ToastUtil.show(mContext.getString(R.string.live_pk_link_error));
+ }
+ });
+ }
+
+ @Override
+ public void onRemoteUserMuteAudio(RCRTCRemoteUser remoteUser, RCRTCInputStream stream, boolean mute) {
+
+ }
+
+ @Override
+ public void onRemoteUserMuteVideo(RCRTCRemoteUser remoteUser, RCRTCInputStream stream, boolean mute) {
+
+ }
+
+ @Override
+ public void onRemoteUserUnpublishResource(RCRTCRemoteUser remoteUser, List streams) {
+
+ }
+
+ @Override
+ public void onUserJoined(RCRTCRemoteUser remoteUser) {
+
+ }
+
+ @Override
+ public void onUserLeft(RCRTCRemoteUser remoteUser) {
+
+ }
+
+ @Override
+ public void onUserOffline(RCRTCRemoteUser remoteUser) {
+
+ }
+
+ @Override
+ public void onPublishLiveStreams(List streams) {
+
+ }
+
+ @Override
+ public void onUnpublishLiveStreams(List streams) {
+
+ }
+ };
+
+
+ public List userinputStreamList1 = new ArrayList<>();
+ public List userinputStreamList2 = new ArrayList<>();
+
+ public void toMic() {
+ RCRTCEngine.getInstance().getDefaultAudioStream().setAudioQuality(RCRTCParamsType.AudioQuality.MUSIC, RCRTCParamsType.AudioScenario.MUSIC_CLASSROOM);
+ userinputStreamList1.clear();
+ userinputStreamList2.clear();
+ RCRTCParamsType.RCRTCVideoResolution rcrtcVideoResolution = RCRTCParamsType.RCRTCVideoResolution.RESOLUTION_480_848;
+ int minRate = 200;
+ int maxRate = 900;
+ switch (IMLoginManager.get(mContext).getSelectClarity()) {
+ case 0:
+ rcrtcVideoResolution = landscape == 1 ? RCRTCParamsType.RCRTCVideoResolution.parseVideoResolution(960, 720) : RCRTCParamsType.RCRTCVideoResolution.RESOLUTION_480_848;
+ minRate = landscape == 1 ? 900 : 200;
+ maxRate = landscape == 1 ? 700 : 900;
+ break;
+ case 1:
+ rcrtcVideoResolution = landscape == 1 ? RCRTCParamsType.RCRTCVideoResolution.parseVideoResolution(960, 720) : RCRTCParamsType.RCRTCVideoResolution.RESOLUTION_720_1280;
+ minRate = landscape == 1 ? 900 : 250;
+ maxRate = landscape == 1 ? 700 : 2200;
+ break;
+ case 2:
+ rcrtcVideoResolution = landscape == 1 ? RCRTCParamsType.RCRTCVideoResolution.parseVideoResolution(960, 720) : RCRTCParamsType.RCRTCVideoResolution.RESOLUTION_1080_1920;
+ minRate = landscape == 1 ? 900 : 400;
+ maxRate = landscape == 1 ? 700 : 4000;
+ break;
+ }
+ // 示例代码使用480x640分辨率演示
+ RCRTCVideoStreamConfig config = RCRTCVideoStreamConfig
+ .Builder.create()
+ //设置分辨率
+ .setVideoResolution(rcrtcVideoResolution)
+ //设置帧率
+ .setVideoFps(RCRTCParamsType.RCRTCVideoFps.Fps_24)
+ //设置最小码率,480P下推荐200
+ .setMinRate(minRate)
+ //设置最大码率,480P下推荐900
+ .setMaxRate(maxRate)
+ .build();
+ RCRTCEngine.getInstance().getDefaultVideoStream().setVideoConfig(config);
+// 创建视图渲染视图
+// RCRTCVideoView videoView = new RCRTCVideoView(contexts);
+// RCRTCEngine.getInstance().getDefaultVideoStream().setVideoView(videoView);
+//TODO 示例代码使用获取本地默认视频流、音频流演示
+ ArrayList streams = new ArrayList<>();
+// streams.add(RCRTCEngine.getInstance().getDefaultVideoStream());
+ streams.add(RCRTCEngine.getInstance().getDefaultAudioStream());
+ if (landscape == 1) {
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ setLiveBeanLandscape(1);
+ }
+ });
+
+ }
+// 开启摄像头
+// RCRTCEngine.getInstance().getDefaultVideoStream().startCamera(null);
+// 开始切换为主播身份
+ RCRTCEngine.getInstance().getRoom().getLocalUser().switchToBroadcaster(streams, new IRCRTCSwitchRoleDataCallback() {
+ /**
+ * 当切换失败且SDK处于无法回退状态时回调,该角色已经无法使用当前角色继续进行音视频。
+ * SDK内部会退出房间并清理所有资源,该用户只能重新加入房间才能继续音视频。
+ */
+ @Override
+ public void onKicked() {
+ Log.e("ry", "切换onKicked");
+
+ }
+
+ @Override
+ public void onSuccess(RCRTCLiveInfo data) {
+ rcrtcRoom.registerRoomListener(roomEventsListener);
+ //该用户切换为主播成功,可以以主播身份进行音视频
+ Log.e("ry", "切换成功");
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ public void run() {
+ if (onMicCallback != null) {
+ onMicCallback.onMikUpdate();
+ }
+ //遍历远端用户列表
+ for (int i = 0; i < rcrtcRoom.getRemoteUsers().size(); i++) {
+ Log.e("ry", rcrtcRoom.getRemoteUsers().get(i).getUserId() + "收到rcrtcOtherRoom" + rcrtcRoom.getRemoteUsers().size());
+ //遍历远端用户发布的资源列表
+ for (RCRTCInputStream stream : rcrtcRoom.getRemoteUsers().get(i).getStreams()) {
+ Log.e("ry", i + "收到" + stream.getMediaType() + "实打实打算" + rcrtcRoom.getRemoteUsers().get(i).getUserId());
+ if (stream.getMediaType() == RCRTCMediaType.VIDEO) {
+ if (userinputStreamList1.size() == 0) {
+
+ //如果远端用户发布的是视频流,创建显示视图RCRTCVideoView,并添加到布局中显示
+ RCRTCVideoView remoteView = new RCRTCVideoView(contexts);
+ ((RCRTCVideoInputStream) stream).setStreamType(RCRTCStreamType.NORMAL);
+ ((RCRTCVideoInputStream) stream).setVideoView(remoteView);
+ ((RCRTCVideoInputStream) stream).setVideoFrameListener(new IRCRTCVideoInputFrameListener() {
+ @Override
+ public void onFrame(RCRTCRemoteVideoFrame videoFrame) {
+ String debugText = " 2、安卓主播开播, 安卓用户申请连麦后 ,安卓用户这边底部画面不全 :" + videoFrame.getFrameType().name() + "\n" +
+ "rotation:" + videoFrame.getRotation() + "\n" +
+ "timestampNs:" + videoFrame.getTimestampNs() + "\n" +
+ "分辨率:" + videoFrame.getBuffer().getHeight() + "x" + videoFrame.getBuffer().getWidth() + "\n" +
+ "当前时间:" + new SimpleDateFormat("HH:mm:ss", Locale.CHINA).format(new Date()) + "\n";
+ //Log.d("ry", "onFrame: " + debugText);
+ new Handler(Looper.getMainLooper()).post(() -> {
+ debugView.setText(debugText);
+
+ });
+ }
+ });
+ //todo 本demo只演示添加1个远端用户的视图
+ ry_view.removeAllViews();
+ remoteView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ remoteView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
+ ry_view.addView(remoteView);
+ }
+ userinputStreamList1.add(stream);
+ }
+ userinputStreamList2.add(stream);
+ }
+ }
+ //开始订阅资源
+ rcrtcRoom.getLocalUser().subscribeStreams(userinputStreamList2, new IRCRTCResultCallback() {
+ @Override
+ public void onSuccess() {
+ Log.e("ry", "订阅资源成功");
+ MicStatusManager.getInstance().setMicData(MicStatusManager.MIC_TYPE_OPEN, LiveActivity.mLiveUid);
+ AudioManager audioManager = (AudioManager) contexts.getSystemService(Context.AUDIO_SERVICE);
+ RCRTCEngine.getInstance().enableSpeaker(true);
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ audioManager.setSpeakerphoneOn(true);
+
+ HttpClient.getInstance().get("live.joinDrLm", "live.joinDrLm")
+ .params("roomid", LiveActivity.mLiveUid)
+ .execute(new HttpCallback() {
+ @Override
+ public void onSuccess(int code, String msg, String[] info) {
+ Log.e("ry", code + "热热热");
+ }
+ });
+ }
+
+ @Override
+ public void onFailed(RTCErrorCode rtcErrorCode) {
+ Log.e("ry", "订阅资源失败: " + rtcErrorCode.getReason());
+ ToastUtil.show(mContext.getString(R.string.live_pk_link_error));
+ }
+ });
+ }
+ });
+
+
+ }
+
+ /**
+ * 当切换失败且不影响当前角色继续音视频时回调
+ * @param errorCode 失败错误码
+ */
+ @Override
+ public void onFailed(RTCErrorCode errorCode) {
+ Log.e("ry", errorCode + "切换失败");
+
+ }
+ });
+ }
+
+ @Override
+ public void setLoadViewListener(LoadingListener listener) {
+ super.setLoadViewListener(listener);
+ }
+
+ private void showLoadingDialog() {
+ if (PLAY_MODEL == PLAY_MODEL_480) return;
+
+ new DialogUitl.Builder(mContext)
+ .setTitle("網絡提示")
+ .setContent("系統監測到您的網絡不穩定,對此將清晰度變成了流暢,您可以在側邊菜單中的「清晰度」選擇調回。")
+ .setView(R.layout.dialog_simple_tip)
+ .setClickCallback(new DialogUitl.SimpleCallback() {
+ @Override
+ public void onConfirmClick(Dialog dialog, String content) {
+ dialog.dismiss();
+ }
+ }).build().show();
+ PLAY_MODEL = PLAY_MODEL_480;
+ String url = srcUrl;
+ if (videoLandscape == VIDEO_VERTICAL) {
+ url = url.replace(".flv", videoRatioVertical[PLAY_MODEL_480] + videoFps[0] + ".flv");
+ } else if (videoLandscape == VIDEO_HORIZONTAL) {
+ url = url.replace(".flv", videoRatioHorizontal[PLAY_MODEL_480] + videoFps[0] + ".flv");
+ }
+ mPlayer.switchUrl(url);
+ }
+
+ private class ExoPlayerListener implements Player.Listener {
+ String TAG = "播放流";
+
+ @Override
+ public void onPlayerError(PlaybackException error) {
+ Player.Listener.super.onPlayerError(error);
+ debugView.setText("播放出错code=" + error.errorCode + " msg=" + error.getErrorCodeName());
+ }
+
+ @Override
+ public void onVideoSizeChanged(VideoSize videoSize) {
+ Player.Listener.super.onVideoSizeChanged(videoSize);
+ Log.i(TAG, "onVideoSizeChanged: width = " + videoSize.width + " height = " + videoSize.height);
+ //ToastUtil.show("分辨率: 宽 = " + videoSize.width + " 高 = " + videoSize.height);
+ if (videoSize.height > videoSize.width) {
+ videoLandscape = VIDEO_VERTICAL;
+ } else {
+ videoLandscape = VIDEO_HORIZONTAL;
+ }
+ }
+
+ @Override
+ public void onPlaybackStateChanged(int playbackState) {
+ Player.Listener.super.onPlaybackStateChanged(playbackState);
+ if (playbackState == Player.STATE_BUFFERING) {
+ //showLoadingDialog();
+ mLoading.setVisibility(View.VISIBLE);
+ OkDownload.getInstance().pauseAll();
+ Log.i(TAG, "onPlaybackStateChanged: 缓存中");
+ } else {
+ mLoading.setVisibility(View.INVISIBLE);
+ Log.i(TAG, "onPlaybackStateChanged: 播放中");
+ }
+ }
+
+ @Override
+ public void onIsPlayingChanged(boolean isPlaying) {
+ Player.Listener.super.onIsPlayingChanged(isPlaying);
+ if (isPlaying) {
+ hideCover();
+ mLoading.setVisibility(View.INVISIBLE);
+ Log.i(TAG, "onIsPlayingChanged: 开始播放 | waitNextUrl = " + waitNextUrl);
+ OkDownload.getInstance().startAll();
+ if (loadingListener != null) {
+ loadingListener.onPlayer();
+ }
+ if (waitNextUrl != null) {
+ mPlayer.switchUrl(waitNextUrl);
+ waitNextUrl = null;
+ }
+ }
+ }
+ }
+
+ private int mPkTimeCount = 0;
+
+
+ public interface PlayViewLayoutInterface {
+ void playViewLayout(int width, int height);
+ }
+
+ private PlayViewLayoutInterface layoutInterface;
+
+ public void setLayoutInterface(PlayViewLayoutInterface layoutInterface) {
+ mVideoView.post(new Runnable() {
+ @Override
+ public void run() {
+ int width = mVideoView.getMeasuredWidth();
+ int height = mVideoView.getMeasuredHeight();
+ if (layoutInterface != null) {
+ layoutInterface.playViewLayout(width, height);
+ }
+ }
+ });
+ }
+
+
+}
diff --git a/live/src/main/java/com/yunbao/live/views/LivePushRyViewHolder.java b/live/src/main/java/com/yunbao/live/views/LivePushRyViewHolder.java
index 9b50cfc7f..0e7d75410 100644
--- a/live/src/main/java/com/yunbao/live/views/LivePushRyViewHolder.java
+++ b/live/src/main/java/com/yunbao/live/views/LivePushRyViewHolder.java
@@ -9,8 +9,8 @@ import static com.yunbao.live.event.LiveAudienceEvent.LiveAudienceType.LIVE_PK_I
import static com.yunbao.live.presenter.LiveRyLinkMicPkPresenter.inputStreamList;
import static com.yunbao.live.presenter.LiveRyLinkMicPkPresenter.inputStreamList1;
import static com.yunbao.live.presenter.LiveRyLinkMicPkPresenter.mPkUid;
-import static cn.rongcloud.rtc.base.RCRTCLiveRole.BROADCASTER;
+import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
@@ -46,6 +46,7 @@ import com.yunbao.common.http.live.LiveNetManager;
import com.yunbao.common.manager.IMLoginManager;
import com.yunbao.common.manager.IMRTCManager;
import com.yunbao.common.manager.RandomPkManager;
+import com.yunbao.common.manager.SWManager;
import com.yunbao.common.utils.Bus;
import com.yunbao.common.utils.DialogUitl;
import com.yunbao.common.utils.DpUtil;
@@ -70,26 +71,19 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
-import cn.rongcloud.rtc.api.RCRTCConfig;
import cn.rongcloud.rtc.api.RCRTCEngine;
import cn.rongcloud.rtc.api.RCRTCMixConfig;
import cn.rongcloud.rtc.api.RCRTCRemoteUser;
import cn.rongcloud.rtc.api.RCRTCRoom;
-import cn.rongcloud.rtc.api.RCRTCRoomConfig;
-import cn.rongcloud.rtc.api.callback.IRCRTCEngineEventListener;
import cn.rongcloud.rtc.api.callback.IRCRTCResultCallback;
import cn.rongcloud.rtc.api.callback.IRCRTCResultDataCallback;
import cn.rongcloud.rtc.api.callback.IRCRTCRoomEventsListener;
import cn.rongcloud.rtc.api.stream.RCRTCInputStream;
import cn.rongcloud.rtc.api.stream.RCRTCLiveInfo;
-import cn.rongcloud.rtc.api.stream.RCRTCVideoStreamConfig;
-import cn.rongcloud.rtc.api.stream.RCRTCVideoView;
import cn.rongcloud.rtc.base.RCRTCParamsType;
-import cn.rongcloud.rtc.base.RCRTCRoomType;
-import cn.rongcloud.rtc.base.RCRTCVideoEventCode;
import cn.rongcloud.rtc.base.RTCErrorCode;
import cn.rongcloud.rtc.core.CameraVideoCapturer;
-import cn.rongcloud.rtc.core.RendererCommon;
+import io.agora.rtc2.RtcEngine;
import io.rong.imlib.IRongCallback;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
@@ -101,13 +95,12 @@ import io.rong.message.TextMessage;
*/
public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITXLivePushListener {
-
+ private RtcEngine mRtcEngine;
private int mMeiBaiVal;//基础美颜 美白
private int mMoPiVal;//基础美颜 磨皮
private int mHongRunVal;//基础美颜 红润
private String mBgmPath;//背景音乐路径
private Bitmap mFilterBmp;
-
private TXDeviceManager mTXDeviceManager;
private TRTCCloudDef.TRTCParams mTRTCParams;
private Handler mMainHandler;
@@ -117,7 +110,6 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
public LinearLayout dr_pk_view;
public static RCRTCRoom rtcRoom;
public static RCRTCLiveInfo rcrtcLiveInfo;
-
private ViewGroup liveActivityContainer;
public FrameLayout timeTitle;
public TextView textTime;
@@ -126,6 +118,7 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
private LinearLayout goto_room_view;
private boolean isPk = false;
private boolean isNeedOpenCamera = false;
+ private SWManager swManager;
//修改上面主播的头像
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -139,7 +132,6 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
goto_room_view.setVisibility(View.VISIBLE);
} else {
goto_room_view.setVisibility(View.GONE);
-
}
}
}
@@ -414,7 +406,7 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
@Override
public void onError(String error) {
- ToastUtil.show(WordUtil.isNewZh()?"抱歉!出錯了!":"i \\'m sorry! An error occurred");
+ ToastUtil.show(WordUtil.isNewZh() ? "抱歉!出錯了!" : "i \\'m sorry! An error occurred");
}
});
@@ -470,7 +462,6 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
}
};
-
@Override
public void init() {
super.init();
@@ -615,8 +606,9 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
});
}
});
+ initRtcEngine();
- // 构建 RoomConfig,指定房间类型和主播身份:
+ /* // 构建 RoomConfig,指定房间类型和主播身份:
RCRTCRoomConfig roomConfig = RCRTCRoomConfig.Builder.create()
// 根据实际场景,选择音视频直播:LIVE_AUDIO_VIDEO 或音频直播:LIVE_AUDIO
.setRoomType(RCRTCRoomType.LIVE_AUDIO_VIDEO)
@@ -772,9 +764,24 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
}
- });
+ });*/
}
+ /**
+ * 初始化声网SDK
+ */
+ private void initRtcEngine() {
+ swManager = SWManager.get();
+ swManager.setAnchorContainer(mPreView);
+ swManager.initRtcEngine((Activity) mContext, "11");
+ swManager.setOnRtcEngineListener(new SWManager.onRtcEngineListener() {
+ @Override
+ public void onOpenSuccess(String channel, int uid) {
+ //开播成功
+
+ }
+ });
+ }
@Override
public void changeToLeft() {
@@ -847,6 +854,10 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
*/
@Override
public void startPush(String pushUrl) {
+ //开播成功,创建频道
+ if (swManager != null) {
+ swManager.createRoom(SWManager.shengwang_token, SWManager.shengwang_channelName);
+ }
if (rcrtcLiveInfo != null) {
rcrtcLiveInfo.addPublishStreamUrl(pushUrl, new IRCRTCResultDataCallback() {
@Override
@@ -946,7 +957,7 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
public void onResume() {
mPaused = false;
Log.i("摄像头", "onResume: " + isNeedOpenCamera);
- if(isNeedOpenCamera){
+ if (isNeedOpenCamera) {
RCRTCEngine.getInstance().getDefaultVideoStream().startCamera(new IRCRTCResultDataCallback() {
@Override
public void onSuccess(Boolean data) {
diff --git a/live/src/main/res/layout/acticity_new_live.xml b/live/src/main/res/layout/acticity_new_live.xml
new file mode 100644
index 000000000..886d43dcd
--- /dev/null
+++ b/live/src/main/res/layout/acticity_new_live.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/live/src/main/res/layout/view_live_play_ksy.xml b/live/src/main/res/layout/view_live_play_ksy.xml
index 91b5d0346..b602c6757 100644
--- a/live/src/main/res/layout/view_live_play_ksy.xml
+++ b/live/src/main/res/layout/view_live_play_ksy.xml
@@ -12,8 +12,14 @@
android:layout_width="match_parent"
app:surface_type="texture_view"
app:use_controller="false"
+ android:visibility="gone"
android:layout_height="match_parent" />
+
+