Commit b6a1ddec by mReturn

横屏直播

parent 69d53b70
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
<option value="$PROJECT_DIR$/IDCardLib" /> <option value="$PROJECT_DIR$/IDCardLib" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/baseSDK" /> <option value="$PROJECT_DIR$/baseSDK" />
<option value="$PROJECT_DIR$/beauty" />
<option value="$PROJECT_DIR$/camera" /> <option value="$PROJECT_DIR$/camera" />
<option value="$PROJECT_DIR$/learnCenter" /> <option value="$PROJECT_DIR$/learnCenter" />
<option value="$PROJECT_DIR$/liveModule" />
<option value="$PROJECT_DIR$/locationComponent" /> <option value="$PROJECT_DIR$/locationComponent" />
<option value="$PROJECT_DIR$/managercenter" /> <option value="$PROJECT_DIR$/managercenter" />
<option value="$PROJECT_DIR$/messageCenter" /> <option value="$PROJECT_DIR$/messageCenter" />
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
<module fileurl="file://$PROJECT_DIR$/IDCardLib/IDCardLib.iml" filepath="$PROJECT_DIR$/IDCardLib/IDCardLib.iml" /> <module fileurl="file://$PROJECT_DIR$/IDCardLib/IDCardLib.iml" filepath="$PROJECT_DIR$/IDCardLib/IDCardLib.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/baseSDK/baseSDK.iml" filepath="$PROJECT_DIR$/baseSDK/baseSDK.iml" /> <module fileurl="file://$PROJECT_DIR$/baseSDK/baseSDK.iml" filepath="$PROJECT_DIR$/baseSDK/baseSDK.iml" />
<module fileurl="file://$PROJECT_DIR$/beauty/beauty.iml" filepath="$PROJECT_DIR$/beauty/beauty.iml" />
<module fileurl="file://$PROJECT_DIR$/camera/camera.iml" filepath="$PROJECT_DIR$/camera/camera.iml" /> <module fileurl="file://$PROJECT_DIR$/camera/camera.iml" filepath="$PROJECT_DIR$/camera/camera.iml" />
<module fileurl="file://$PROJECT_DIR$/dayu-saas-android.iml" filepath="$PROJECT_DIR$/dayu-saas-android.iml" /> <module fileurl="file://$PROJECT_DIR$/dayu-saas-android.iml" filepath="$PROJECT_DIR$/dayu-saas-android.iml" />
<module fileurl="file://$PROJECT_DIR$/learnCenter/learnCenter.iml" filepath="$PROJECT_DIR$/learnCenter/learnCenter.iml" /> <module fileurl="file://$PROJECT_DIR$/learnCenter/learnCenter.iml" filepath="$PROJECT_DIR$/learnCenter/learnCenter.iml" />
<module fileurl="file://$PROJECT_DIR$/liveModule/liveModule.iml" filepath="$PROJECT_DIR$/liveModule/liveModule.iml" />
<module fileurl="file://$PROJECT_DIR$/locationComponent/locationComponent.iml" filepath="$PROJECT_DIR$/locationComponent/locationComponent.iml" /> <module fileurl="file://$PROJECT_DIR$/locationComponent/locationComponent.iml" filepath="$PROJECT_DIR$/locationComponent/locationComponent.iml" />
<module fileurl="file://$PROJECT_DIR$/managercenter/managercenter.iml" filepath="$PROJECT_DIR$/managercenter/managercenter.iml" /> <module fileurl="file://$PROJECT_DIR$/managercenter/managercenter.iml" filepath="$PROJECT_DIR$/managercenter/managercenter.iml" />
<module fileurl="file://$PROJECT_DIR$/messageCenter/messageCenter.iml" filepath="$PROJECT_DIR$/messageCenter/messageCenter.iml" /> <module fileurl="file://$PROJECT_DIR$/messageCenter/messageCenter.iml" filepath="$PROJECT_DIR$/messageCenter/messageCenter.iml" />
......
...@@ -42,18 +42,18 @@ public class Constants { ...@@ -42,18 +42,18 @@ public class Constants {
/** /**
* dev环境配置. * dev环境配置.
*/ */
// public static String ENVIROMENT = "debug"; public static String ENVIROMENT = "debug";
// public static final int LOG_LEVEL = LogUtils.LEVEL_ALL; public static final int LOG_LEVEL = LogUtils.LEVEL_ALL;
// public static String BASE_URL = "http://47.94.101.239:3112"; public static String BASE_URL = "http://47.94.101.239:3112";
// public static String WEB_SOP = "http://47.94.101.239:9004/#/sop"; public static String WEB_SOP = "http://47.94.101.239:9004/#/sop";
// public static String CHECK_MULTI_WEB_SOP = "http://47.94.101.239:9004/#/manyServiceResult"; public static String CHECK_MULTI_WEB_SOP = "http://47.94.101.239:9004/#/manyServiceResult";
// public static String MULTI_WEB_SOP = "http://47.94.101.239:9004/#/manySop"; public static String MULTI_WEB_SOP = "http://47.94.101.239:9004/#/manySop";
// public static String WEB_SOP_DETAIL = "http://47.94.101.239:9004/#/sopdetail"; public static String WEB_SOP_DETAIL = "http://47.94.101.239:9004/#/sopdetail";
// public static String WEB_ZHI_SHI = "http://47.94.101.239:9004/#/detail"; public static String WEB_ZHI_SHI = "http://47.94.101.239:9004/#/detail";
// public static final String UP_PHOTO = "/file/uploadMore?targetPath=test/sp/mobile/android/business/checkApply"; public static final String UP_PHOTO = "/file/uploadMore?targetPath=test/sp/mobile/android/business/checkApply";
// public static final String UP_VIDEO = "/file/uploadVideoOne?targetPath=dev/video"; public static final String UP_VIDEO = "/file/uploadVideoOne?targetPath=dev/video";
// public static final boolean IS_DEBUG = true; public static final boolean IS_DEBUG = true;
// public static String VIDEO_SHARE_URL = "http://uat.kf.ai:9099/#/shareVideo?type=_type&id="; //uat 学习视频分享链接 type(课程: course 直播: live) public static String VIDEO_SHARE_URL = "http://uat.kf.ai:9099/#/shareVideo?type=_type&id="; //uat 学习视频分享链接 type(课程: course 直播: live)
/** /**
...@@ -77,18 +77,18 @@ public class Constants { ...@@ -77,18 +77,18 @@ public class Constants {
/** /**
* 正式环境. * 正式环境.
*/ */
public static String ENVIROMENT = "release"; // public static String ENVIROMENT = "release";
public static int LOG_LEVEL = LogUtils.LEVEL_OFF; // public static int LOG_LEVEL = LogUtils.LEVEL_OFF;
public static String BASE_URL = "https://mobile.kf.ai"; // public static String BASE_URL = "https://mobile.kf.ai";
public static String WEB_SOP = "https://sop.kf.ai/#/sop"; // public static String WEB_SOP = "https://sop.kf.ai/#/sop";
public static String WEB_SOP_DETAIL = "https://sop.kf.ai/#/sopdetail"; // public static String WEB_SOP_DETAIL = "https://sop.kf.ai/#/sopdetail";
public static String WEB_ZHI_SHI = "https://sop.kf.ai/#/detail"; // public static String WEB_ZHI_SHI = "https://sop.kf.ai/#/detail";
public static String CHECK_MULTI_WEB_SOP = "https://sop.kf.ai/#/manyServiceResult"; // public static String CHECK_MULTI_WEB_SOP = "https://sop.kf.ai/#/manyServiceResult";
public static String MULTI_WEB_SOP = "https://sop.kf.ai/#/manySop"; // public static String MULTI_WEB_SOP = "https://sop.kf.ai/#/manySop";
public static final String UP_PHOTO = "/file/uploadMore?targetPath=online/sp/mobile/android/business/checkApply"; // public static final String UP_PHOTO = "/file/uploadMore?targetPath=online/sp/mobile/android/business/checkApply";
public static final String UP_VIDEO = "/file/uploadVideoOne?targetPath=online/video"; // public static final String UP_VIDEO = "/file/uploadVideoOne?targetPath=online/video";
public static final boolean IS_DEBUG = false; // public static final boolean IS_DEBUG = false;
public static String VIDEO_SHARE_URL = "http://app.dl.kf.ai/ext/#/shareVideo?type=_type&id="; //学习视频分享链接 type(课程: course 直播: live) // public static String VIDEO_SHARE_URL = "http://app.dl.kf.ai/ext/#/shareVideo?type=_type&id="; //学习视频分享链接 type(课程: course 直播: live)
/** /**
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
/> />
<activity android:name=".ui.activity.VideoPlayActivity" <activity android:name=".ui.activity.VideoPlayActivity"
android:screenOrientation="portrait" android:screenOrientation="landscape"
/> />
</application> </application>
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity <activity
android:name=".xiaozhibo.audience.TCAudienceActivity" android:name=".xiaozhibo.audience.TCAudienceActivity"
android:screenOrientation="portrait" android:screenOrientation="landscape"
android:theme="@style/PlayerTheme" android:theme="@style/PlayerTheme"
android:windowSoftInputMode="adjustNothing" /> android:windowSoftInputMode="adjustNothing" />
<activity <activity
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
android:windowSoftInputMode="adjustNothing" /> android:windowSoftInputMode="adjustNothing" />
<activity <activity
android:name=".xiaozhibo.anchor.TCCameraAnchorActivity" android:name=".xiaozhibo.anchor.TCCameraAnchorActivity"
android:screenOrientation="portrait" android:screenOrientation="landscape"
android:theme="@style/PlayerTheme"
android:windowSoftInputMode="adjustNothing" /> android:windowSoftInputMode="adjustNothing" />
<activity <activity
android:name=".xiaozhibo.anchor.screen.TCScreenAnchorActivity" android:name=".xiaozhibo.anchor.screen.TCScreenAnchorActivity"
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dayu.livemodule" >
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- IMSDK 权限 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!--<uses-permission android:name="android.permission.SET_DEBUG_APP" />-->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<application
android:usesCleartextTraffic="true"
android:largeHeap="true"
>
<activity
android:name=".xiaozhibo.login.TCLoginActivity"
android:screenOrientation="portrait"
android:theme="@style/LoginTheme" />
<activity
android:name=".xiaozhibo.login.TCRegisterActivity"
android:screenOrientation="portrait"
android:theme="@style/RegisterTheme" />
<activity
android:name=".xiaozhibo.main.TCMainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTask"/>
<activity
android:name=".xiaozhibo.anchor.prepare.TCAnchorPrepareActivity"
android:screenOrientation="portrait" />
<activity
android:name=".xiaozhibo.audience.TCAudienceActivity"
android:screenOrientation="landscape"
android:theme="@style/PlayerTheme"
android:windowSoftInputMode="adjustNothing" />
<activity
android:name=".xiaozhibo.playback.TCPlaybackActivity"
android:screenOrientation="portrait"
android:theme="@style/PlayerTheme"
android:windowSoftInputMode="adjustNothing" />
<activity
android:name=".xiaozhibo.anchor.TCCameraAnchorActivity"
android:screenOrientation="landscape"
android:theme="@style/PlayerTheme"
android:windowSoftInputMode="adjustNothing" />
<activity
android:name=".xiaozhibo.anchor.screen.TCScreenAnchorActivity"
android:theme="@style/RecordActivityTheme"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustNothing"
android:launchMode="singleTask">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".xiaozhibo.anchor.screen.TCScreenRecordService"
android:enabled="true"
android:exported="false">
</service>
<activity android:name="com.tencent.rtmp.video.TXScreenCapture$TXScreenCaptureAssistantActivity" android:theme="@android:style/Theme.Translucent" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.dayu.bigfish.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
<uses-library
android:name="com.google.android.maps"
android:required="false" />
<uses-library android:name="android.test.runner" />
<service
android:name="com.tencent.imsdk.session.remote.SessionService"
android:process=":network" />
<service
android:name="com.tencent.imsdk.session.remote.AssistService"
android:process=":network" />
<service
android:name="com.tencent.imsdk.session.remote.KeepAliveJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":network" />
<receiver android:name="com.tencent.imsdk.session.SessionBroadcastReceiver" >
<intent-filter>
<action android:name="com.tencent.imsdk.session.boot" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.tencent.qcloud.qal.TASK_REMOVED" />
</intent-filter>
</receiver>
</application>
</manifest>
...@@ -57,67 +57,69 @@ import java.util.Vector; ...@@ -57,67 +57,69 @@ import java.util.Vector;
public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.HeartBeatCallback, IMMessageMgr.IMMessageListener { public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.HeartBeatCallback, IMMessageMgr.IMMessageListener {
protected static final String TAG = MLVBLiveRoomImpl.class.getName(); protected static final String TAG = MLVBLiveRoomImpl.class.getName();
protected static final int LIVEROOM_ROLE_NONE = 0; protected static final int LIVEROOM_ROLE_NONE = 0;
protected static final int LIVEROOM_ROLE_PUSHER = 1; protected static final int LIVEROOM_ROLE_PUSHER = 1;
protected static final int LIVEROOM_ROLE_PLAYER = 2; protected static final int LIVEROOM_ROLE_PLAYER = 2;
protected static MLVBLiveRoomImpl mInstance = null; protected static MLVBLiveRoomImpl mInstance = null;
protected static final String mServerDomain = "https://liveroom.qcloud.com/weapp/live_room"; //RoomService后台域名 protected static final String mServerDomain = "https://liveroom.qcloud.com/weapp/live_room"; //RoomService后台域名
protected Context mAppContext = null; protected Context mAppContext = null;
protected IMLVBLiveRoomListener mListener = null; protected IMLVBLiveRoomListener mListener = null;
protected int mSelfRoleType = LIVEROOM_ROLE_NONE; protected int mSelfRoleType = LIVEROOM_ROLE_NONE;
protected boolean mJoinPusher = false; protected boolean mJoinPusher = false;
protected boolean mBackground = false; protected boolean mBackground = false;
protected TXLivePlayer mTXLivePlayer; protected TXLivePlayer mTXLivePlayer;
protected TXLivePlayConfig mTXLivePlayConfig; protected TXLivePlayConfig mTXLivePlayConfig;
protected Handler mListenerHandler = null; protected Handler mListenerHandler = null;
protected HttpRequests mHttpRequest = null; //HTTP CGI请求相关 protected HttpRequests mHttpRequest = null; //HTTP CGI请求相关
protected IMMessageMgr mIMMessageMgr; //IM SDK相关 protected IMMessageMgr mIMMessageMgr; //IM SDK相关
protected LoginInfo mSelfAccountInfo; protected LoginInfo mSelfAccountInfo;
protected StreamMixturer mStreamMixturer; //混流类 protected StreamMixturer mStreamMixturer; //混流类
protected HeartBeatThread mHeartBeatThread; //心跳 protected HeartBeatThread mHeartBeatThread; //心跳
protected String mCurrRoomID; protected String mCurrRoomID;
protected int mRoomStatusCode = 0; protected int mRoomStatusCode = 0;
protected ArrayList<RoomInfo> mRoomList = new ArrayList<>(); protected ArrayList<RoomInfo> mRoomList = new ArrayList<>();
protected TXLivePusher mTXLivePusher; protected TXLivePusher mTXLivePusher;
protected TXLivePushListenerImpl mTXLivePushListener; protected TXLivePushListenerImpl mTXLivePushListener;
protected String mSelfPushUrl; protected String mSelfPushUrl;
protected String mSelfAccelerateURL; protected String mSelfAccelerateURL;
protected HashMap<String, PlayerItem> mPlayers = new LinkedHashMap<>(); protected HashMap<String, PlayerItem> mPlayers = new LinkedHashMap<>();
protected HashMap<String, AnchorInfo> mPushers = new LinkedHashMap<>(); protected HashMap<String, AnchorInfo> mPushers = new LinkedHashMap<>();
private IMLVBLiveRoomListener.RequestJoinAnchorCallback mJoinAnchorCallback; private IMLVBLiveRoomListener.RequestJoinAnchorCallback mJoinAnchorCallback;
private Runnable mJoinAnchorTimeoutTask; private Runnable mJoinAnchorTimeoutTask;
private IMLVBLiveRoomListener.RequestRoomPKCallback mRequestPKCallback = null; private IMLVBLiveRoomListener.RequestRoomPKCallback mRequestPKCallback = null;
private Runnable mRequestPKTimeoutTask = null; private Runnable mRequestPKTimeoutTask = null;
private AnchorInfo mPKAnchorInfo = null; private AnchorInfo mPKAnchorInfo = null;
//观众列表最大长度 //观众列表最大长度
private static final int MAX_MEMBER_SIZE = 20; private static final int MAX_MEMBER_SIZE = 20;
//更新观众列表的频率,防止观众进房太多导致的刷新频率太高 //更新观众列表的频率,防止观众进房太多导致的刷新频率太高
private static final int REFRESH_AUDIENCE_INTERVAL_MS = 2000; private static final int REFRESH_AUDIENCE_INTERVAL_MS = 2000;
private long mLastEnterAudienceTimeMS = 0; private long mLastEnterAudienceTimeMS = 0;
private long mLastExitAudienceTimeMS = 0; private long mLastExitAudienceTimeMS = 0;
//观众列表 //观众列表
private LinkedHashMap<String/*userID*/, AudienceInfo> mAudiences = null; private LinkedHashMap<String/*userID*/, AudienceInfo> mAudiences = null;
private static final int LIVEROOM_CAMERA_PREVIEW = 0; private static final int LIVEROOM_CAMERA_PREVIEW = 0;
private static final int LIVEROOM_SCREEN_PREVIEW = 1; private static final int LIVEROOM_SCREEN_PREVIEW = 1;
private int mPreviewType = LIVEROOM_CAMERA_PREVIEW; private int mPreviewType = LIVEROOM_CAMERA_PREVIEW;
protected boolean mScreenAutoEnable = true; protected boolean mScreenAutoEnable = true;
private boolean mHasAddAnchor = false; private boolean mHasAddAnchor = false;
private static final int STREAM_MIX_MODE_JOIN_ANCHOR = 0; private static final int STREAM_MIX_MODE_JOIN_ANCHOR = 0;
private static final int STREAM_MIX_MODE_PK = 1; private static final int STREAM_MIX_MODE_PK = 1;
private int mMixMode = STREAM_MIX_MODE_JOIN_ANCHOR; private int mMixMode = STREAM_MIX_MODE_JOIN_ANCHOR;
private long mTimeDiff = 0; //客户端和服务器时间差,用户连麦和PK请求超时处理 private long mTimeDiff = 0; //客户端和服务器时间差,用户连麦和PK请求超时处理
private boolean isFrontCamera;
public static MLVBLiveRoom sharedInstance(Context context) { public static MLVBLiveRoom sharedInstance(Context context) {
synchronized (MLVBLiveRoomImpl.class) { synchronized (MLVBLiveRoomImpl.class) {
...@@ -139,7 +141,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -139,7 +141,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 设置回调接口 * 设置回调接口
* * <p>
* 您可以通过 IMLVBLiveRoomListener 获得 MLVBLiveRoom 的各种状态通知 * 您可以通过 IMLVBLiveRoomListener 获得 MLVBLiveRoom 的各种状态通知
* *
* @param listener 回调接口 * @param listener 回调接口
...@@ -276,7 +278,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -276,7 +278,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 获取房间列表 * 获取房间列表
* * <p>
* 该接口支持分页获取房间列表,可以用 index 和 count 两个参数控制列表分页的逻辑, * 该接口支持分页获取房间列表,可以用 index 和 count 两个参数控制列表分页的逻辑,
* - index = 0 & count = 10 代表获取第一页的10个房间。 * - index = 0 & count = 10 代表获取第一页的10个房间。
* - index = 11 & count = 10 代表获取第二页的10个房间。 * - index = 11 & count = 10 代表获取第二页的10个房间。
...@@ -296,9 +298,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -296,9 +298,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mHttpRequest.getRoomList(index, count, new HttpRequests.OnResponseCallback<HttpResponse.RoomList>() { mHttpRequest.getRoomList(index, count, new HttpRequests.OnResponseCallback<HttpResponse.RoomList>() {
@Override @Override
public void onResponse(final int retcode, final String retmsg, HttpResponse.RoomList data) { public void onResponse(final int retcode, final String retmsg, HttpResponse.RoomList data) {
if (retcode != HttpResponse.CODE_OK || data == null || data.rooms == null){ if (retcode != HttpResponse.CODE_OK || data == null || data.rooms == null) {
callbackOnThread(callback, "onError", retcode, "[LiveRoom] getRoomList 失败[" + retmsg + "]"); callbackOnThread(callback, "onError", retcode, "[LiveRoom] getRoomList 失败[" + retmsg + "]");
}else { } else {
final ArrayList<RoomInfo> arrayList = new ArrayList<>(data.rooms.size()); final ArrayList<RoomInfo> arrayList = new ArrayList<>(data.rooms.size());
arrayList.addAll(data.rooms); arrayList.addAll(data.rooms);
mRoomList = arrayList; mRoomList = arrayList;
...@@ -310,7 +312,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -310,7 +312,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 获取观众列表 * 获取观众列表
* * <p>
* 当有观众进房时,后台会将其信息加入到指定房间的观众列表中,调入该函数即可返回指定房间的观众列表 * 当有观众进房时,后台会将其信息加入到指定房间的观众列表中,调入该函数即可返回指定房间的观众列表
* *
* @param callback 获取观众列表的结果回调。 * @param callback 获取观众列表的结果回调。
...@@ -318,7 +320,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -318,7 +320,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
*/ */
@Override @Override
public void getAudienceList(final IMLVBLiveRoomListener.GetAudienceListCallback callback) { public void getAudienceList(final IMLVBLiveRoomListener.GetAudienceListCallback callback) {
TXCLog.i(TAG, "API -> getAudienceList " +mCurrRoomID); TXCLog.i(TAG, "API -> getAudienceList " + mCurrRoomID);
if (mCurrRoomID == null || mCurrRoomID.length() == 0) { if (mCurrRoomID == null || mCurrRoomID.length() == 0) {
callbackOnThread(callback, "onError", MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_IN_ROOM, "[LiveRoom] getAudienceList 失败[房间号为空]"); callbackOnThread(callback, "onError", MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_IN_ROOM, "[LiveRoom] getAudienceList 失败[房间号为空]");
return; return;
...@@ -358,7 +360,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -358,7 +360,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 创建房间(主播调用) * 创建房间(主播调用)
* * <p>
* 主播开播的正常调用流程是: * 主播开播的正常调用流程是:
* 1.【主播】调用 startLocalPreview() 打开摄像头预览,此时可以调整美颜参数。 * 1.【主播】调用 startLocalPreview() 打开摄像头预览,此时可以调整美颜参数。
* 2.【主播】调用 createRoom 创建直播间,房间创建成功与否会通过 {@link IMLVBLiveRoomListener.CreateRoomCallback} 通知给主播。 * 2.【主播】调用 createRoom 创建直播间,房间创建成功与否会通过 {@link IMLVBLiveRoomListener.CreateRoomCallback} 通知给主播。
...@@ -381,12 +383,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -381,12 +383,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
public void onResponse(int retcode, String retmsg, HttpResponse.PushUrl data) { public void onResponse(int retcode, String retmsg, HttpResponse.PushUrl data) {
if (retcode == HttpResponse.CODE_OK && data != null && data.pushURL != null) { if (retcode == HttpResponse.CODE_OK && data != null && data.pushURL != null) {
// final String pushURL = data.pushURL; // final String pushURL = data.pushURL;
final String pushURL = TCGlobalConfig.pushURLPrefix +data.pushURL.substring(data.pushURL.indexOf("/live"),data.pushURL.length()); final String pushURL = TCGlobalConfig.pushURLPrefix + data.pushURL.substring(data.pushURL.indexOf("/live"), data.pushURL.length());
mSelfPushUrl = pushURL; mSelfPushUrl = pushURL;
mSelfAccelerateURL = data.accelerateURL; mSelfAccelerateURL = data.accelerateURL;
TXCLog.i(TAG, "API -> createRoom push url:" +pushURL); TXCLog.i(TAG, "API -> createRoom push url:" + pushURL);
TXCLog.i(TAG, "API -> createRoom push url2:" +data.pushURL); TXCLog.i(TAG, "API -> createRoom push url2:" + data.pushURL);
//3.开始推流 //3.开始推流
startPushStream(pushURL, TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION, new StandardCallback() { startPushStream(pushURL, TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION, new StandardCallback() {
...@@ -408,14 +410,14 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -408,14 +410,14 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mTXLivePusher.setConfig(config); mTXLivePusher.setConfig(config);
} }
EventBus.getDefault().post(new StartPushEvent(true,mSelfPushUrl,roomInfo)); EventBus.getDefault().post(new StartPushEvent(true, mSelfPushUrl, roomInfo));
mBackground = false; mBackground = false;
//4.推流成功,请求CGI:create_room,获取roomID、roomSig //4.推流成功,请求CGI:create_room,获取roomID、roomSig
String mRoomInfo = roomInfo; String mRoomInfo = roomInfo;
if (!TextUtils.isEmpty(mRoomInfo)){ if (!TextUtils.isEmpty(mRoomInfo)) {
try { try {
JSONObject jsonRoomInfo = new JSONObject(mRoomInfo); JSONObject jsonRoomInfo = new JSONObject(mRoomInfo);
jsonRoomInfo.put("playurl",data.playUrl); jsonRoomInfo.put("playurl", data.playUrl);
mRoomInfo = jsonRoomInfo.toString(); mRoomInfo = jsonRoomInfo.toString();
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -470,8 +472,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -470,8 +472,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
}); });
} } else {
else {
callbackOnThread(callback, "onError", retcode, "[LiveRoom] 创建房间失败[获取推流地址失败]"); callbackOnThread(callback, "onError", retcode, "[LiveRoom] 创建房间失败[获取推流地址失败]");
} }
} }
...@@ -480,7 +481,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -480,7 +481,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 进入房间(观众调用) * 进入房间(观众调用)
* * <p>
* 观众观看直播的正常调用流程是: * 观众观看直播的正常调用流程是:
* 1.【观众】调用 getRoomList() 刷新最新的直播房间列表,并通过 {@link IMLVBLiveRoomListener.GetRoomListCallback} 回调拿到房间列表。 * 1.【观众】调用 getRoomList() 刷新最新的直播房间列表,并通过 {@link IMLVBLiveRoomListener.GetRoomListCallback} 回调拿到房间列表。
* 2.【观众】选择一个直播间以后,调用 enterRoom() 进入该房间。 * 2.【观众】选择一个直播间以后,调用 enterRoom() 进入该房间。
...@@ -521,7 +522,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -521,7 +522,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
int playType = getPlayType(mixedPlayUrl); int playType = getPlayType(mixedPlayUrl);
mTXLivePlayer.setPlayerView(view); mTXLivePlayer.setPlayerView(view);
mTXLivePlayer.startPlay(mixedPlayUrl, playType); mTXLivePlayer.startPlay(mixedPlayUrl, playType);
TXCLog.i(TAG, "startPlay "+mixedPlayUrl+" "+playType); TXCLog.i(TAG, "startPlay " + mixedPlayUrl + " " + playType);
if (mHttpRequest != null) { if (mHttpRequest != null) {
String userInfo = ""; String userInfo = "";
...@@ -536,7 +537,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -536,7 +537,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mHttpRequest.addAudience(roomID, mSelfAccountInfo.userID, userInfo, new HttpRequests.OnResponseCallback<HttpResponse>() { mHttpRequest.addAudience(roomID, mSelfAccountInfo.userID, userInfo, new HttpRequests.OnResponseCallback<HttpResponse>() {
@Override @Override
public void onResponse(int retcode, @Nullable String retmsg, @Nullable HttpResponse data) { public void onResponse(int retcode, @Nullable String retmsg, @Nullable HttpResponse data) {
TXCLog.i(TAG, "addAudience "+roomID+" "+retcode+" "+retmsg); TXCLog.i(TAG, "addAudience " + roomID + " " + retcode + " " + retmsg);
} }
}); });
} }
...@@ -563,7 +564,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -563,7 +564,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// 停止 BGM // 停止 BGM
stopBGM(); stopBGM();
if (mSelfRoleType == LIVEROOM_ROLE_PUSHER) { if (mSelfRoleType == LIVEROOM_ROLE_PUSHER) {
//2. 如果是大主播,则销毁群 //2. 如果是大主播,则销毁群
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
...@@ -657,7 +658,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -657,7 +658,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mJoinPusher = false; mJoinPusher = false;
mSelfRoleType = LIVEROOM_ROLE_NONE; mSelfRoleType = LIVEROOM_ROLE_NONE;
mCurrRoomID = ""; mCurrRoomID = "";
mPushers.clear(); mPushers.clear();
mStreamMixturer.resetMergeState(); mStreamMixturer.resetMergeState();
...@@ -667,16 +668,15 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -667,16 +668,15 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 设置自定义信息 * 设置自定义信息
* * <p>
* 有时候您可能需要为房间产生一些额外的信息,此接口可以将这些信息缓存到服务器。 * 有时候您可能需要为房间产生一些额外的信息,此接口可以将这些信息缓存到服务器。
* *
* @param op 执行动作,定义请查看 {@link MLVBCommonDef.CustomFieldOp} * @param op 执行动作,定义请查看 {@link MLVBCommonDef.CustomFieldOp}
* @param key 自定义键 * @param key 自定义键
* @param value 数值 * @param value 数值
*
* @note op 为 {@link MLVBCommonDef.CustomFieldOp#SET} 时,value 可以是 String 或者 Integer 类型 * @note op 为 {@link MLVBCommonDef.CustomFieldOp#SET} 时,value 可以是 String 或者 Integer 类型
* op 为 {@link MLVBCommonDef.CustomFieldOp#INC} 时,value 是 Integer 类型 * op 为 {@link MLVBCommonDef.CustomFieldOp#INC} 时,value 是 Integer 类型
* op 为 {@link MLVBCommonDef.CustomFieldOp#DEC} 时,value 是 Integer 类型 * op 为 {@link MLVBCommonDef.CustomFieldOp#DEC} 时,value 是 Integer 类型
*/ */
public void setCustomInfo(final MLVBCommonDef.CustomFieldOp op, final String key, final Object value, final IMLVBLiveRoomListener.SetCustomInfoCallback callback) { public void setCustomInfo(final MLVBCommonDef.CustomFieldOp op, final String key, final Object value, final IMLVBLiveRoomListener.SetCustomInfoCallback callback) {
TXCLog.i(TAG, "API -> setCustomInfo:" + op + ":" + key); TXCLog.i(TAG, "API -> setCustomInfo:" + op + ":" + key);
...@@ -732,7 +732,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -732,7 +732,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 观众请求连麦 * 观众请求连麦
* * <p>
* 主播和观众的连麦流程可以简单描述为如下几个步骤: * 主播和观众的连麦流程可以简单描述为如下几个步骤:
* 1. 【观众】调用 requestJoinAnchor() 向主播发起连麦请求。 * 1. 【观众】调用 requestJoinAnchor() 向主播发起连麦请求。
* 2. 【主播】会收到 {@link IMLVBLiveRoomListener#onRequestJoinAnchor(AnchorInfo, String)} 的回调通知。 * 2. 【主播】会收到 {@link IMLVBLiveRoomListener#onRequestJoinAnchor(AnchorInfo, String)} 的回调通知。
...@@ -787,7 +787,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -787,7 +787,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
//10秒收不到主播同意/拒绝连麦的响应,则回调超时 //10秒收不到主播同意/拒绝连麦的响应,则回调超时
mListenerHandler.postDelayed(mJoinAnchorTimeoutTask, 10 * 1000); mListenerHandler.postDelayed(mJoinAnchorTimeoutTask, 10 * 1000);
String content = new Gson().toJson(request, new TypeToken<CommonJson<JoinAnchorRequest>>(){}.getType()); String content = new Gson().toJson(request, new TypeToken<CommonJson<JoinAnchorRequest>>() {
}.getType());
String toUserID = getRoomCreator(mCurrRoomID); String toUserID = getRoomCreator(mCurrRoomID);
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
...@@ -812,21 +813,19 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -812,21 +813,19 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
}); });
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* 主播处理连麦请求 * 主播处理连麦请求
* * <p>
* 主播在收到 {@link IMLVBLiveRoomListener#onRequestJoinAnchor(AnchorInfo, String)} 回调之后会需要调用此接口来处理观众的连麦请求。 * 主播在收到 {@link IMLVBLiveRoomListener#onRequestJoinAnchor(AnchorInfo, String)} 回调之后会需要调用此接口来处理观众的连麦请求。
* *
* @param userID 观众ID * @param userID 观众ID
* @param agree true:同意;false:拒绝 * @param agree true:同意;false:拒绝
* @param reason 同意/拒绝连麦的原因描述 * @param reason 同意/拒绝连麦的原因描述
*
* @return 0:响应成功;非0:响应失败 * @return 0:响应成功;非0:响应失败
*/ */
@Override @Override
...@@ -844,11 +843,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -844,11 +843,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
response.cmd = "linkmic"; response.cmd = "linkmic";
response.data = new JoinAnchorResponse(); response.data = new JoinAnchorResponse();
response.data.type = "response"; response.data.type = "response";
response.data.result = agree?"accept":"reject"; response.data.result = agree ? "accept" : "reject";
response.data.reason = reason; response.data.reason = reason;
response.data.roomID = mCurrRoomID; response.data.roomID = mCurrRoomID;
response.data.timestamp = System.currentTimeMillis() - mTimeDiff; response.data.timestamp = System.currentTimeMillis() - mTimeDiff;
String content = new Gson().toJson(response, new TypeToken<CommonJson<JoinAnchorResponse>>(){}.getType()); String content = new Gson().toJson(response, new TypeToken<CommonJson<JoinAnchorResponse>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() { imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() {
...@@ -863,8 +863,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -863,8 +863,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
}); });
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return 0; return 0;
...@@ -872,13 +871,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -872,13 +871,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 观众进入连麦状态 * 观众进入连麦状态
* * <p>
* 进入连麦成功后,主播和其他连麦观众会收到 {@link IMLVBLiveRoomListener#onAnchorEnter(AnchorInfo)} 通知 * 进入连麦成功后,主播和其他连麦观众会收到 {@link IMLVBLiveRoomListener#onAnchorEnter(AnchorInfo)} 通知
* *
* @param callback 进入连麦的结果回调 * @param callback 进入连麦的结果回调
*/ */
@Override @Override
public void joinAnchor(String roomInfo,final IMLVBLiveRoomListener.JoinAnchorCallback callback) { public void joinAnchor(String roomInfo, final IMLVBLiveRoomListener.JoinAnchorCallback callback) {
TXCLog.i(TAG, "API -> joinAnchor"); TXCLog.i(TAG, "API -> joinAnchor");
if (mCurrRoomID == null || mCurrRoomID.length() == 0) { if (mCurrRoomID == null || mCurrRoomID.length() == 0) {
callbackOnThread(callback, "onError", MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_IN_ROOM, "[LiveRoom] 观众进入连麦失败[房间号为空,请确认是否已经进房]"); callbackOnThread(callback, "onError", MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_IN_ROOM, "[LiveRoom] 观众进入连麦失败[房间号为空,请确认是否已经进房]");
...@@ -912,12 +911,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -912,12 +911,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// mSelfPushUrl = data.pushURL; // mSelfPushUrl = data.pushURL;
// mSelfAccelerateURL = data.accelerateURL; // mSelfAccelerateURL = data.accelerateURL;
final String pushURL = TCGlobalConfig.pushURLPrefix+data.pushURL.substring(data.pushURL.indexOf("/live"),data.pushURL.length()); final String pushURL = TCGlobalConfig.pushURLPrefix + data.pushURL.substring(data.pushURL.indexOf("/live"), data.pushURL.length());
mSelfPushUrl = pushURL; mSelfPushUrl = pushURL;
mSelfAccelerateURL = data.accelerateURL; mSelfAccelerateURL = data.accelerateURL;
TXCLog.i(TAG, "API -> createRoom push join url:" +pushURL); TXCLog.i(TAG, "API -> createRoom push join url:" + pushURL);
TXCLog.i(TAG, "API -> createRoom push join url2:" +data.pushURL+" "+roomInfo); TXCLog.i(TAG, "API -> createRoom push join url2:" + data.pushURL + " " + roomInfo);
//5. 开始推流 //5. 开始推流
startPushStream(pushURL, TXLiveConstants.VIDEO_QUALITY_LINKMIC_SUB_PUBLISHER, new StandardCallback() { startPushStream(pushURL, TXLiveConstants.VIDEO_QUALITY_LINKMIC_SUB_PUBLISHER, new StandardCallback() {
...@@ -929,7 +928,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -929,7 +928,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
@Override @Override
public void onSuccess() { public void onSuccess() {
mBackground = false; mBackground = false;
EventBus.getDefault().post(new StartPushEvent(false,mSelfPushUrl,roomInfo)); EventBus.getDefault().post(new StartPushEvent(false, mSelfPushUrl, roomInfo));
//6. 推流成功,请求CGI:add_pusher,把自己加入房间成员列表 //6. 推流成功,请求CGI:add_pusher,把自己加入房间成员列表
addAnchor(mCurrRoomID, data.pushURL, new StandardCallback() { addAnchor(mCurrRoomID, data.pushURL, new StandardCallback() {
@Override @Override
...@@ -958,7 +957,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -958,7 +957,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 观众退出连麦 * 观众退出连麦
* * <p>
* 退出连麦成功后,主播和其他连麦观众会收到 {@link IMLVBLiveRoomListener#onAnchorExit(AnchorInfo)} 通知 * 退出连麦成功后,主播和其他连麦观众会收到 {@link IMLVBLiveRoomListener#onAnchorExit(AnchorInfo)} 通知
* *
* @param callback 退出连麦的结果回调 * @param callback 退出连麦的结果回调
...@@ -1025,7 +1024,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1025,7 +1024,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 主播踢除连麦观众 * 主播踢除连麦观众
* * <p>
* 主播调用此接口踢除连麦观众后,被踢连麦观众会收到 {@link IMLVBLiveRoomListener#onKickoutJoinAnchor()} 回调通知 * 主播调用此接口踢除连麦观众后,被踢连麦观众会收到 {@link IMLVBLiveRoomListener#onKickoutJoinAnchor()} 回调通知
* *
* @param userID 连麦观众ID * @param userID 连麦观众ID
...@@ -1041,30 +1040,30 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1041,30 +1040,30 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
response.data.type = "kickout"; response.data.type = "kickout";
response.data.roomID = mCurrRoomID; response.data.roomID = mCurrRoomID;
response.data.timestamp = System.currentTimeMillis() - mTimeDiff; response.data.timestamp = System.currentTimeMillis() - mTimeDiff;
String content = new Gson().toJson(response, new TypeToken<CommonJson<KickoutResponse>>(){}.getType()); String content = new Gson().toJson(response, new TypeToken<CommonJson<KickoutResponse>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() { imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() {
@Override @Override
public void onError(final int code, final String errInfo) { public void onError(final int code, final String errInfo) {
} }
@Override @Override
public void onSuccess(Object... args) { public void onSuccess(Object... args) {
} }
}); });
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* 请求跨房PK * 请求跨房PK
* * <p>
* 主播和主播之间可以跨房间 PK,两个正在直播中的主播 A 和 B,他们之间的跨房 PK 流程如下: * 主播和主播之间可以跨房间 PK,两个正在直播中的主播 A 和 B,他们之间的跨房 PK 流程如下:
* 1. 【主播 A】调用 requestRoomPK() 向主播 B 发起连麦请求。 * 1. 【主播 A】调用 requestRoomPK() 向主播 B 发起连麦请求。
* 2. 【主播 B】会收到 {@link IMLVBLiveRoomListener#onRequestRoomPK(AnchorInfo)} 回调通知。 * 2. 【主播 B】会收到 {@link IMLVBLiveRoomListener#onRequestRoomPK(AnchorInfo)} 回调通知。
...@@ -1118,7 +1117,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1118,7 +1117,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mPKAnchorInfo = new AnchorInfo(userID, "", "", ""); mPKAnchorInfo = new AnchorInfo(userID, "", "", "");
String content = new Gson().toJson(request, new TypeToken<CommonJson<PKRequest>>(){}.getType()); String content = new Gson().toJson(request, new TypeToken<CommonJson<PKRequest>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() { imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() {
...@@ -1133,21 +1133,19 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1133,21 +1133,19 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
}); });
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* 响应跨房 PK 请求 * 响应跨房 PK 请求
* * <p>
* 主播响应其他房间主播的 PK 请求,发起 PK 请求的主播会收到 {@link IMLVBLiveRoomListener.RequestRoomPKCallback} 回调通知。 * 主播响应其他房间主播的 PK 请求,发起 PK 请求的主播会收到 {@link IMLVBLiveRoomListener.RequestRoomPKCallback} 回调通知。
* *
* @param userID 发起 PK 请求的主播 ID * @param userID 发起 PK 请求的主播 ID
* @param agree true:同意;false:拒绝 * @param agree true:同意;false:拒绝
* @param reason 同意/拒绝PK的原因描述 * @param reason 同意/拒绝PK的原因描述
*
* @return 0:响应成功;非0:响应失败 * @return 0:响应成功;非0:响应失败
*/ */
@Override @Override
...@@ -1165,29 +1163,29 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1165,29 +1163,29 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
response.cmd = "pk"; response.cmd = "pk";
response.data = new PKResponse(); response.data = new PKResponse();
response.data.type = "response"; response.data.type = "response";
response.data.result = agree?"accept":"reject"; response.data.result = agree ? "accept" : "reject";
response.data.reason= reason; response.data.reason = reason;
response.data.roomID = mCurrRoomID; response.data.roomID = mCurrRoomID;
response.data.accelerateURL = mSelfAccelerateURL; response.data.accelerateURL = mSelfAccelerateURL;
response.data.timestamp = System.currentTimeMillis() - mTimeDiff; response.data.timestamp = System.currentTimeMillis() - mTimeDiff;
String content = new Gson().toJson(response, new TypeToken<CommonJson<PKResponse>>(){}.getType()); String content = new Gson().toJson(response, new TypeToken<CommonJson<PKResponse>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() { imMessageMgr.sendC2CCustomMessage(userID, content, new IMMessageMgr.Callback() {
@Override @Override
public void onError(final int code, final String errInfo) { public void onError(final int code, final String errInfo) {
} }
@Override @Override
public void onSuccess(Object... args) { public void onSuccess(Object... args) {
} }
}); });
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return 0; return 0;
...@@ -1195,7 +1193,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1195,7 +1193,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 退出跨房 PK * 退出跨房 PK
* * <p>
* 当两个主播中的任何一个退出跨房 PK 状态后,另一个主播会收到 {@link IMLVBLiveRoomListener#onQuitRoomPK(AnchorInfo)} 回调通知。 * 当两个主播中的任何一个退出跨房 PK 状态后,另一个主播会收到 {@link IMLVBLiveRoomListener#onQuitRoomPK(AnchorInfo)} 回调通知。
* *
* @param callback 退出跨房 PK 的结果回调 * @param callback 退出跨房 PK 的结果回调
...@@ -1217,26 +1215,26 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1217,26 +1215,26 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
request.data.accelerateURL = ""; request.data.accelerateURL = "";
request.data.timestamp = System.currentTimeMillis() - mTimeDiff; request.data.timestamp = System.currentTimeMillis() - mTimeDiff;
String content = new Gson().toJson(request, new TypeToken<CommonJson<PKRequest>>() {}.getType()); String content = new Gson().toJson(request, new TypeToken<CommonJson<PKRequest>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendC2CCustomMessage(mPKAnchorInfo.userID, content, new IMMessageMgr.Callback() { imMessageMgr.sendC2CCustomMessage(mPKAnchorInfo.userID, content, new IMMessageMgr.Callback() {
@Override @Override
public void onError(final int code, final String errInfo) { public void onError(final int code, final String errInfo) {
callbackOnThread(callback, "onError", code, "[IM] 退出PK失败[" + errInfo + ":" + code + "]"); callbackOnThread(callback, "onError", code, "[IM] 退出PK失败[" + errInfo + ":" + code + "]");
} }
@Override @Override
public void onSuccess(Object... args) { public void onSuccess(Object... args) {
callbackOnThread(callback, "onSuccess"); callbackOnThread(callback, "onSuccess");
} }
}); });
} }
} else { } else {
TXCLog.e(TAG, "获取不到 PK 主播信息,请确认是否已经跨房 PK"); TXCLog.e(TAG, "获取不到 PK 主播信息,请确认是否已经跨房 PK");
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -1250,11 +1248,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1250,11 +1248,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
@Override @Override
public void startLocalPreview(boolean frontCamera, TXCloudVideoView view) { public void startLocalPreview(boolean frontCamera, TXCloudVideoView view) {
TXCLog.i(TAG, "API -> startLocalPreview:" + frontCamera); TXCLog.i(TAG, "API -> startLocalPreview:" + frontCamera);
isFrontCamera = frontCamera;
initLivePusher(frontCamera); initLivePusher(frontCamera);
if (mTXLivePusher != null) { if (mTXLivePusher != null) {
if (view != null) { if (view != null) {
view.setVisibility(View.VISIBLE); view.setVisibility(View.VISIBLE);
} }
mTXLivePusher.setMirror(isFrontCamera);
mTXLivePusher.startCameraPreview(view); mTXLivePusher.startCameraPreview(view);
} }
mPreviewType = LIVEROOM_CAMERA_PREVIEW; mPreviewType = LIVEROOM_CAMERA_PREVIEW;
...@@ -1278,7 +1278,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1278,7 +1278,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
* @param anchorInfo 对方的用户信息 * @param anchorInfo 对方的用户信息
* @param view 承载视频画面的控件 * @param view 承载视频画面的控件
* @param callback 播放器监听器 * @param callback 播放器监听器
*
* @note 在 onUserVideoAvailable 回调时,调用这个接口 * @note 在 onUserVideoAvailable 回调时,调用这个接口
*/ */
@Override @Override
...@@ -1307,7 +1306,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1307,7 +1306,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
//PK //PK
mTXLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_LINKMIC_MAIN_PUBLISHER, true, true); mTXLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_LINKMIC_MAIN_PUBLISHER, true, true);
TXLivePushConfig config = mTXLivePusher.getConfig(); TXLivePushConfig config = mTXLivePusher.getConfig();
config.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_360_640); // config.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_360_640);
config.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_640_360); //横屏分辨率
config.setAutoAdjustBitrate(false); config.setAutoAdjustBitrate(false);
config.setVideoBitrate(800); config.setVideoBitrate(800);
mTXLivePusher.setConfig(config); mTXLivePusher.setConfig(config);
...@@ -1342,8 +1342,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1342,8 +1342,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
callbackOnThread(callback, "onBegin"); callbackOnThread(callback, "onBegin");
} } else if (event == TXLiveConstants.PLAY_EVT_PLAY_END || event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT) {
else if (event == TXLiveConstants.PLAY_EVT_PLAY_END || event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT){
callbackOnThread(callback, "onError", event, "[LivePlayer] 播放异常[" + param.getString(TXLiveConstants.EVT_DESCRIPTION) + "]"); callbackOnThread(callback, "onError", event, "[LivePlayer] 播放异常[" + param.getString(TXLiveConstants.EVT_DESCRIPTION) + "]");
//结束播放 //结束播放
...@@ -1353,8 +1352,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1353,8 +1352,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// item.destroy(); // item.destroy();
// } // }
// } // }
} } else {
else {
callbackOnThread(callback, "onEvent", event, param); callbackOnThread(callback, "onEvent", event, param);
} }
} }
...@@ -1366,7 +1364,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1366,7 +1364,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
}); });
int result = player.startPlay(anchorInfo.accelerateURL, TXLivePlayer.PLAY_TYPE_LIVE_RTMP_ACC); int result = player.startPlay(anchorInfo.accelerateURL, TXLivePlayer.PLAY_TYPE_LIVE_RTMP_ACC);
if (result != 0){ if (result != 0) {
TXCLog.e(TAG, String.format("[BaseRoom] 播放成员 {%s} 地址 {%s} 失败", anchorInfo.userID, anchorInfo.accelerateURL)); TXCLog.e(TAG, String.format("[BaseRoom] 播放成员 {%s} 地址 {%s} 失败", anchorInfo.userID, anchorInfo.accelerateURL));
} }
} }
...@@ -1388,7 +1386,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1388,7 +1386,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
handler.post(new Runnable() { handler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
if (mPlayers.containsKey(anchorInfo.userID)){ if (mPlayers.containsKey(anchorInfo.userID)) {
PlayerItem pusherPlayer = mPlayers.remove(anchorInfo.userID); PlayerItem pusherPlayer = mPlayers.remove(anchorInfo.userID);
pusherPlayer.destroy(); pusherPlayer.destroy();
} }
...@@ -1420,7 +1418,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1420,7 +1418,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 启动录屏。 * 启动录屏。
*
*/ */
public synchronized void startScreenCapture() { public synchronized void startScreenCapture() {
TXCLog.i(TAG, "API -> startScreenCapture"); TXCLog.i(TAG, "API -> startScreenCapture");
...@@ -1433,7 +1430,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1433,7 +1430,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 结束录屏。 * 结束录屏。
*
*/ */
public synchronized void stopScreenCapture() { public synchronized void stopScreenCapture() {
TXCLog.i(TAG, "API -> stopScreenCapture"); TXCLog.i(TAG, "API -> stopScreenCapture");
...@@ -1473,7 +1469,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1473,7 +1469,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
*/ */
@Override @Override
public void muteRemoteAudio(String userID, boolean mute) { public void muteRemoteAudio(String userID, boolean mute) {
if (mPlayers.containsKey(userID)){ if (mPlayers.containsKey(userID)) {
PlayerItem pusherPlayer = mPlayers.get(userID); PlayerItem pusherPlayer = mPlayers.get(userID);
pusherPlayer.player.setMute(mute); pusherPlayer.player.setMute(mute);
} else if (userID == getRoomCreator(mCurrRoomID)) { } else if (userID == getRoomCreator(mCurrRoomID)) {
...@@ -1503,6 +1499,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1503,6 +1499,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
@Override @Override
public void switchCamera() { public void switchCamera() {
if (mTXLivePusher != null) { if (mTXLivePusher != null) {
isFrontCamera = !isFrontCamera;
mTXLivePusher.setMirror(isFrontCamera);
mTXLivePusher.switchCamera(); mTXLivePusher.switchCamera();
} }
} }
...@@ -1511,7 +1509,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1511,7 +1509,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
* 设置摄像头缩放因子(焦距) * 设置摄像头缩放因子(焦距)
* *
* @param distance 取值范围 1 - 5 ,当为1的时候为最远视角(正常镜头),当为5的时候为最近视角(放大镜头),这里最大值推荐为5,超过5后视频数据会变得模糊不清 * @param distance 取值范围 1 - 5 ,当为1的时候为最远视角(正常镜头),当为5的时候为最近视角(放大镜头),这里最大值推荐为5,超过5后视频数据会变得模糊不清
*
* @return false:调用失败;true:调用成功 * @return false:调用失败;true:调用成功
*/ */
@Override @Override
...@@ -1526,7 +1523,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1526,7 +1523,6 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
* 开关闪光灯 * 开关闪光灯
* *
* @param enable true:开启;false:关闭 * @param enable true:开启;false:关闭
*
* @return false:调用失败;true:调用成功 * @return false:调用失败;true:调用成功
*/ */
@Override @Override
...@@ -1539,7 +1535,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1539,7 +1535,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 主播屏蔽摄像头期间需要显示的等待图片 * 主播屏蔽摄像头期间需要显示的等待图片
* * <p>
* 当主播屏蔽摄像头,或者由于 App 切入后台无法使用摄像头的时候,我们需要使用一张等待图片来提示观众“主播暂时离开,请不要走开”。 * 当主播屏蔽摄像头,或者由于 App 切入后台无法使用摄像头的时候,我们需要使用一张等待图片来提示观众“主播暂时离开,请不要走开”。
* *
* @param bitmap 位图 * @param bitmap 位图
...@@ -1556,7 +1552,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1556,7 +1552,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 主播屏蔽摄像头期间需要显示的等待图片 * 主播屏蔽摄像头期间需要显示的等待图片
* * <p>
* 当主播屏蔽摄像头,或者由于 App 切入后台无法使用摄像头的时候,我们需要使用一张等待图片来提示观众“主播暂时离开,请不要走开”。 * 当主播屏蔽摄像头,或者由于 App 切入后台无法使用摄像头的时候,我们需要使用一张等待图片来提示观众“主播暂时离开,请不要走开”。
* *
* @param id 设置默认显示图片的资源文件 * @param id 设置默认显示图片的资源文件
...@@ -1623,10 +1619,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1623,10 +1619,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 添加水印,height 不用设置,sdk 内部会根据水印宽高比自动计算 height * 添加水印,height 不用设置,sdk 内部会根据水印宽高比自动计算 height
* *
* @param image 水印图片 null 表示清除水印 * @param image 水印图片 null 表示清除水印
* @param x 归一化水印位置的 X 轴坐标,取值[0,1] * @param x 归一化水印位置的 X 轴坐标,取值[0,1]
* @param y 归一化水印位置的 Y 轴坐标,取值[0,1] * @param y 归一化水印位置的 Y 轴坐标,取值[0,1]
* @param width 归一化水印宽度,取值[0,1] * @param width 归一化水印宽度,取值[0,1]
*/ */
@Override @Override
public void setWatermark(Bitmap image, float x, float y, float width) { public void setWatermark(Bitmap image, float x, float y, float width) {
...@@ -1651,13 +1647,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1651,13 +1647,12 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 设置绿幕文件 * 设置绿幕文件
* * <p>
* 目前图片支持jpg/png,视频支持mp4/3gp等Android系统支持的格式 * 目前图片支持jpg/png,视频支持mp4/3gp等Android系统支持的格式
* *
* @param file 绿幕文件位置,支持两种方式: * @param file 绿幕文件位置,支持两种方式:
* 1.资源文件放在assets目录,path直接取文件名 * 1.资源文件放在assets目录,path直接取文件名
* 2.path取文件绝对路径 * 2.path取文件绝对路径
*
* @return false:调用失败;true:调用成功 * @return false:调用失败;true:调用成功
* @note API要求18 * @note API要求18
*/ */
...@@ -1756,7 +1751,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1756,7 +1751,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 发送文本消息 * 发送文本消息
* *
* @param message 文本消息 * @param message 文本消息
* @param callback 发送消息的结果回调 * @param callback 发送消息的结果回调
* @see {@link IMLVBLiveRoomListener#onRecvRoomTextMsg(String, String, String, String, String)} * @see {@link IMLVBLiveRoomListener#onRecvRoomTextMsg(String, String, String, String, String)}
*/ */
...@@ -1783,8 +1778,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1783,8 +1778,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 发送自定义文本消息 * 发送自定义文本消息
* *
* @param cmd 命令字,由开发者自定义,主要用于区分不同消息类型 * @param cmd 命令字,由开发者自定义,主要用于区分不同消息类型
* @param message 文本消息 * @param message 文本消息
* @param callback 发送消息的结果回调 * @param callback 发送消息的结果回调
* @see {@link IMLVBLiveRoomListener#onRecvRoomCustomMsg(String, String, String, String, String, String)} * @see {@link IMLVBLiveRoomListener#onRecvRoomCustomMsg(String, String, String, String, String, String)}
*/ */
...@@ -1796,8 +1791,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1796,8 +1791,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
customMessage.data.userName = mSelfAccountInfo.userName; customMessage.data.userName = mSelfAccountInfo.userName;
customMessage.data.userAvatar = mSelfAccountInfo.userAvatar; customMessage.data.userAvatar = mSelfAccountInfo.userAvatar;
customMessage.data.cmd = cmd; customMessage.data.cmd = cmd;
customMessage.data.msg = message ; customMessage.data.msg = message;
final String content = new Gson().toJson(customMessage, new TypeToken<CommonJson<CustomMessage>>(){}.getType()); final String content = new Gson().toJson(customMessage, new TypeToken<CommonJson<CustomMessage>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendGroupCustomMessage(content, new IMMessageMgr.Callback() { imMessageMgr.sendGroupCustomMessage(content, new IMMessageMgr.Callback() {
...@@ -1882,7 +1878,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1882,7 +1878,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
@Override @Override
public void setMicVolumeOnMixing(int volume) { public void setMicVolumeOnMixing(int volume) {
if (mTXLivePusher != null) { if (mTXLivePusher != null) {
mTXLivePusher.setMicVolume(volume/100.0f); mTXLivePusher.setMicVolume(volume / 100.0f);
} }
} }
...@@ -1894,7 +1890,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1894,7 +1890,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
@Override @Override
public void setBGMVolume(int volume) { public void setBGMVolume(int volume) {
if (mTXLivePusher != null) { if (mTXLivePusher != null) {
mTXLivePusher.setBGMVolume(volume/100.0f); mTXLivePusher.setBGMVolume(volume / 100.0f);
} }
} }
...@@ -1902,13 +1898,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1902,13 +1898,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
* 设置混响效果 * 设置混响效果
* *
* @param reverbType 混响类型,详见 * @param reverbType 混响类型,详见
* {@link TXLiveConstants#REVERB_TYPE_0 } (关闭混响) * {@link TXLiveConstants#REVERB_TYPE_0 } (关闭混响)
* {@link TXLiveConstants#REVERB_TYPE_1 } (KTV) * {@link TXLiveConstants#REVERB_TYPE_1 } (KTV)
* {@link TXLiveConstants#REVERB_TYPE_2 } (小房间) * {@link TXLiveConstants#REVERB_TYPE_2 } (小房间)
* {@link TXLiveConstants#REVERB_TYPE_3 } (大会堂) * {@link TXLiveConstants#REVERB_TYPE_3 } (大会堂)
* {@link TXLiveConstants#REVERB_TYPE_4 } (低沉) * {@link TXLiveConstants#REVERB_TYPE_4 } (低沉)
* {@link TXLiveConstants#REVERB_TYPE_5 } (洪亮) * {@link TXLiveConstants#REVERB_TYPE_5 } (洪亮)
* {@link TXLiveConstants#REVERB_TYPE_6 } (磁性) * {@link TXLiveConstants#REVERB_TYPE_6 } (磁性)
*/ */
@Override @Override
public void setReverbType(int reverbType) { public void setReverbType(int reverbType) {
...@@ -1931,7 +1927,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1931,7 +1927,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 设置背景音乐的音调。 * 设置背景音乐的音调。
* * <p>
* 该接口用于混音处理,比如将背景音乐与麦克风采集到的声音混合后播放。 * 该接口用于混音处理,比如将背景音乐与麦克风采集到的声音混合后播放。
* *
* @param pitch 音调,0为正常音量,范围是 -1 - 1。 * @param pitch 音调,0为正常音量,范围是 -1 - 1。
...@@ -1945,12 +1941,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1945,12 +1941,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
/** /**
* 指定背景音乐的播放位置 * 指定背景音乐的播放位置
* *
* @note 请尽量避免频繁地调用该接口,因为该接口可能会再次读写 BGM 文件,耗时稍高。
* 例如:当配合进度条使用时,请在进度条拖动完毕的回调中调用,而避免在拖动过程中实时调用。
*
* @param position 背景音乐的播放位置,单位ms。 * @param position 背景音乐的播放位置,单位ms。
*
* @return 结果是否成功,true:成功;false:失败。 * @return 结果是否成功,true:成功;false:失败。
* @note 请尽量避免频繁地调用该接口,因为该接口可能会再次读写 BGM 文件,耗时稍高。
* 例如:当配合进度条使用时,请在进度条拖动完毕的回调中调用,而避免在拖动过程中实时调用。
*/ */
public boolean setBGMPosition(int position) { public boolean setBGMPosition(int position) {
if (mTXLivePusher != null) { if (mTXLivePusher != null) {
...@@ -1992,7 +1986,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -1992,7 +1986,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
if (ratio > 1.3f) { if (ratio > 1.3f) {
mTXLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN); mTXLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);
} else { } else {
mTXLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_ADJUST_RESOLUTION); //画面填充整个屏幕
mTXLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);
// mTXLivePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_ADJUST_RESOLUTION);
} }
} }
} }
...@@ -2010,8 +2006,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2010,8 +2006,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
protected void startPushStream(final String url, final int videoQuality, final StandardCallback callback) {
protected void startPushStream(final String url, final int videoQuality, final StandardCallback callback){
//在主线程开启推流 //在主线程开启推流
Handler handler = new Handler(mAppContext.getMainLooper()); Handler handler = new Handler(mAppContext.getMainLooper());
handler.post(new Runnable() { handler.post(new Runnable() {
...@@ -2024,18 +2019,20 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2024,18 +2019,20 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
if (ret == -5) { if (ret == -5) {
String msg = "[LiveRoom] 推流失败[license 校验失败]"; String msg = "[LiveRoom] 推流失败[license 校验失败]";
TXCLog.e(TAG, msg); TXCLog.e(TAG, msg);
if (callback != null) callback.onError(MLVBCommonDef.LiveRoomErrorCode.ERROR_LICENSE_INVALID, msg); if (callback != null)
callback.onError(MLVBCommonDef.LiveRoomErrorCode.ERROR_LICENSE_INVALID, msg);
} }
} else { } else {
String msg = "[LiveRoom] 推流失败[TXLivePusher未初始化,请确保已经调用startLocalPreview]"; String msg = "[LiveRoom] 推流失败[TXLivePusher未初始化,请确保已经调用startLocalPreview]";
TXCLog.e(TAG, msg); TXCLog.e(TAG, msg);
if (callback != null) callback.onError(MLVBCommonDef.LiveRoomErrorCode.ERROR_PUSH, msg); if (callback != null)
callback.onError(MLVBCommonDef.LiveRoomErrorCode.ERROR_PUSH, msg);
} }
} }
}); });
} }
protected void doCreateRoom(final String roomID, String roomInfo, final StandardCallback callback){ protected void doCreateRoom(final String roomID, String roomInfo, final StandardCallback callback) {
mHttpRequest.createRoom(roomID, mSelfAccountInfo.userID, roomInfo, mHttpRequest.createRoom(roomID, mSelfAccountInfo.userID, roomInfo,
new HttpRequests.OnResponseCallback<HttpResponse.CreateRoom>() { new HttpRequests.OnResponseCallback<HttpResponse.CreateRoom>() {
@Override @Override
...@@ -2093,7 +2090,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2093,7 +2090,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
protected void jionIMGroup(final String roomID, final StandardCallback callback){ protected void jionIMGroup(final String roomID, final StandardCallback callback) {
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.jionGroup(roomID, new IMMessageMgr.Callback() { imMessageMgr.jionGroup(roomID, new IMMessageMgr.Callback() {
...@@ -2118,7 +2115,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2118,7 +2115,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
msg.cmd = "notifyPusherChange"; msg.cmd = "notifyPusherChange";
msg.data = new AnchorInfo(); msg.data = new AnchorInfo();
msg.data.userID = mSelfAccountInfo.userID; msg.data.userID = mSelfAccountInfo.userID;
String content = new Gson().toJson(msg, new TypeToken<CommonJson<AnchorInfo>>(){}.getType()); String content = new Gson().toJson(msg, new TypeToken<CommonJson<AnchorInfo>>() {
}.getType());
IMMessageMgr imMessageMgr = mIMMessageMgr; IMMessageMgr imMessageMgr = mIMMessageMgr;
if (imMessageMgr != null) { if (imMessageMgr != null) {
imMessageMgr.sendGroupCustomMessage(content, new IMMessageMgr.Callback() { imMessageMgr.sendGroupCustomMessage(content, new IMMessageMgr.Callback() {
...@@ -2144,7 +2142,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2144,7 +2142,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
protected void updateAnchors(final boolean excludeRoomCreator, final UpdateAnchorsCallback callback){ protected void updateAnchors(final boolean excludeRoomCreator, final UpdateAnchorsCallback callback) {
mHttpRequest.getPushers(mCurrRoomID, new HttpRequests.OnResponseCallback<HttpResponse.PusherList>() { mHttpRequest.getPushers(mCurrRoomID, new HttpRequests.OnResponseCallback<HttpResponse.PusherList>() {
@Override @Override
public void onResponse(final int retcode, String retmsg, final HttpResponse.PusherList data) { public void onResponse(final int retcode, String retmsg, final HttpResponse.PusherList data) {
...@@ -2244,8 +2242,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2244,8 +2242,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
mPushers = mergedAnchors; mPushers = mergedAnchors;
} } else {
else {
TXCLog.e(TAG, "更新主播列表返回空数据"); TXCLog.e(TAG, "更新主播列表返回空数据");
if (callback != null) { if (callback != null) {
callback.onUpdateAnchors(-1, null, null, null, null); callback.onUpdateAnchors(-1, null, null, null, null);
...@@ -2253,7 +2250,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2253,7 +2250,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
protected void mergerAnchors(List<AnchorInfo> anchors, List<AnchorInfo> addAnchors, List<AnchorInfo> delAnchors, HashMap<String, AnchorInfo> mergedAnchors){ protected void mergerAnchors(List<AnchorInfo> anchors, List<AnchorInfo> addAnchors, List<AnchorInfo> delAnchors, HashMap<String, AnchorInfo> mergedAnchors) {
if (anchors == null) { if (anchors == null) {
//主播列表为空,意味着所有主播都已经退房 //主播列表为空,意味着所有主播都已经退房
if (delAnchors != null) { if (delAnchors != null) {
...@@ -2267,7 +2264,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2267,7 +2264,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
for (AnchorInfo member : anchors) { for (AnchorInfo member : anchors) {
if (member.userID != null && (!member.userID.equals(mSelfAccountInfo.userID))){ if (member.userID != null && (!member.userID.equals(mSelfAccountInfo.userID))) {
if (!mPushers.containsKey(member.userID)) { if (!mPushers.containsKey(member.userID)) {
if (addAnchors != null) { if (addAnchors != null) {
addAnchors.add(member); addAnchors.add(member);
...@@ -2315,7 +2312,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2315,7 +2312,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
protected String getRoomCreator(String roomID) { protected String getRoomCreator(String roomID) {
for (RoomInfo item: mRoomList) { for (RoomInfo item : mRoomList) {
if (roomID.equalsIgnoreCase(item.roomID)) { if (roomID.equalsIgnoreCase(item.roomID)) {
return item.roomCreator; return item.roomCreator;
} }
...@@ -2332,9 +2329,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2332,9 +2329,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
config.setFrontCamera(frontCamera); config.setFrontCamera(frontCamera);
config.enableScreenCaptureAutoRotate(mScreenAutoEnable);// 是否开启屏幕自适应 config.enableScreenCaptureAutoRotate(mScreenAutoEnable);// 是否开启屏幕自适应
config.setTouchFocus(false);// 手动对焦 config.setTouchFocus(false);// 手动对焦
// config.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT); //横屏推流 config.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT); //横屏推流
config.setPauseFlag(TXLiveConstants.PAUSE_FLAG_PAUSE_VIDEO | TXLiveConstants.PAUSE_FLAG_PAUSE_AUDIO); config.setPauseFlag(TXLiveConstants.PAUSE_FLAG_PAUSE_VIDEO | TXLiveConstants.PAUSE_FLAG_PAUSE_AUDIO);
mTXLivePusher.setConfig(config); mTXLivePusher.setConfig(config);
// mTXLivePusher.setMirror(true);
mTXLivePusher.setBeautyFilter(TXLiveConstants.BEAUTY_STYLE_SMOOTH, 5, 3, 2); mTXLivePusher.setBeautyFilter(TXLiveConstants.BEAUTY_STYLE_SMOOTH, 5, 3, 2);
mTXLivePushListener = new TXLivePushListenerImpl(); mTXLivePushListener = new TXLivePushListenerImpl();
mTXLivePusher.setPushListener(mTXLivePushListener); mTXLivePusher.setPushListener(mTXLivePushListener);
...@@ -2451,8 +2449,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2451,8 +2449,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
return; return;
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -2500,8 +2497,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2500,8 +2497,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
}); });
return; return;
} } else if (result.equalsIgnoreCase("reject")) {
else if (result.equalsIgnoreCase("reject")) {
callbackOnThread(new Runnable() { callbackOnThread(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -2525,8 +2521,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2525,8 +2521,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
}); });
return; return;
} }
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -2561,6 +2556,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2561,6 +2556,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// IMMessageMgr.IMMessageListener // IMMessageMgr.IMMessageListener
// //
////////////////////////////////////////// //////////////////////////////////////////
/** /**
* IM连接成功 * IM连接成功
*/ */
...@@ -2617,7 +2613,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2617,7 +2613,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
*/ */
@Override @Override
public void onGroupCustomMessage(final String groupID, final String senderID, String message) { public void onGroupCustomMessage(final String groupID, final String senderID, String message) {
final CustomMessage customMessage = new Gson().fromJson(message, CustomMessage.class); final CustomMessage customMessage = new Gson().fromJson(message, CustomMessage.class);
callbackOnThread(mListener, "onRecvRoomCustomMsg", groupID, senderID, customMessage.userName, customMessage.userAvatar, customMessage.cmd, customMessage.msg); callbackOnThread(mListener, "onRecvRoomCustomMsg", groupID, senderID, customMessage.userName, customMessage.userAvatar, customMessage.cmd, customMessage.msg);
} }
...@@ -2632,8 +2628,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2632,8 +2628,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
public void onC2CCustomMessage(String sendID, String cmd, String message) { public void onC2CCustomMessage(String sendID, String cmd, String message) {
if (cmd.equalsIgnoreCase("linkmic")) { if (cmd.equalsIgnoreCase("linkmic")) {
onRecvLinkMicMessage(message); onRecvLinkMicMessage(message);
} } else if (cmd.equalsIgnoreCase("pk")) {
else if (cmd.equalsIgnoreCase("pk")) {
onRecvPKMessage(message); onRecvPKMessage(message);
} }
} }
...@@ -2711,17 +2706,17 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2711,17 +2706,17 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
private class StreamMixturer { private class StreamMixturer {
private String mMainStreamId = ""; private String mMainStreamId = "";
private String mPKStreamId = ""; private String mPKStreamId = "";
private Vector<String> mSubStreamIds = new Vector<String>(); private Vector<String> mSubStreamIds = new Vector<String>();
private int mMainStreamWidth = 540; private int mMainStreamWidth = 960;
private int mMainStreamHeight = 960; private int mMainStreamHeight = 540;
public StreamMixturer() { public StreamMixturer() {
} }
public void setMainVideoStream(String streamUrl) { public void setMainVideoStream(String streamUrl) {
mMainStreamId = getStreamIDByStreamUrl(streamUrl); mMainStreamId = getStreamIDByStreamUrl(streamUrl);
Log.e(TAG, "MergeVideoStream: setMainVideoStream " + mMainStreamId); Log.e(TAG, "MergeVideoStream: setMainVideoStream " + mMainStreamId);
...@@ -2734,7 +2729,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2734,7 +2729,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
public void addSubVideoStream(String streamUrl) { public void addSubVideoStream(String streamUrl) {
if (mSubStreamIds.size() > 3) { if (mSubStreamIds.size() > 3) {
return; return;
} }
...@@ -2747,7 +2742,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2747,7 +2742,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
return; return;
} }
for (String item: mSubStreamIds) { for (String item : mSubStreamIds) {
if (item.equalsIgnoreCase(streamId)) { if (item.equalsIgnoreCase(streamId)) {
return; return;
} }
...@@ -2757,13 +2752,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2757,13 +2752,13 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
sendStreamMergeRequest(5); sendStreamMergeRequest(5);
} }
public void delSubVideoStream(String streamUrl) { public void delSubVideoStream(String streamUrl) {
String streamId = getStreamIDByStreamUrl(streamUrl); String streamId = getStreamIDByStreamUrl(streamUrl);
Log.e(TAG, "MergeVideoStream: delSubVideoStream " + streamId); Log.e(TAG, "MergeVideoStream: delSubVideoStream " + streamId);
boolean bExist = false; boolean bExist = false;
for (String item: mSubStreamIds) { for (String item : mSubStreamIds) {
if (item.equalsIgnoreCase(streamId)) { if (item.equalsIgnoreCase(streamId)) {
bExist = true; bExist = true;
break; break;
...@@ -2814,9 +2809,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2814,9 +2809,9 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
mSubStreamIds.clear(); mSubStreamIds.clear();
mMainStreamId = null; mMainStreamId = null;
mPKStreamId = null; mPKStreamId = null;
mMainStreamWidth = 540; mMainStreamWidth = 960;
mMainStreamHeight = 960; mMainStreamHeight = 540;
} }
private void sendStreamMergeRequest(final int retryCount) { private void sendStreamMergeRequest(final int retryCount) {
...@@ -2839,8 +2834,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2839,8 +2834,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
if (runImmediately == false) { if (runImmediately == false) {
try { try {
sleep(2000, 0); sleep(2000, 0);
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -2859,8 +2853,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2859,8 +2853,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
if (result != null && result.code == 0 && result.merge_code == 0) { if (result != null && result.code == 0 && result.merge_code == 0) {
return; return;
} } else {
else {
int tempRetryIndex = retryIndex - 1; int tempRetryIndex = retryIndex - 1;
if (tempRetryIndex > 0) { if (tempRetryIndex > 0) {
internalSendRequest(tempRetryIndex, false, requestParam); internalSendRequest(tempRetryIndex, false, requestParam);
...@@ -2881,82 +2874,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2881,82 +2874,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// input_stream_list // input_stream_list
JSONArray inputStreamList = new JSONArray(); JSONArray inputStreamList = new JSONArray();
// 大主播 // // 大主播
{
JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", 1);
JSONObject mainStream = new JSONObject();
mainStream.put("input_stream_id", mMainStreamId);
mainStream.put("layout_params", layoutParam);
inputStreamList.put(mainStream);
}
// int subWidth = 160;
// int subHeight = 240;
int offsetHeight = 90;
int subWidth = 288;
int subHeight = 432;
// int offsetHeight = 162;
if (mMainStreamWidth < 540 || mMainStreamHeight < 960) {
// subWidth = 120;
// subHeight = 180;
offsetHeight = 60;
subWidth = 216;
subHeight = 324;
// offsetHeight = 108;
}
int subLocationX = mMainStreamWidth - subWidth;
int subLocationY = mMainStreamHeight - subHeight - offsetHeight;
// 小主播
int layerIndex = 0;
for (String item : mSubStreamIds) {
JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", layerIndex + 2);
layoutParam.put("image_width", subWidth);
layoutParam.put("image_height", subHeight);
layoutParam.put("location_x", subLocationX);
layoutParam.put("location_y", subLocationY - layerIndex * subHeight);
JSONObject subStream = new JSONObject();
subStream.put("input_stream_id", item);
subStream.put("layout_params", layoutParam);
inputStreamList.put(subStream);
++layerIndex;
}
// // 画布
// { // {
// JSONObject layoutParam = new JSONObject(); // JSONObject layoutParam = new JSONObject();
// layoutParam.put("image_layer", 1); // layoutParam.put("image_layer", 1);
// layoutParam.put("input_type", 3);
// layoutParam.put("image_width", 540);
// layoutParam.put("image_height", 960);
//
// JSONObject canvasStream = new JSONObject();
// canvasStream.put("input_stream_id", mMainStreamId);
// canvasStream.put("layout_params", layoutParam);
//
// inputStreamList.put(canvasStream);
// }
//
// // mainStream
// {
// JSONObject layoutParam = new JSONObject();
// layoutParam.put("image_layer", 2);
// if (mSubStreamIds.size()>0){
// layoutParam.put("image_width", 540);
// layoutParam.put("image_height", 480);
// }else {
// layoutParam.put("image_width", 540);
// layoutParam.put("image_height", 960);
// }
// layoutParam.put("location_x", 0);
// layoutParam.put("location_y", 0);
// //
// JSONObject mainStream = new JSONObject(); // JSONObject mainStream = new JSONObject();
// mainStream.put("input_stream_id", mMainStreamId); // mainStream.put("input_stream_id", mMainStreamId);
...@@ -2965,21 +2886,96 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2965,21 +2886,96 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// inputStreamList.put(mainStream); // inputStreamList.put(mainStream);
// } // }
// //
//// int subWidth = 160;
//// int subHeight = 240;
// int offsetHeight = 90;
// int subWidth = 288;
// int subHeight = 432;
//// int offsetHeight = 162;
// if (mMainStreamWidth < 540 || mMainStreamHeight < 960) {
//// subWidth = 120;
//// subHeight = 180;
// offsetHeight = 60;
// subWidth = 216;
// subHeight = 324;
//// offsetHeight = 108;
// }
// int subLocationX = mMainStreamWidth - subWidth;
// int subLocationY = mMainStreamHeight - subHeight - offsetHeight;
//
// // 小主播
// int layerIndex = 0;
// for (String item : mSubStreamIds) { // for (String item : mSubStreamIds) {
// JSONObject layoutParam = new JSONObject(); // JSONObject layoutParam = new JSONObject();
// layoutParam.put("image_layer", 3); // layoutParam.put("image_layer", layerIndex + 2);
// layoutParam.put("image_width", 540); // layoutParam.put("image_width", subWidth);
// layoutParam.put("image_height", 480); // layoutParam.put("image_height", subHeight);
// layoutParam.put("location_x", 0); // layoutParam.put("location_x", subLocationX);
// layoutParam.put("location_y", 480); // layoutParam.put("location_y", subLocationY - layerIndex * subHeight);
// //
// JSONObject mainStream = new JSONObject(); // JSONObject subStream = new JSONObject();
// mainStream.put("input_stream_id", item); // subStream.put("input_stream_id", item);
// mainStream.put("layout_params", layoutParam); // subStream.put("layout_params", layoutParam);
// //
// inputStreamList.put(mainStream); // inputStreamList.put(subStream);
// ++layerIndex;
// } // }
// 画布
{
JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", 1);
layoutParam.put("input_type", 3);
layoutParam.put("image_width", 960);
layoutParam.put("image_height", 540);
JSONObject canvasStream = new JSONObject();
canvasStream.put("input_stream_id", mMainStreamId);
canvasStream.put("layout_params", layoutParam);
inputStreamList.put(canvasStream);
}
// mainStream
{
JSONObject mainStream = new JSONObject();
JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", 2);
layoutParam.put("image_width", 960);
layoutParam.put("image_height", 540);
layoutParam.put("location_x", 0);
layoutParam.put("location_y", 0);
mainStream.put("input_stream_id", mMainStreamId);
mainStream.put("layout_params", layoutParam);
inputStreamList.put(mainStream);
}
for (String item : mSubStreamIds) {
JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", 3);
layoutParam.put("image_width", 480);
layoutParam.put("image_height", 540);
layoutParam.put("location_x", 480);
layoutParam.put("location_y", 0);
JSONObject cropParam = new JSONObject();
cropParam.put("crop_width", 280);
cropParam.put("crop_height", 320);
cropParam.put("crop_x", 0);
cropParam.put("crop_y", 0);
JSONObject mainStream = new JSONObject();
mainStream.put("input_stream_id", item);
mainStream.put("layout_params", layoutParam);
mainStream.put("crop_params", cropParam);
inputStreamList.put(mainStream);
}
// para // para
JSONObject para = new JSONObject(); JSONObject para = new JSONObject();
para.put("app_id", ""); para.put("app_id", "");
...@@ -2998,8 +2994,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -2998,8 +2994,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
requestParam.put("timestamp", System.currentTimeMillis() / 1000); requestParam.put("timestamp", System.currentTimeMillis() / 1000);
requestParam.put("eventId", System.currentTimeMillis() / 1000); requestParam.put("eventId", System.currentTimeMillis() / 1000);
requestParam.put("interface", interfaceObj); requestParam.put("interface", interfaceObj);
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -3018,7 +3013,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3018,7 +3013,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
// input_stream_list // input_stream_list
JSONArray inputStreamList = new JSONArray(); JSONArray inputStreamList = new JSONArray();
if (mPKStreamId != null && mPKStreamId.length() > 0){ if (mPKStreamId != null && mPKStreamId.length() > 0) {
// 画布 // 画布
{ {
JSONObject layoutParam = new JSONObject(); JSONObject layoutParam = new JSONObject();
...@@ -3065,8 +3060,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3065,8 +3060,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
inputStreamList.put(mainStream); inputStreamList.put(mainStream);
} }
} } else {
else {
JSONObject layoutParam = new JSONObject(); JSONObject layoutParam = new JSONObject();
layoutParam.put("image_layer", 1); layoutParam.put("image_layer", 1);
...@@ -3095,8 +3089,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3095,8 +3089,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
requestParam.put("timestamp", System.currentTimeMillis() / 1000); requestParam.put("timestamp", System.currentTimeMillis() / 1000);
requestParam.put("eventId", System.currentTimeMillis() / 1000); requestParam.put("eventId", System.currentTimeMillis() / 1000);
requestParam.put("interface", interfaceObj); requestParam.put("interface", interfaceObj);
} } catch (Exception e) {
catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -3176,11 +3169,11 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3176,11 +3169,11 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
}; };
public void startHeartbeat(){ public void startHeartbeat() {
synchronized (this) { synchronized (this) {
if (handler != null && handler.getLooper() != null) { if (handler != null && handler.getLooper() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
handler.getLooper().quitSafely(); handler.getLooper().quitSafely();
} else { } else {
handler.getLooper().quit(); handler.getLooper().quit();
} }
...@@ -3192,7 +3185,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3192,7 +3185,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
} }
} }
public void stopHeartbeat(){ public void stopHeartbeat() {
synchronized (this) { synchronized (this) {
if (handler != null) { if (handler != null) {
handler.removeCallbacks(heartBeatRunnable); handler.removeCallbacks(heartBeatRunnable);
...@@ -3229,11 +3222,11 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3229,11 +3222,11 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
callbackOnThread(mCallback, "onError", event, msg); callbackOnThread(mCallback, "onError", event, msg);
} else if (event == TXLiveConstants.PUSH_ERR_NET_DISCONNECT || event == TXLiveConstants.PUSH_ERR_INVALID_ADDRESS) { } else if (event == TXLiveConstants.PUSH_ERR_NET_DISCONNECT || event == TXLiveConstants.PUSH_ERR_INVALID_ADDRESS) {
String msg = "[LivePusher] 推流失败[网络断开]"; String msg = "[LivePusher] 推流失败[网络断开]";
TXCLog.e(TAG,msg); TXCLog.e(TAG, msg);
callbackOnThread(mCallback, "onError", event, msg); callbackOnThread(mCallback, "onError", event, msg);
} else if (event == TXLiveConstants.PUSH_ERR_SCREEN_CAPTURE_START_FAILED) { } else if (event == TXLiveConstants.PUSH_ERR_SCREEN_CAPTURE_START_FAILED) {
String msg = "[LivePusher] 推流失败[录屏启动失败]"; String msg = "[LivePusher] 推流失败[录屏启动失败]";
TXCLog.e(TAG,msg); TXCLog.e(TAG, msg);
callbackOnThread(mCallback, "onError", event, msg); callbackOnThread(mCallback, "onError", event, msg);
} }
} }
...@@ -3284,10 +3277,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3284,10 +3277,10 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
}); });
} }
private class PlayerItem { private class PlayerItem {
public TXCloudVideoView view; public TXCloudVideoView view;
public AnchorInfo anchorInfo; public AnchorInfo anchorInfo;
public TXLivePlayer player; public TXLivePlayer player;
public PlayerItem(TXCloudVideoView view, AnchorInfo anchorInfo, TXLivePlayer player) { public PlayerItem(TXCloudVideoView view, AnchorInfo anchorInfo, TXLivePlayer player) {
this.view = view; this.view = view;
...@@ -3295,15 +3288,15 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3295,15 +3288,15 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
this.player = player; this.player = player;
} }
public void resume(){ public void resume() {
this.player.resume(); this.player.resume();
} }
public void pause(){ public void pause() {
this.player.pause(); this.player.pause();
} }
public void destroy(){ public void destroy() {
this.player.stopPlay(true); this.player.stopPlay(true);
this.view.onDestroy(); this.view.onDestroy();
} }
...@@ -3311,7 +3304,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3311,7 +3304,8 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
protected class CommonJson<T> { protected class CommonJson<T> {
public String cmd; public String cmd;
public T data; public T data;
public CommonJson() { public CommonJson() {
} }
} }
...@@ -3360,7 +3354,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart ...@@ -3360,7 +3354,7 @@ public class MLVBLiveRoomImpl extends MLVBLiveRoom implements HttpRequests.Heart
public long timestamp; public long timestamp;
} }
protected class CustomMessage{ protected class CustomMessage {
public String userName; public String userName;
public String userAvatar; public String userAvatar;
public String cmd; public String cmd;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -13,13 +13,13 @@ import android.support.v7.widget.RecyclerView; ...@@ -13,13 +13,13 @@ import android.support.v7.widget.RecyclerView;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.dayu.livemodule.IMLVBLiveRoomListener;
import com.dayu.livemodule.R; import com.dayu.livemodule.R;
import com.dayu.livemodule.roomutil.commondef.AnchorInfo; import com.dayu.livemodule.roomutil.commondef.AnchorInfo;
import com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl; import com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl;
...@@ -47,9 +47,9 @@ import java.util.Locale; ...@@ -47,9 +47,9 @@ import java.util.Locale;
* Function: 主播推流的页面 * Function: 主播推流的页面
* <p> * <p>
* <p> * <p>
* 1. MLVB 其他观众发起连麦请求处理:{@link TCCameraAnchorActivity#onRequestJoinAnchor(AnchorInfo, String)} * 1. MLVB 其他观众发起连麦请求处理:{@link TCCameraAnchorActivity2#onRequestJoinAnchor(AnchorInfo, String)}
* <p> * <p>
* 2. MLVB 其他主播连麦,结束连麦处理:{@link TCCameraAnchorActivity#onAnchorEnter(AnchorInfo)} {@link TCCameraAnchorActivity#onAnchorExit(AnchorInfo)} * 2. MLVB 其他主播连麦,结束连麦处理:{@link TCCameraAnchorActivity2#onAnchorEnter(AnchorInfo)} {@link TCCameraAnchorActivity2#onAnchorExit(AnchorInfo)}
* <p> * <p>
* 3. 音效控制面板类 {@link TCAudioControl} * 3. 音效控制面板类 {@link TCAudioControl}
* <p> * <p>
...@@ -71,6 +71,8 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity { ...@@ -71,6 +71,8 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity {
private TextView mBroadcastTime; // 已经开播的时间 private TextView mBroadcastTime; // 已经开播的时间
private TextView mMemberCount; // 观众数量 private TextView mMemberCount; // 观众数量
View halfView;
private TCAudioControl mAudioCtrl; // 音效控制面板 private TCAudioControl mAudioCtrl; // 音效控制面板
private LinearLayout mAudioPluginLayout; private LinearLayout mAudioPluginLayout;
...@@ -103,7 +105,9 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity { ...@@ -103,7 +105,9 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity {
@Override @Override
protected void initView() { protected void initView() {
setContentView(R.layout.activity_camera_anchor); setContentView(R.layout.activity_camera_anchor);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.initView(); super.initView();
halfView = findViewById(R.id.half_view);
mTXCloudVideoView = (TXCloudVideoView) findViewById(R.id.anchor_video_view); mTXCloudVideoView = (TXCloudVideoView) findViewById(R.id.anchor_video_view);
mTXCloudVideoView.setLogMargin(10, 10, 45, 55); mTXCloudVideoView.setLogMargin(10, 10, 45, 55);
...@@ -156,7 +160,7 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity { ...@@ -156,7 +160,7 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity {
} }
mLiveRoom.startLocalPreview(true, videoView.videoView); mLiveRoom.startLocalPreview(true, videoView.videoView);
mLiveRoom.startRemoteView(item, mTXCloudVideoView, new IMLVBLiveRoomListener.PlayCallback() { mLiveRoom.startRemoteView(item, mTXCloudVideoView, new PlayCallback() {
@Override @Override
public void onBegin() { public void onBegin() {
} }
...@@ -321,7 +325,7 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity { ...@@ -321,7 +325,7 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity {
} }
videoView.startLoading(); videoView.startLoading();
mLiveRoom.startRemoteView(pusherInfo, videoView.videoView, new IMLVBLiveRoomListener.PlayCallback() { mLiveRoom.startRemoteView(pusherInfo, videoView.videoView, new PlayCallback() {
@Override @Override
public void onBegin() { public void onBegin() {
videoView.stopLoading(true); //推流成功,stopLoading 大主播显示出踢人的button videoView.stopLoading(true); //推流成功,stopLoading 大主播显示出踢人的button
...@@ -496,6 +500,15 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity { ...@@ -496,6 +500,15 @@ public class TCCameraAnchorActivity extends TCBaseAnchorActivity {
*/ */
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (null != mAudioCtrl && mAudioCtrl.getVisibility() == View.VISIBLE) {
mAudioCtrl.setVisibility( View.GONE);
return;
}
if (mBeautyControl.isShown() || mBeautyControl.getVisibility() == View.VISIBLE) {
mBeautyControl.setVisibility( View.GONE);
return;
}
int i = v.getId(); int i = v.getId();
if (i == R.id.switch_cam) { if (i == R.id.switch_cam) {
if (mLiveRoom != null) { if (mLiveRoom != null) {
......
package com.dayu.livemodule.xiaozhibo.anchor;
import android.animation.ObjectAnimator;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.dayu.livemodule.R;
import com.dayu.livemodule.roomutil.commondef.AnchorInfo;
import com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl;
import com.dayu.livemodule.xiaozhibo.common.msg.TCSimpleUserInfo;
import com.dayu.livemodule.xiaozhibo.common.report.TCELKReportMgr;
import com.dayu.livemodule.xiaozhibo.common.utils.TCConstants;
import com.dayu.livemodule.xiaozhibo.common.utils.TCUtils;
import com.dayu.livemodule.xiaozhibo.common.widget.TCUserAvatarListAdapter;
import com.dayu.livemodule.xiaozhibo.common.widget.beauty.LiveRoomBeautyKit;
import com.dayu.livemodule.xiaozhibo.common.widget.video.TCVideoView;
import com.dayu.livemodule.xiaozhibo.common.widget.video.TCVideoViewMgr;
import com.dayu.livemodule.xiaozhibo.login.TCUserMgr;
import com.tencent.liteav.demo.beauty.BeautyPanel;
import com.tencent.liteav.demo.beauty.BeautyParams;
import com.tencent.rtmp.ui.TXCloudVideoView;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/**
* Module: TCBaseAnchorActivity
* <p>
* Function: 主播推流的页面
* <p>
* <p>
* 1. MLVB 其他观众发起连麦请求处理:{@link TCCameraAnchorActivity2#onRequestJoinAnchor(AnchorInfo, String)}
* <p>
* 2. MLVB 其他主播连麦,结束连麦处理:{@link TCCameraAnchorActivity2#onAnchorEnter(AnchorInfo)} {@link TCCameraAnchorActivity2#onAnchorExit(AnchorInfo)}
* <p>
* 3. 音效控制面板类 {@link TCAudioControl}
* <p>
* 4. 美颜特效控制类 {@link BeautyPanel}
*/
public class TCCameraAnchorActivity2 extends TCBaseAnchorActivity {
private static final String TAG = TCCameraAnchorActivity2.class.getSimpleName();
private TXCloudVideoView mTXCloudVideoView; // 主播本地预览的 View
private Button mFlashView; // 闪光灯按钮
// 观众头像列表控件
private RecyclerView mUserAvatarList; // 用户头像的列表控件
private TCUserAvatarListAdapter mAvatarListAdapter; // 头像列表的 Adapter
// 主播信息
private ImageView mHeadIcon; // 主播头像
private ImageView mRecordBall; // 表明正在录制的红点球
private TextView mBroadcastTime; // 已经开播的时间
private TextView mMemberCount; // 观众数量
View halfView;
private TCAudioControl mAudioCtrl; // 音效控制面板
private LinearLayout mAudioPluginLayout;
private BeautyPanel mBeautyControl; // 美颜设置的控制类
// log相关
private boolean mShowLog; // 是否打开 log 面板
private boolean mFlashOn; // 是否打开闪光灯
// 连麦主播
private boolean mPendingRequest; // 主播是否正在处理请求
private TCVideoViewMgr mPlayerVideoViewList; // 主播视频列表的View
private List<AnchorInfo> mPusherList; // 当前在麦上的主播
private ObjectAnimator mObjAnim; // 动画
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.BeautyTheme);
super.onCreate(savedInstanceState);
TCELKReportMgr.getInstance().reportELK(TCConstants.ELK_ACTION_CAMERA_PUSH, TCUserMgr.getInstance().getUserId(), 0, "摄像头推流", null);
mPusherList = new ArrayList<>();
LiveRoomBeautyKit manager = new LiveRoomBeautyKit(mLiveRoom);
mBeautyControl.setProxy(manager);
}
@Override
protected void initView() {
setContentView(R.layout.activity_camera_anchor);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.initView();
halfView = findViewById(R.id.half_view);
mTXCloudVideoView = (TXCloudVideoView) findViewById(R.id.anchor_video_view);
mTXCloudVideoView.setLogMargin(10, 10, 45, 55);
mUserAvatarList = (RecyclerView) findViewById(R.id.anchor_rv_avatar);
mAvatarListAdapter = new TCUserAvatarListAdapter(this, TCUserMgr.getInstance().getUserId());
mUserAvatarList.setAdapter(mAvatarListAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mUserAvatarList.setLayoutManager(linearLayoutManager);
mFlashView = (Button) findViewById(R.id.anchor_btn_flash);
mBroadcastTime = (TextView) findViewById(R.id.anchor_tv_broadcasting_time);
mBroadcastTime.setText(String.format(Locale.US, "%s", "00:00:00"));
mRecordBall = (ImageView) findViewById(R.id.anchor_iv_record_ball);
mHeadIcon = (ImageView) findViewById(R.id.anchor_iv_head_icon);
showHeadIcon(mHeadIcon, TCUserMgr.getInstance().getAvatar());
mMemberCount = (TextView) findViewById(R.id.anchor_tv_member_counts);
mMemberCount.setText("0");
//AudioControl
mAudioCtrl = (TCAudioControl) findViewById(R.id.anchor_audio_control);
mAudioPluginLayout = (LinearLayout) findViewById(R.id.anchor_ll_audio_plugin);
mBeautyControl = (BeautyPanel) findViewById(R.id.beauty_panel);
// 监听踢出的回调
mPlayerVideoViewList = new TCVideoViewMgr(this, new TCVideoView.OnRoomViewListener() {
@Override
public void onKickUser(String userID) {
if (userID != null) {
for (AnchorInfo item : mPusherList) {
if (userID.equalsIgnoreCase(item.userID)) {
onAnchorExit(item);
// changePushView(item);
break;
}
}
mLiveRoom.kickoutJoinAnchor(userID);
}
}
});
}
private void changePushView(AnchorInfo item) {
final TCVideoView videoView = mPlayerVideoViewList.applyVideoView(item.userID);
if (videoView == null) {
return;
}
mLiveRoom.startLocalPreview(true, videoView.videoView);
mLiveRoom.startRemoteView(item, mTXCloudVideoView, new PlayCallback() {
@Override
public void onBegin() {
}
@Override
public void onError(int errCode, String errInfo) {
}
@Override
public void onEvent(int event, Bundle param) {
}
}); //开启远端视频渲染
}
/**
* 加载主播头像
*
* @param view view
* @param avatar 头像链接
*/
private void showHeadIcon(ImageView view, String avatar) {
TCUtils.showPicWithUrl(this, view, avatar, R.drawable.face);
}
@Override
protected void onDestroy() {
super.onDestroy();
stopRecordAnimation();
mPlayerVideoViewList.recycleVideoView();
mPlayerVideoViewList = null;
if (mMainHandler != null) {
mMainHandler.removeCallbacksAndMessages(null);
}
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 开始和停止推流相关
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
protected void startPublish() {
mAudioCtrl.setPusher(mLiveRoom);
mTXCloudVideoView.setVisibility(View.VISIBLE);
// 打开本地预览,传入预览的 View
mLiveRoom.startLocalPreview(true, mTXCloudVideoView);
// 设置美颜参数
BeautyParams beautyParams = new BeautyParams();
mLiveRoom.getBeautyManager().setBeautyStyle(beautyParams.mBeautyStyle);
mLiveRoom.getBeautyManager().setBeautyLevel(beautyParams.mBeautyLevel);
mLiveRoom.getBeautyManager().setWhitenessLevel(beautyParams.mWhiteLevel);
mLiveRoom.getBeautyManager().setRuddyLevel(beautyParams.mRuddyLevel);
// 设置瘦脸参数
mLiveRoom.getBeautyManager().setFaceSlimLevel(beautyParams.mFaceSlimLevel);
// 设置大眼参数
mLiveRoom.getBeautyManager().setEyeScaleLevel(beautyParams.mBigEyeLevel);
if (TCUtils.checkRecordPermission(this)) {
super.startPublish();
}
}
@Override
protected void stopPublish() {
//踢出连麦人
// if (mPusherList != null && mPusherList.size() > 0) {
// for (AnchorInfo user : mPusherList){
// mLiveRoom.kickoutJoinAnchor(user.userID);
// onAnchorExit(user);
// }
// }
super.stopPublish();
if (mAudioCtrl != null) {
mAudioCtrl.unInit();
mAudioCtrl.setPusher(null);
mAudioCtrl = null;
}
}
/**
* 取消连麦弹框
*
*/
public void showExitAnchorDialog(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.ConfirmDialogStyle);
builder.setCancelable(true);
builder.setTitle(msg);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
stopAnchor();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
alertDialog.setCanceledOnTouchOutside(false);
}
private void stopAnchor() {
//踢出连麦人
if (mPusherList != null && mPusherList.size() > 0) {
for (AnchorInfo user : mPusherList){
mLiveRoom.kickoutJoinAnchor(user.userID);
onAnchorExit(user);
}
}
}
@Override
protected void onCreateRoomSuccess() {
super.onCreateRoomSuccess();
startRecordAnimation();
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // MLVB 组件回调
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
public void onAnchorEnter(final AnchorInfo pusherInfo) {
if (pusherInfo == null || pusherInfo.userID == null) {
return;
}
final TCVideoView videoView = mPlayerVideoViewList.applyVideoView(pusherInfo.userID);
if (videoView == null) {
return;
}
if (mPusherList != null) {
boolean exist = false;
for (AnchorInfo item : mPusherList) {
if (pusherInfo.userID.equalsIgnoreCase(item.userID)) {
exist = true;
break;
}
}
if (exist == false) {
mPusherList.add(pusherInfo);
}
}
videoView.startLoading();
mLiveRoom.startRemoteView(pusherInfo, videoView.videoView, new PlayCallback() {
@Override
public void onBegin() {
videoView.stopLoading(true); //推流成功,stopLoading 大主播显示出踢人的button
}
@Override
public void onError(int errCode, String errInfo) {
videoView.stopLoading(false);
onDoAnchorExit(pusherInfo);
}
@Override
public void onEvent(int event, Bundle param) {
}
}); //开启远端视频渲染
}
@Override
public void onAnchorExit(AnchorInfo pusherInfo) {
onDoAnchorExit(pusherInfo);
}
private void onDoAnchorExit(AnchorInfo pusherInfo) {
if (mPusherList != null) {
Iterator<AnchorInfo> it = mPusherList.iterator();
while (it.hasNext()) {
AnchorInfo item = it.next();
if (pusherInfo.userID.equalsIgnoreCase(item.userID)) {
it.remove();
break;
}
}
}
mLiveRoom.stopRemoteView(pusherInfo);//关闭远端视频渲染
mPlayerVideoViewList.recycleVideoView(pusherInfo.userID);
}
@Override
public void onRequestJoinAnchor(final AnchorInfo pusherInfo, String reason) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setCancelable(true)
.setTitle("提示")
.setMessage(pusherInfo.userName + "向您发起连麦请求")
.setPositiveButton("接受", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mLiveRoom.responseJoinAnchor(pusherInfo.userID, true, "");
dialog.dismiss();
mPendingRequest = false;
}
})
.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mLiveRoom.responseJoinAnchor(pusherInfo.userID, false, "主播拒绝了您的连麦请求");
dialog.dismiss();
mPendingRequest = false;
}
});
mMainHandler.post(new Runnable() {
@Override
public void run() {
if (mPendingRequest == true) {
mLiveRoom.responseJoinAnchor(pusherInfo.userID, false, "请稍后,主播正在处理其它人的连麦请求");
return;
}
if (mPusherList.size() >= 1) {
mLiveRoom.responseJoinAnchor(pusherInfo.userID, false, "主播端连麦人数超过最大限制");
return;
}
final AlertDialog alertDialog = builder.create();
alertDialog.setCancelable(false);
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.show();
mPendingRequest = true;
mMainHandler.postDelayed(new Runnable() {
@Override
public void run() {
alertDialog.dismiss();
mPendingRequest = false;
}
}, 10000);
}
});
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 音乐控制面板相关
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (null != mAudioCtrl && mAudioCtrl.getVisibility() != View.GONE && ev.getRawY() < mAudioCtrl.getTop()) {
mAudioCtrl.setVisibility(View.GONE);
}
if (null != mBeautyControl && mBeautyControl.getVisibility() != View.GONE && ev.getRawY() < mBeautyControl.getTop()) {
mBeautyControl.setVisibility(View.GONE);
}
return super.dispatchTouchEvent(ev);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/** attention to this below ,must add this**/
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {//是否选择,没选择就不会继续
if (requestCode == mAudioCtrl.REQUESTCODE) {
if (data == null) {
Log.e(TAG, "null data");
} else {
Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
if (mAudioCtrl != null) {
mAudioCtrl.processActivityResult(uri);
} else {
Log.e(TAG, "NULL Pointer! Get Music Failed");
}
}
}
}
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 界面动画与时长统计
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
/**
* 开启红点与计时动画
*/
private void startRecordAnimation() {
mObjAnim = ObjectAnimator.ofFloat(mRecordBall, "alpha", 1f, 0f, 1f);
mObjAnim.setDuration(1000);
mObjAnim.setRepeatCount(-1);
mObjAnim.start();
}
/**
* 关闭红点与计时动画
*/
private void stopRecordAnimation() {
if (null != mObjAnim)
mObjAnim.cancel();
}
@Override
protected void onBroadcasterTimeUpdate(long second) {
super.onBroadcasterTimeUpdate(second);
if (!mTCSwipeAnimationController.isMoving())
mBroadcastTime.setText(TCUtils.formattedTime(second));
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 点击事件与调用函数相关
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
public void onClick(View v) {
if (null != mAudioCtrl && mAudioCtrl.getVisibility() == View.VISIBLE) {
mAudioCtrl.setVisibility( View.GONE);
return;
}
if (mBeautyControl.isShown() || mBeautyControl.getVisibility() == View.VISIBLE) {
mBeautyControl.setVisibility( View.GONE);
return;
}
int i = v.getId();
if (i == R.id.switch_cam) {
if (mLiveRoom != null) {
mLiveRoom.switchCamera();
}
} else if (i == R.id.anchor_btn_flash) {
if (mLiveRoom == null || !mLiveRoom.enableTorch(!mFlashOn)) {
Toast.makeText(getApplicationContext(), "打开闪光灯失败", Toast.LENGTH_SHORT).show();
return;
}
mFlashOn = !mFlashOn;
mFlashView.setBackgroundDrawable(mFlashOn ?
getResources().getDrawable(R.drawable.flash_on) :
getResources().getDrawable(R.drawable.flash_off));
} else if (i == R.id.beauty_btn) {
if (mBeautyControl.isShown()) {
mBeautyControl.setVisibility(View.GONE);
} else {
mBeautyControl.setVisibility(View.VISIBLE);
}
} else if (i == R.id.btn_close) {
if (mPusherList != null && mPusherList.size() > 0) {
showExitAnchorDialog("当前正在连麦,是否结束连麦?");
}else {
showExitInfoDialog("当前正在直播,是否退出直播?", false);
}
} else if (i == R.id.btn_audio_ctrl) {
if (null != mAudioCtrl) {
mAudioCtrl.setVisibility(mAudioCtrl.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
}
} else if (i == R.id.btn_audio_effect) {
mAudioCtrl.setVisibility(mAudioCtrl.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
} else if (i == R.id.btn_audio_close) {
mAudioCtrl.stopBGM();
mAudioPluginLayout.setVisibility(View.GONE);
mAudioCtrl.setVisibility(View.GONE);
} else if (i == R.id.btn_log) {
showLog();
} else {
super.onClick(v);
}
}
@Override
protected void showErrorAndQuit(int errorCode, String errorMsg) {
stopRecordAnimation();
super.showErrorAndQuit(errorCode, errorMsg);
}
private void showLog() {
mShowLog = !mShowLog;
if (mTXCloudVideoView != null) {
mTXCloudVideoView.showLog(mShowLog);
}
ImageView liveLog = (ImageView) findViewById(R.id.btn_log);
if (mShowLog) {
if (liveLog != null) liveLog.setBackgroundResource(R.drawable.icon_log_on);
} else {
if (liveLog != null) liveLog.setBackgroundResource(R.drawable.icon_log_off);
}
mPlayerVideoViewList.showLog(mShowLog);
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 成员进退房事件信息处理
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
protected void handleMemberJoinMsg(TCSimpleUserInfo userInfo) {
//更新头像列表 返回false表明已存在相同用户,将不会更新数据
if (mAvatarListAdapter.addItem(userInfo))
super.handleMemberJoinMsg(userInfo);
mMemberCount.setText(String.format(Locale.CHINA, "%d", mCurrentMemberCount));
}
@Override
protected void handleMemberQuitMsg(TCSimpleUserInfo userInfo) {
mAvatarListAdapter.removeItem(userInfo.userid);
super.handleMemberQuitMsg(userInfo);
mMemberCount.setText(String.format(Locale.CHINA, "%d", mCurrentMemberCount));
}
/**
* /////////////////////////////////////////////////////////////////////////////////
* //
* // 权限相关
* //
* /////////////////////////////////////////////////////////////////////////////////
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 100:
for (int ret : grantResults) {
if (ret != PackageManager.PERMISSION_GRANTED) {
showErrorAndQuit(-1314, "获取权限失败");
return;
}
}
this.startPublish();
break;
default:
break;
}
}
}
...@@ -5,6 +5,13 @@ ...@@ -5,6 +5,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:ignore="contentDescription"> tools:ignore="contentDescription">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
</LinearLayout>
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/anchor_video_view" android:id="@+id/anchor_video_view"
...@@ -20,33 +27,33 @@ ...@@ -20,33 +27,33 @@
<!--连麦:播放小窗口定义 开始--> <!--连麦:播放小窗口定义 开始-->
<ScrollView <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_alignParentBottom="true" android:orientation="horizontal"
android:layout_marginBottom="56dp" >
android:layout_alignParentRight="true"> <View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content"> android:layout_weight="1"
android:layout_height="match_parent">
<!--连麦:第一个播放小窗口--> <!--连麦:第一个播放小窗口-->
<FrameLayout <FrameLayout
android:id="@+id/frameLayout1" android:id="@+id/frameLayout1"
android:layout_width="180dp" android:layout_width="match_parent"
android:layout_height="270dp" android:layout_height="match_parent"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_marginRight="8dp"
> >
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player1" android:id="@+id/video_player1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView> android:visibility="gone"/>
<FrameLayout <FrameLayout
android:id="@+id/loading_background1" android:id="@+id/loading_background1"
...@@ -69,14 +76,28 @@ ...@@ -69,14 +76,28 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:visibility="gone" /> android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="56dp"
android:layout_alignParentRight="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--连麦:第二个播放小窗口--> <!--连麦:第二个播放小窗口-->
<FrameLayout <FrameLayout
android:id="@+id/frameLayout2" android:id="@+id/frameLayout2"
android:layout_width="180dp" android:layout_width="180dp"
android:layout_height="270dp" android:layout_height="270dp"
android:layout_above="@+id/frameLayout1" >
android:layout_alignRight="@+id/frameLayout1"> <!--android:layout_above="@+id/frameLayout1"-->
<!--android:layout_alignRight="@+id/frameLayout1"-->
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player2" android:id="@+id/video_player2"
...@@ -378,7 +399,7 @@ ...@@ -378,7 +399,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginRight="15dp" android:layout_marginRight="125dp"
android:layout_marginBottom="10dp"> android:layout_marginBottom="10dp">
<com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout <com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/audience_play_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="contentDescription">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
</LinearLayout>
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/anchor_video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:visibility="gone" />
<ImageView
android:id="@+id/audience_background"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!--连麦:播放小窗口定义 开始-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<!--连麦:第一个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
>
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<FrameLayout
android:id="@+id/loading_background1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out1"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="56dp"
android:layout_alignParentRight="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--连麦:第二个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout2"
android:layout_width="180dp"
android:layout_height="270dp"
>
<!--android:layout_above="@+id/frameLayout1"-->
<!--android:layout_alignRight="@+id/frameLayout1"-->
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView>
<FrameLayout
android:id="@+id/loading_background2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out2"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
<!--连麦:第三个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout3"
android:layout_width="180dp"
android:layout_height="270dp"
android:layout_above="@+id/frameLayout2"
android:layout_alignRight="@+id/frameLayout2">
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView>
<FrameLayout
android:id="@+id/loading_background3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out3"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
</RelativeLayout>
</ScrollView>
<!--连麦:播放小窗口定义 结束-->
<RelativeLayout
android:id="@+id/anchor_rl_controllLayer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/layout_live_pusher_info"
layout="@layout/layout_live_pusher_info"
android:layout_width="110dp"
android:layout_height="35dp"
android:layout_margin="5dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/anchor_rv_avatar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="15dp"
android:layout_toRightOf="@+id/layout_live_pusher_info"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:id="@+id/btn_message_input"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_alignParentLeft="true"
android:background="@drawable/icon_message"
android:onClick="onClick" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/audience_btn_switch_cam"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/icon_switch_camera_on"
android:visibility="invisible" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/audience_btn_linkmic"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/linkmic_on"
android:visibility="invisible" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="gone">
<ImageView
android:id="@+id/btn_share"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/icon_share"
android:onClick="onClick" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="gone">
<ImageView
android:id="@+id/btn_log"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/icon_log_off"
android:onClick="onClick" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
android:id="@+id/btn_like"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/icon_like"
android:onClick="onClick" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_back"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_gravity="center"
android:background="@drawable/btn_close"
android:onClick="onClick" />
</FrameLayout>
</LinearLayout>
</RelativeLayout>
<ListView
android:id="@+id/im_msg_listview"
android:layout_width="250dp"
android:layout_height="10dp"
android:layout_above="@id/tool_bar"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:cacheColorHint="#00000000"
android:divider="#3c421b1b"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
android:stackFromBottom="true"
android:transcriptMode="normal"
android:visibility="gone" />
<!--录制-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:visibility="gone">
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/record_progress" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="11" />
<FrameLayout
android:layout_width="5dp"
android:layout_height="5dp"
android:background="#FF0ACBAB" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_weight="1" />
</LinearLayout>
<ImageView
android:id="@+id/close_record"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:background="@drawable/btn_close"
android:onClick="onClick" />
<ImageView
android:id="@+id/record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="30dp"
android:background="@drawable/start_record"
android:onClick="onClick" />
<ImageView
android:id="@+id/retry_record"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="50dp"
android:background="@drawable/again"
android:onClick="onClick" />
</RelativeLayout>
<!--点赞动画-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="125dp"
android:layout_marginBottom="10dp">
<com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout
android:id="@+id/heart_layout"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:focusable="true" />
</RelativeLayout>
<!--弹幕-->
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/anchor_danmaku_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_centerInParent="true" />
</RelativeLayout>
<com.tencent.liteav.demo.beauty.BeautyPanel
android:id="@+id/beauty_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone" />
</RelativeLayout>
\ No newline at end of file
...@@ -3,6 +3,18 @@ ...@@ -3,6 +3,18 @@
android:id="@+id/rl_root" android:id="@+id/rl_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="gone"
>
<View
android:id="@+id/half_view"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
</LinearLayout>
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/anchor_video_view" android:id="@+id/anchor_video_view"
...@@ -13,32 +25,33 @@ ...@@ -13,32 +25,33 @@
<!--连麦:播放小窗口定义 开始--> <!--连麦:播放小窗口定义 开始-->
<ScrollView <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_alignParentRight="true" android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_marginBottom="56dp"
> >
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content"> android:layout_weight="1"
android:background="#00000000"
android:layout_height="match_parent">
<!--连麦:第一个播放小窗口--> <!--连麦:第一个播放小窗口-->
<FrameLayout <FrameLayout
android:id="@+id/frameLayout1" android:id="@+id/frameLayout1"
android:layout_width="180dp" android:layout_width="match_parent"
android:layout_height="270dp" android:layout_height="match_parent"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="8dp"
> >
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player1" android:id="@+id/video_player1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView> android:visibility="gone"/>
<FrameLayout <FrameLayout
android:id="@+id/loading_background1" android:id="@+id/loading_background1"
...@@ -69,13 +82,29 @@ ...@@ -69,13 +82,29 @@
android:onClick="onClick" android:onClick="onClick"
android:visibility="invisible" /> android:visibility="invisible" />
</RelativeLayout>
</LinearLayout>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="56dp"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--连麦:第二个播放小窗口--> <!--连麦:第二个播放小窗口-->
<FrameLayout <FrameLayout
android:id="@+id/frameLayout2" android:id="@+id/frameLayout2"
android:layout_width="180dp" android:layout_width="180dp"
android:layout_height="270dp" android:layout_height="270dp"
android:layout_above="@+id/frameLayout1" >
android:layout_alignRight="@+id/frameLayout1"> <!--android:layout_above="@+id/frameLayout1"-->
<!--android:layout_alignRight="@+id/frameLayout1"-->
<com.tencent.rtmp.ui.TXCloudVideoView <com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player2" android:id="@+id/video_player2"
...@@ -155,6 +184,7 @@ ...@@ -155,6 +184,7 @@
android:onClick="onClick" android:onClick="onClick"
android:visibility="invisible" /> android:visibility="invisible" />
</RelativeLayout> </RelativeLayout>
</ScrollView> </ScrollView>
<!--连麦:播放小窗口定义 结束--> <!--连麦:播放小窗口定义 结束-->
...@@ -299,16 +329,23 @@ ...@@ -299,16 +329,23 @@
android:stackFromBottom="true" android:stackFromBottom="true"
android:transcriptMode="normal" /> android:transcriptMode="normal" />
<com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl <ScrollView
android:id="@+id/anchor_audio_control"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:overScrollMode="never"
android:background="#ffffff" android:layout_marginBottom="60dp"
android:clickable="true" android:background="#00000000"
android:orientation="vertical" >
android:padding="0dp" <com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl
android:visibility="gone" /> android:id="@+id/anchor_audio_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:clickable="true"
android:orientation="vertical"
android:padding="0dp"
android:visibility="gone" />
</ScrollView>
<com.tencent.liteav.demo.beauty.BeautyPanel <com.tencent.liteav.demo.beauty.BeautyPanel
android:id="@+id/beauty_panel" android:id="@+id/beauty_panel"
...@@ -391,6 +428,7 @@ ...@@ -391,6 +428,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"> android:layout_marginBottom="10dp">
<com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout <com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="gone"
>
<View
android:id="@+id/half_view"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
</LinearLayout>
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/anchor_video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:visibility="gone" />
<!--连麦:播放小窗口定义 开始-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
<!--连麦:第一个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
>
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<FrameLayout
android:id="@+id/loading_background1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out1"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignTop="@id/frameLayout1"
android:layout_alignRight="@id/frameLayout1"
android:layout_gravity="top|right"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/btn_kick_out"
android:onClick="onClick"
android:visibility="invisible" />
</RelativeLayout>
</LinearLayout>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="56dp"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--连麦:第二个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout2"
android:layout_width="180dp"
android:layout_height="270dp"
>
<!--android:layout_above="@+id/frameLayout1"-->
<!--android:layout_alignRight="@+id/frameLayout1"-->
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView>
<FrameLayout
android:id="@+id/loading_background2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out2"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignTop="@id/frameLayout2"
android:layout_alignRight="@id/frameLayout2"
android:layout_gravity="top|right"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/btn_kick_out"
android:onClick="onClick"
android:visibility="invisible" />
<!--连麦:第三个播放小窗口-->
<FrameLayout
android:id="@+id/frameLayout3"
android:layout_width="180dp"
android:layout_height="270dp"
android:layout_above="@+id/frameLayout2"
android:layout_alignRight="@+id/frameLayout2">
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video_player3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"></com.tencent.rtmp.ui.TXCloudVideoView>
<FrameLayout
android:id="@+id/loading_background3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@color/black"
android:visibility="gone">
<ImageView
android:id="@+id/loading_imageview3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center" />
</FrameLayout>
</FrameLayout>
<Button
android:id="@+id/btn_kick_out3"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignTop="@id/frameLayout3"
android:layout_alignRight="@id/frameLayout3"
android:layout_gravity="top|right"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/btn_kick_out"
android:onClick="onClick"
android:visibility="invisible" />
</RelativeLayout>
</ScrollView>
<!--连麦:播放小窗口定义 结束-->
<RelativeLayout
android:id="@+id/anchor_rl_controllLayer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/layout_live_pusher_info"
layout="@layout/layout_live_pusher_info"
android:layout_width="110dp"
android:layout_height="35dp"
android:layout_margin="5dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/anchor_rv_avatar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="15dp"
android:layout_toRightOf="@+id/layout_live_pusher_info" />
<LinearLayout
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="15dp">
<Button
android:id="@+id/btn_message_input"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/icon_message"
android:onClick="onClick" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/anchor_btn_flash"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/icon_flash"
android:onClick="onClick" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/switch_cam"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/icon_switch_camera_on"
android:onClick="onClick" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/beauty_btn"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/icon_beauty_drawable"
android:onClick="onClick" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btn_audio_ctrl"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/music_big"
android:onClick="onClick" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btn_close"
android:layout_width="@dimen/live_btn_size"
android:layout_height="@dimen/live_btn_size"
android:background="@drawable/btn_close"
android:onClick="onClick" />
</LinearLayout>
<LinearLayout
android:id="@+id/anchor_ll_audio_plugin"
android:layout_width="200dp"
android:layout_height="50dp"
android:orientation="horizontal"
android:visibility="gone"
android:weightSum="10">
<Button
android:id="@+id/btn_audio_effect"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:background="@drawable/shape_round_button"
android:onClick="onClick"
android:text="音效"
android:textColor="#FFFFFF"
android:textSize="20dp" />
<Button
android:id="@+id/btn_audio_close"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:background="@drawable/shape_round_button"
android:onClick="onClick"
android:text="结束"
android:textColor="#FFFFFF"
android:textSize="20dp" />
</LinearLayout>
<ListView
android:id="@+id/im_msg_listview"
android:layout_width="250dp"
android:layout_height="10dp"
android:layout_above="@id/tool_bar"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:cacheColorHint="#00000000"
android:divider="#3c421b1b"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
android:stackFromBottom="true"
android:transcriptMode="normal" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:layout_marginBottom="60dp"
android:background="#00000000"
>
<com.dayu.livemodule.xiaozhibo.anchor.music.TCAudioControl
android:id="@+id/anchor_audio_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:clickable="true"
android:orientation="vertical"
android:padding="0dp"
android:visibility="gone" />
</ScrollView>
<com.tencent.liteav.demo.beauty.BeautyPanel
android:id="@+id/beauty_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/tool_bar"
android:visibility="gone" />
<LinearLayout
android:id="@+id/layoutFaceBeauty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_marginBottom="0dp"
android:background="@color/white"
android:clickable="true"
android:minHeight="105dp"
android:orientation="vertical"
android:padding="15dp"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activity_publish_beauty"
android:textSize="16sp" />
<SeekBar
android:id="@+id/beauty_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:maxHeight="1.0dip"
android:minHeight="1.0dip"
android:paddingLeft="15dp"
android:paddingRight="18dp"
android:progressDrawable="@drawable/beauty_seekbar_progress"
android:thumb="@drawable/beauty_seekbar_icon"
android:visibility="visible" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activity_publish_white"
android:textSize="16sp" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:maxHeight="1.0dip"
android:minHeight="1.0dip"
android:paddingLeft="15dp"
android:paddingRight="18dp"
android:progressDrawable="@drawable/beauty_seekbar_progress"
android:thumb="@drawable/beauty_seekbar_icon"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
<!--点赞动画-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp">
<com.dayu.livemodule.xiaozhibo.common.widget.like.TCHeartLayout
android:id="@+id/heart_layout"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:focusable="true" />
</RelativeLayout>
<!--点赞动画-->
<!--弹幕-->
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/anchor_danmaku_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_centerInParent="true" />
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
...@@ -515,6 +515,7 @@ ...@@ -515,6 +515,7 @@
android:background="@color/colorGray7"/> android:background="@color/colorGray7"/>
<TextView <TextView
android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="50dp" android:layout_height="50dp"
android:text="音效调节" android:text="音效调节"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/xml_music_control_part"
android:orientation="vertical"
android:background="@color/colorTransparentGray"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="15dp">
<Button
android:id="@+id/btn_select_bgm"
android:layout_width="50dp"
android:layout_height="20dp"
android:text="伴奏"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button"
android:layout_marginLeft="15dp"
android:layout_marginBottom="15dp"
android:layout_above="@+id/seekBar_bgm_volume"/>
<Button
android:id="@+id/btn_stop_bgm"
android:layout_width="50dp"
android:layout_height="20dp"
android:text="结束"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button"
android:layout_marginLeft="15dp"
android:layout_marginBottom="15dp"
android:layout_toRightOf="@+id/btn_select_bgm"
android:layout_above="@+id/seekBar_bgm_volume" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="15dp" >
<TextView
android:id="@+id/textView_bgm_pitch"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:text="伴奏音调"
android:textSize="12dp"
android:textColor="@color/colorTextBlack"
android:layout_marginBottom="8dp"
android:layout_above="@+id/textView_bgm_seek"
android:layout_marginLeft="15dp" />
<SeekBar
android:id="@+id/seekBar_bgm_pitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="4.0dip"
android:minHeight="4.0dip"
android:visibility="visible"
android:progressDrawable="@drawable/seekbar_progress_drawable"
android:max="100"
android:progress="50"
android:indeterminate="false"
android:layout_marginBottom="15dp"
android:layout_above="@+id/seekBar_bgm_seek"
android:layout_toRightOf="@+id/textView_bgm_pitch" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="15dp" >
<TextView
android:id="@+id/textView_bgm_seek"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:text="伴奏快进"
android:textSize="12dp"
android:textColor="@color/colorTextBlack"
android:layout_marginBottom="8dp"
android:layout_above="@+id/textView_bgm_volume"
android:layout_marginLeft="15dp" />
<SeekBar
android:id="@+id/seekBar_bgm_seek"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="4.0dip"
android:minHeight="4.0dip"
android:visibility="visible"
android:progressDrawable="@drawable/seekbar_progress_drawable"
android:max="100"
android:progress="0"
android:indeterminate="false"
android:layout_marginBottom="15dp"
android:layout_above="@+id/seekBar_bgm_volume"
android:layout_toRightOf="@+id/textView_bgm_volume" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="15dp" >
<TextView
android:id="@+id/textView_bgm_volume"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:text="伴奏音量"
android:textSize="12dp"
android:textColor="@color/colorTextBlack"
android:layout_marginBottom="8dp"
android:layout_above="@+id/textView_voice_volume"
android:layout_marginLeft="15dp" />
<SeekBar
android:id="@+id/seekBar_bgm_volume"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="4.0dip"
android:minHeight="4.0dip"
android:visibility="visible"
android:progressDrawable="@drawable/seekbar_progress_drawable"
android:max="100"
android:progress="50"
android:indeterminate="false"
android:layout_marginBottom="15dp"
android:layout_above="@+id/seekBar_voice_volume"
android:layout_toRightOf="@+id/textView_bgm_volume" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginTop="15dp" >
<TextView
android:id="@+id/textView_voice_volume"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:text="人声音量"
android:textSize="12dp"
android:textColor="@color/colorTextBlack"
android:layout_marginBottom="8dp"
android:layout_above="@+id/layout_reverb"
android:layout_marginLeft="15dp" />
<SeekBar
android:id="@+id/seekBar_voice_volume"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="4.0dip"
android:minHeight="4.0dip"
android:visibility="visible"
android:progressDrawable="@drawable/seekbar_progress_drawable"
android:max="100"
android:progress="50"
android:indeterminate="false"
android:layout_toRightOf="@+id/textView_voice_volume" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:orientation="horizontal"
android:weightSum="7"
android:layout_above="@+id/textView_audio_ctrl_title">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_default"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="原声"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_1"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="KTV"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_2"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="房间"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_3"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="会堂"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_4"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="低沉"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_5"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="洪亮"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_reverb_6"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="磁性"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:orientation="horizontal"
android:weightSum="7"
android:layout_above="@+id/textView_audio_ctrl_title">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_default"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="原声"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_1"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="熊孩子"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_2"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="萝莉"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_3"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="大叔"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_4"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="重金属"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_5"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="感冒"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:orientation="horizontal"
android:weightSum="7"
android:layout_above="@+id/textView_audio_ctrl_title">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_6"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="外国人"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_7"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="困兽"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_8"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="死肥仔"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_9"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="强电流"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_10"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="重机械"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:id="@+id/btn_voicechanger_11"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="空灵"
android:textSize="12dp"
android:focusable="false"
android:background="@drawable/round_button_2"/>
</FrameLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/colorGray7"/>
<TextView
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="音效调节"
android:textSize="16dp"
android:textColor="@color/colorTextBlack"
android:background="@color/white"
android:gravity="center"
android:layout_alignParentBottom="true" />
</LinearLayout>
<com.dayu.livemodule.xiaozhibo.anchor.music.TCMusicSelectView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/xml_music_select_view"
android:visibility="gone"
android:clickable="true"
android:background="@color/white">
</com.dayu.livemodule.xiaozhibo.anchor.music.TCMusicSelectView>
</LinearLayout>
\ No newline at end of file
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
android:layout_weight="4" android:layout_weight="4"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeActionId="@+id/login" android:imeActionId="@+id/login"
android:imeOptions="actionUnspecified" android:imeOptions="flagNoExtractUi"
android:inputType="text" android:inputType="text"
android:maxLength="32" android:maxLength="32"
android:textColor="@color/black" android:textColor="@color/black"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_outside_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/rl_inputdlg_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_input_dialog_background"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/barrage_area"
android:orientation="horizontal"
android:layout_weight="0.3"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/barrage_btn"
android:layout_width="40dp"
android:layout_marginLeft="10dp"
android:layout_height="25dp"
android:layout_marginRight="10dp"
android:background="@drawable/barrage_slider_off" />
</LinearLayout>
<View android:layout_width="0.5dp"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:background="@color/colorTransparentBlack"/>
<EditText
android:id="@+id/et_input_message"
android:hint="@string/dialog_input_text_hint"
android:layout_width="match_parent"
android:layout_weight="4"
android:layout_height="wrap_content"
android:imeActionId="@+id/login"
android:imeOptions="flagNoExtractUi"
android:inputType="text"
android:maxLength="32"
android:textColor="@color/black"
android:maxLines="1"
android:singleLine="true" />
<View android:layout_width="0.5dp"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:background="@color/colorTransparentBlack"/>
<LinearLayout
android:id="@+id/confirm_area"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_height="wrap_content">
<Button
android:id="@+id/confrim_btn"
android:layout_width="50dp"
android:layout_height="30dp"
android:background="@drawable/btn_send_message"
android:gravity="center"
android:textColor="@color/colorAccent"
android:text="@string/send" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment