初次提交,修改了头像不能展示

This commit is contained in:
2025-08-11 11:01:55 +08:00
commit 7e2dcad9c9
3841 changed files with 227903 additions and 0 deletions

1
module_live/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

73
module_live/build.gradle Normal file
View File

@@ -0,0 +1,73 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
// applicationId "com.yuyin.module_login"
minSdkVersion 22
targetSdkVersion 30
versionCode 12
versionName "1.2"
dataBinding {
//noinspection DataBindingWithoutKapt
enabled = true
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
multiDexEnabled true
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
android {
sourceSets.main {
jniLibs.srcDir 'libs'
jni.srcDirs = []
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.1'
implementation 'androidx.navigation:navigation-ui:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
api 'com.alibaba:arouter-api:1.4.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.palette:palette:1.0.0'
kapt'com.alibaba:arouter-compiler:1.2.2'
api project(':tuicore')
api project(':tuiconversation')
api project(':tuichat')
api project(':lib_base')
api project(':SudMGPWrapper')
}

View File

21
module_live/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yuyin.module_live">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.VIBRATE" />
<application>
<service
android:name=".keepalive.ForegroundService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="microphone|camera|mediaPlayback" />
<service
android:name=".keepalive.CancelNoticeService"
android:enabled="true"
android:exported="true" />
<activity
android:name=".ui.allowance.SearchUserActivity"
android:exported="true" />
<activity
android:name=".ui.allowance.AllocationActivity"
android:exported="true" />
<activity
android:name=".ui.pk.PKRecordActivity"
android:exported="false" />
<activity
android:name=".ui.pk.InitiatePKActivity"
android:exported="false" />
<activity android:name=".ui.rank.RankActivity" />
<activity
android:name=".ui.room.AdminRoomActivity"
android:screenOrientation="portrait"
android:launchMode="singleTask"
/>
<activity android:name=".ui.room.setadmin.SetAdminActivity" />
<activity android:name=".ui.roomset.RoomSetActivity" />
<activity android:name=".ui.room.setsuper.SetSuperAdminActivity" />
<activity android:name=".ui.allowance.LSFilterActivity" />
<activity android:name=".ui.room.music.MusicActivity" />
<activity android:name=".ui.roomset.RoomSetNewActivity"/>
<activity android:name=".ui.roomset.RoomShareRatioActivity"/>
<activity android:name=".ui.rank.WeekRankActivity"/>
<activity android:name=".ui.rank.LoveMtlRankActivity"/>
<activity android:name=".ui.room.black.RoomBlackListActivity"/>
<activity android:name=".ui.roomset.RoomSetTypeActivity"/>
</application>
</manifest>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,422 @@
package com.yuyin.module_live.game;
import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Toast;
import tech.sud.mgp.SudMGPWrapper.decorator.SudFSMMGDecorator;
import tech.sud.mgp.SudMGPWrapper.decorator.SudFSMMGListener;
import tech.sud.mgp.SudMGPWrapper.decorator.SudFSTAPPDecorator;
import tech.sud.mgp.SudMGPWrapper.model.GameConfigModel;
import tech.sud.mgp.SudMGPWrapper.model.GameViewInfoModel;
import tech.sud.mgp.SudMGPWrapper.state.MGStateResponse;
import tech.sud.mgp.SudMGPWrapper.utils.SudJsonUtils;
import tech.sud.mgp.core.ISudFSMStateHandle;
import tech.sud.mgp.core.ISudFSTAPP;
import tech.sud.mgp.core.ISudListenerInitSDK;
import tech.sud.mgp.core.SudMGP;
/**
* 游戏业务逻辑抽象类
* 1.定自义ViewModel继承此类实现对应方法。(注意onAddGameView()与onRemoveGameView()与页面有交互)
* 2.外部调用switchGame()方法启动游戏
* 3.页面销毁时调用onDestroy()
*/
public abstract class BaseGameViewModel implements SudFSMMGListener {
private String gameRoomId; // 游戏房间id
private long playingGameId; // 当前使用的游戏id
public final SudFSTAPPDecorator sudFSTAPPDecorator = new SudFSTAPPDecorator(); // app调用sdk的封装类
public final SudFSMMGDecorator sudFSMMGDecorator = new SudFSMMGDecorator(); // 用于处理游戏SDK部分回调业务
private boolean isRunning = true; // 业务是否还在运行
public View gameView; // 游戏View
public GameConfigModel gameConfigModel = new GameConfigModel(); // 游戏配置
protected final Handler handler = new Handler(Looper.getMainLooper());
/**
* 外部调用切换游戏传不同的gameId即可加载不同的游戏
* gameId传0 等同于关闭游戏
*
* @param activity 游戏所在页面,用作于生命周期判断
* @param gameRoomId 游戏房间id房间隔离同一房间才能一起游戏
* @param gameId 游戏id传入不同的游戏id即可加载不同的游戏传0等同于关闭游戏
*/
public void switchGame(Activity activity, String gameRoomId, long gameId) {
if (TextUtils.isEmpty(gameRoomId)) {
Toast.makeText(activity, "gameRoomId can not be empty", Toast.LENGTH_LONG).show();
return;
}
if (!isRunning) {
return;
}
if (playingGameId == gameId && gameRoomId.equals(this.gameRoomId)) {
return;
}
destroyMG();
this.gameRoomId = gameRoomId;
playingGameId = gameId;
login(activity, gameId);
}
/**
* 第1步获取短期令牌code用于换取游戏Server访问APP Server的长期ssToken
* 接入方客户端 调用 接入方服务端 login 获取 短期令牌code
* 参考文档时序图sud-mgp-doc(https://docs.sud.tech/zh-CN/app/Client/StartUp-Android.html)
*
* @param activity 游戏所在页面
* @param gameId 游戏id
*/
private void login(Activity activity, long gameId) {
if (activity.isDestroyed() || gameId <= 0) {
return;
}
// 请求登录code
getCode(activity, getUserId(), getAppId(), new GameGetCodeListener() {
@Override
public void onSuccess(String code) {
if (!isRunning || gameId != playingGameId) {
return;
}
initSdk(activity, gameId, code);
}
@Override
public void onFailed() {
delayLoadGame(activity, gameId);
}
});
}
/**
* 第2步初始化SudMGP sdk
*
* @param activity 游戏所在页面
* @param gameId 游戏id
* @param code 令牌
*/
private void initSdk(Activity activity, long gameId, String code) {
String appId = getAppId();
String appKey = getAppKey();
// 初始化sdk
SudMGP.initSDK(activity, appId, appKey, isTestEnv(), new ISudListenerInitSDK() {
@Override
public void onSuccess() {
loadGame(activity, code, gameId);
}
@Override
public void onFailure(int errCode, String errMsg) {
// TODO: 2022/6/13 下面toast可以根据业务需要决定是否保留
if (isTestEnv()) {
Toast.makeText(activity, "initSDK onFailure:" + errMsg + "(" + errCode + ")", Toast.LENGTH_LONG).show();
}
delayLoadGame(activity, gameId);
}
});
}
/**
* 第3步加载游戏
* APP和游戏的相互调用
* ISudFSTAPPAPP调用游戏的接口
* ISudFSMMG游戏调APP的响应回调
*
* @param activity 游戏所在页面
* @param code 登录令牌
* @param gameId 游戏id
*/
private void loadGame(Activity activity, String code, long gameId) {
if (activity.isDestroyed() || !isRunning || gameId != playingGameId) {
return;
}
// 给装饰类设置回调
sudFSMMGDecorator.setSudFSMMGListener(this);
// 调用游戏sdk加载游戏
ISudFSTAPP iSudFSTAPP = SudMGP.loadMG(activity, getUserId(), gameRoomId, code, gameId, getLanguageCode(), sudFSMMGDecorator);
// 如果返回空,则代表参数问题或者非主线程
if (iSudFSTAPP == null) {
Toast.makeText(activity, "loadMG params error", Toast.LENGTH_LONG).show();
delayLoadGame(activity, gameId);
return;
}
// APP调用游戏接口的装饰类设置
sudFSTAPPDecorator.setISudFSTAPP(iSudFSTAPP);
// 获取游戏视图将其抛回Activity进行展示
// Activity调用gameContainer.addView(view, FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
gameView = iSudFSTAPP.getGameView();
onAddGameView(gameView);
}
/**
* 游戏加载失败的时候,延迟一会再重新加载
*
* @param activity 游戏所在页面
* @param gameId 游戏id
*/
private void delayLoadGame(Activity activity, long gameId) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
login(activity, gameId);
}
}, 5000);
}
// region 生命周期相关
/** 页面销毁的时候调用 */
public void onDestroy() {
isRunning = true;
destroyMG();
}
// endregion 生命周期相关
/** 销毁游戏 */
private void destroyMG() {
if (playingGameId > 0) {
sudFSTAPPDecorator.destroyMG();
sudFSMMGDecorator.destroyMG();
playingGameId = 0;
gameView = null;
onRemoveGameView();
}
}
/** 获取当前游戏房id */
public String getGameRoomId() {
return gameRoomId;
}
// region 子类需要实现的方法
/**
* 向接入方服务器获取code
*/
protected abstract void getCode(Activity activity, String userId, String appId, GameGetCodeListener listener);
/**
* 设置当前用户id(接入方定义)
*
* @return 返回用户id
*/
protected abstract String getUserId();
/**
* 设置游戏所用的appId
*
* @return 返回游戏服务appId
*/
protected abstract String getAppId();
/**
* 设置游戏所用的appKey
*
* @return 返回游戏服务appKey
*/
protected abstract String getAppKey();
/**
* 设置游戏的语言代码
* 参考文档https://docs.sud.tech/zh-CN/app/Client/Languages/
*
* @return 返回语言代码
*/
protected abstract String getLanguageCode();
/**
* 设置游戏的安全操作区域
*
* @param gameViewInfoModel 游戏视图大小
*/
protected abstract void getGameRect(GameViewInfoModel gameViewInfoModel);
/**
* true 加载游戏时为测试环境
* false 加载游戏时为生产环境
*/
protected abstract boolean isTestEnv();
/**
* 将游戏View添加到页面中
*
* @param gameView
*/
protected abstract void onAddGameView(View gameView);
/**
* 将页面中的游戏View移除
*/
protected abstract void onRemoveGameView();
// endregion 子类需要实现的方法
// region 游戏侧回调
/**
* 游戏日志
* 最低版本v1.1.30.xx
*/
@Override
public void onGameLog(String str) {
SudFSMMGListener.super.onGameLog(str);
}
/**
* 游戏开始
* 最低版本v1.1.30.xx
*/
@Override
public void onGameStarted() {
}
/**
* 游戏销毁
* 最低版本v1.1.30.xx
*/
@Override
public void onGameDestroyed() {
}
/**
* Code过期需要实现
* APP接入方需要调用handle.success或handle.fail
*
* @param dataJson {"code":"value"}
*/
@Override
public void onExpireCode(ISudFSMStateHandle handle, String dataJson) {
processOnExpireCode(sudFSTAPPDecorator, handle);
}
/**
* 获取游戏View信息需要实现
* APP接入方需要调用handle.success或handle.fail
*
* @param handle handle
* @param dataJson {}
*/
@Override
public void onGetGameViewInfo(ISudFSMStateHandle handle, String dataJson) {
processOnGetGameViewInfo(gameView, handle);
}
/**
* 获取游戏Config需要实现
* APP接入方需要调用handle.success或handle.fail
*
* @param handle handle
* @param dataJson {}
* 最低版本v1.1.30.xx
*/
@Override
public void onGetGameCfg(ISudFSMStateHandle handle, String dataJson) {
processOnGetGameCfg(handle, dataJson);
}
// endregion 游戏侧回调
/** 处理code过期 */
public void processOnExpireCode(SudFSTAPPDecorator sudFSTAPPDecorator, ISudFSMStateHandle handle) {
// code过期刷新code
getCode(null, getUserId(), getAppId(), new GameGetCodeListener() {
@Override
public void onSuccess(String code) {
if (!isRunning) return;
MGStateResponse mgStateResponse = new MGStateResponse();
mgStateResponse.ret_code = MGStateResponse.SUCCESS;
sudFSTAPPDecorator.updateCode(code, null);
handle.success(SudJsonUtils.toJson(mgStateResponse));
}
@Override
public void onFailed() {
MGStateResponse mgStateResponse = new MGStateResponse();
mgStateResponse.ret_code = -1;
handle.failure(SudJsonUtils.toJson(mgStateResponse));
}
});
}
/**
* 处理游戏视图信息(游戏安全区)
* 文档https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html
*/
public void processOnGetGameViewInfo(View gameView, ISudFSMStateHandle handle) {
//拿到游戏View的宽高
int gameViewWidth = gameView.getMeasuredWidth();
int gameViewHeight = gameView.getMeasuredHeight();
if (gameViewWidth > 0 && gameViewHeight > 0) {
notifyGameViewInfo(handle, gameViewWidth, gameViewHeight);
return;
}
//如果游戏View未加载完成则监听加载完成时回调
gameView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
gameView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = gameView.getMeasuredWidth();
int height = gameView.getMeasuredHeight();
notifyGameViewInfo(handle, width, height);
}
});
}
/** 通知游戏,游戏视图信息 */
private void notifyGameViewInfo(ISudFSMStateHandle handle, int gameViewWidth, int gameViewHeight) {
GameViewInfoModel gameViewInfoModel = new GameViewInfoModel();
gameViewInfoModel.ret_code = 0;
// 游戏View大小
gameViewInfoModel.view_size.width = gameViewWidth;
gameViewInfoModel.view_size.height = gameViewHeight;
// 游戏安全操作区域
getGameRect(gameViewInfoModel);
// 给游戏侧进行返回
String json = SudJsonUtils.toJson(gameViewInfoModel);
// 如果设置安全区有疑问可将下面的日志打印出来分析json数据
// Log.d("SudBaseGameViewModel", "notifyGameViewInfo:" + json);
handle.success(json);
}
public void onPause() {
// playMG和pauseMG要配对
sudFSTAPPDecorator.pauseMG();
}
public void onResume() {
// playMG和pauseMG要配对
sudFSTAPPDecorator.playMG();
}
/**
* 处理游戏配置
* 文档https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameCfg.html
*/
public void processOnGetGameCfg(ISudFSMStateHandle handle, String dataJson) {
handle.success(SudJsonUtils.toJson(gameConfigModel));
}
/** 游戏login(getCode)监听 */
public interface GameGetCodeListener {
/** 成功 */
void onSuccess(String code);
/** 失败 */
void onFailed();
}
}

View File

@@ -0,0 +1,68 @@
package com.yuyin.module_live.game
import android.app.Dialog
import android.view.Gravity
import android.view.LayoutInflater
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.GridLayoutManager
import com.blankj.utilcode.util.JsonUtils
import com.blankj.utilcode.util.ResourceUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yuyin.module_live.R
import com.yuyin.module_live.databinding.DialogGameListBinding
import com.yuyin.module_live.model.GameListBean
import com.yuyin.module_live.ui.adapter.GameListAdapter
import com.yuyin.module_live.ui.room.AdminRoomActivity
class GameListDialog(val context: AdminRoomActivity) : Dialog(context) {
private lateinit var binding: DialogGameListBinding
private lateinit var gameListAdapter: GameListAdapter
init {
initDialog()
}
private fun initDialog() {
val inflater = LayoutInflater.from(context)
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_game_list, null, false)
setContentView(binding.root)
val window = window
val params = window!!.attributes
params.width = WindowManager.LayoutParams.MATCH_PARENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.BOTTOM
window.attributes = params
window.setBackgroundDrawableResource(R.color.transparent)
initView()
}
private fun initView() {
binding.ivDismiss.setOnClickListener { dismiss() }
val json =
JsonUtils.formatJson(ResourceUtils.readAssets2String("sud_game.json"))
val data = Gson().fromJson<List<GameListBean>>(
json.toString(),
object : TypeToken<List<GameListBean>>() {}.type
)
binding.rvContainer.layoutManager = GridLayoutManager(context, 4)
gameListAdapter = GameListAdapter()
gameListAdapter.setNewData(data)
binding.rvContainer.adapter = gameListAdapter
gameListAdapter.setOnItemClickListener { adapter, view, position ->
context.viewModel.room_game_start(
context.getRid(),
gameListAdapter.data[position].gameId.toString()
)
dismiss()
}
}
}

View File

@@ -0,0 +1,394 @@
package com.yuyin.module_live.game;
import android.app.Activity;
import android.view.View;
import androidx.lifecycle.MutableLiveData;
import com.blankj.utilcode.util.LogUtils;
import com.yuyin.lib_base.Const;
import com.yuyin.lib_base.base.UserManager;
import com.yuyin.lib_base.util.HSTextUtils;
import com.yuyin.module_live.ui.room.AdminRoomActivity;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Objects;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import tech.sud.mgp.SudMGPWrapper.decorator.SudFSMMGListener;
import tech.sud.mgp.SudMGPWrapper.decorator.SudFSTAPPDecorator;
import tech.sud.mgp.SudMGPWrapper.model.GameConfigModel;
import tech.sud.mgp.SudMGPWrapper.model.GameViewInfoModel;
import tech.sud.mgp.SudMGPWrapper.state.SudMGPMGState;
import tech.sud.mgp.SudMGPWrapper.utils.ISudFSMStateHandleUtils;
import tech.sud.mgp.core.ISudFSMMG;
import tech.sud.mgp.core.ISudFSMStateHandle;
/**
* 游戏业务逻辑
* 1.自定义ViewModel继承此类实现对应方法。(注意onAddGameView()与onRemoveGameView()与页面有交互)
* 2.外部调用switchGame(activity,gameRoomId,gameId)方法启动游戏,参数定义可查看方法注释。
* 3.页面销毁时调用onDestroy()
*/
public class QuickStartGameViewModel extends BaseGameViewModel {
/**
* Sud平台申请的appId
*/
public static String SudMGP_APP_ID = "1907343783408873474";
/**
* Sud平台申请的appKey
*/
public static String SudMGP_APP_KEY = "ZpyHv1Pw4iZyQQjdbqA36Qu7EEmv29Ok";
/**
* true 加载游戏时为测试环境 false 加载游戏时为生产环境
*/
public static final boolean GAME_IS_TEST_ENV = false;
/**
* 使用的UserId。这里随机生成作演示开发者将其修改为业务使用的唯一userId
*/
public static String userId = String.valueOf(UserManager.INSTANCE.getUser().getUid());
/**
* 游戏自定义安全操作区域
*/
public GameViewInfoModel.GameViewRectModel gameViewRectModel;
/**
* 游戏的语言代码
*/
public String languageCode = "zh-CN";
public final MutableLiveData<View> gameViewLiveData = new MutableLiveData<>(); // 游戏View回调
// 是否是房主
public final MutableLiveData<Integer> isHouseOwner = new MutableLiveData<Integer>(0);
public MutableLiveData<AdminRoomActivity> activity = new MutableLiveData<AdminRoomActivity>();
public final MutableLiveData<String> gameKeywordLiveData = new MutableLiveData<>(); // 游戏关键字
public GameControlListener gameControlListener;
/**
* 向接入方服务器获取code
*/
@Override
protected void getCode(Activity activity, String userId, String appId, GameGetCodeListener listener) {
// TODO: 2022/6/10 注意这里是演示使用OkHttpClient请求hello-sud服务
// TODO: 2022/6/10 开发者在与后端联调时需将其改成自己的网络请求方式向自己的服务器获取code
OkHttpClient client = new OkHttpClient();
String req;
try {
JSONObject reqJsonObj = new JSONObject();
reqJsonObj.put("login_token", UserManager.INSTANCE.getUser().getLogin_token());
reqJsonObj.put("uid", userId);
reqJsonObj.put("app_id", appId);
req = reqJsonObj.toString();
} catch (Exception e) {
e.printStackTrace();
req = "";
}
LogUtils.e(req);
RequestBody body = RequestBody.create(req, MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(Const.URL1 + "Agora/get_code")
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onFailed();
}
});
}
@Override
public void onResponse(Call call, Response response) {
try {
String dataJson = Objects.requireNonNull(response.body()).string();
JSONObject jsonObject = new JSONObject(dataJson);
// int ret_code = jsonObject.getInt("ret_code");
JSONObject dataObject = jsonObject.getJSONObject("data");
String code = dataObject.getString("code");
handler.post(new Runnable() {
@Override
public void run() {
if (!code.isEmpty()) {
listener.onSuccess(code);
} else {
listener.onFailed();
}
}
});
} catch (Exception e) {
e.printStackTrace();
handler.post(new Runnable() {
@Override
public void run() {
listener.onFailed();
}
});
}
}
});
}
/**
* 设置当前用户id(接入方定义)
*/
@Override
protected String getUserId() {
return userId;
}
/**
* 设置Sud平台申请的appId
*/
@Override
protected String getAppId() {
return SudMGP_APP_ID;
}
/**
* 设置Sud平台申请的appKey
*/
@Override
protected String getAppKey() {
return SudMGP_APP_KEY;
}
/**
* 设置游戏的语言代码
*/
@Override
protected String getLanguageCode() {
return languageCode;
}
/**
* 设置游戏的安全操作区域,{@link ISudFSMMG}.onGetGameViewInfo()的实现。
* 参考文档https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html
*
* @param gameViewInfoModel 游戏视图模型
*/
@Override
protected void getGameRect(GameViewInfoModel gameViewInfoModel) {
// 相对于view_size左、上、右、下边框偏移单位像素
// 开发者可自定义gameViewRectModel来控制安全区域
if (gameViewRectModel != null) {
gameViewInfoModel.view_game_rect = gameViewRectModel;
}
}
/**
* 获取游戏配置对象,{@link ISudFSMMG}.onGetGameCfg()的实现。
* 参考文档https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameCfg.html
* 开发者拿到此对象之后,可修改自己需要的配置
* 注意:在加载游戏之前配置才有效
*
* @return 游戏配置对象
*/
public GameConfigModel getGameConfigModel() {
return gameConfigModel;
}
/**
* true 加载游戏时为测试环境
* false 加载游戏时为生产环境
*/
@Override
protected boolean isTestEnv() {
return GAME_IS_TEST_ENV;
}
/**
* 将游戏View添加到页面中
*/
@Override
protected void onAddGameView(View gameView) {
gameViewLiveData.setValue(gameView);
}
/**
* 将页面中的游戏View移除
*/
@Override
protected void onRemoveGameView() {
gameViewLiveData.setValue(null);
}
// ************ 上面是基础能力以及必要配置,下面讲解状态交互
// ************ 主要有1.App向游戏发送状态2.游戏向App回调状态
/**
* 1.App向游戏发送状态
* 这里演示的是发送1. 加入状态;
* 开发者可自由定义方法,能发送的状态都封装在{@link SudFSTAPPDecorator}
* 参考文档https://docs.sud.tech/zh-CN/app/Client/APPFST/
* 注意:
* 1App向游戏发送状态因为需要走网络所以向游戏发送状态之后不能马上销毁游戏或者finish Activity否则状态无法发送成功。
* 2要保证状态能到达可以发送之后delay 500ms再销毁游戏或者finish Activity。
*/
public void notifyAPPCommonSelfIn(boolean isIn, int seatIndex, boolean isSeatRandom, int teamId) {
sudFSTAPPDecorator.notifyAPPCommonSelfIn(isIn, seatIndex, isSeatRandom, teamId);
}
/**
* 2.游戏向App回调状态
* 这里演示的是接收游戏回调状态10. 游戏状态 mg_common_game_state
* 游戏回调的每个状态都对应着一个方法,方法定义在:{@link SudFSMMGListener}
*/
@Override
public void onGameMGCommonGameState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameState model) {
super.onGameMGCommonGameState(handle, model);
}
/**
* 游戏公屏消息
*
* @param handle
* @param model
*/
@Override
public void onGameMGCommonPublicMessage(ISudFSMStateHandle handle, SudMGPMGState.MGCommonPublicMessage model) {
super.onGameMGCommonPublicMessage(handle, model);
StringBuilder str = new StringBuilder();
for (int i = 0; i < model.msg.size(); i++) {
str.append(model.msg.get(i).text.zh_CN);
}
if (isHouseOwner.getValue() == 1) {
activity.getValue().sendGameChat(str.toString());
}
}
@Override
public void onPlayerMGDGSelecting(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGSelecting model) {
super.onPlayerMGDGSelecting(handle, userId, model);
}
@Override
public void onPlayerMGDGPainting(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGPainting model) {
super.onPlayerMGDGPainting(handle, userId, model);
}
@Override
public void onGameStarted() {
super.onGameStarted();
// activity.getValue().sendGameChat("小管家: 游戏开始");
}
@Override
public void onGameDestroyed() {
super.onGameDestroyed();
// activity.getValue().sendGameChat("小管家: 游戏结束");
}
/**
* 游戏加入状态
*
* @param handle
* @param userId
* @param model
*/
@Override
public void onPlayerMGCommonPlayerIn(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerIn model) {
super.onPlayerMGCommonPlayerIn(handle, userId, model);
if (isHouseOwner.getValue() == 1) {
sudFSTAPPDecorator.notifyAPPCommonSelfCaptain(userId);
}
LogUtils.e(model);
}
/**
* 队长状态
*
* @param handle
* @param userId
* @param model
*/
@Override
public void onPlayerMGCommonPlayerCaptain(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerCaptain model) {
super.onPlayerMGCommonPlayerCaptain(handle, userId, model);
LogUtils.e(model);
}
/**
* 用户发送了公屏消息
*/
public void sendMsgCompleted(String msg) {
if (msg == null || msg.isEmpty()) {
return;
}
// 数字炸弹
if (sudFSMMGDecorator.isHitBomb() && HSTextUtils.isInteger(msg)) {
sudFSTAPPDecorator.notifyAPPCommonSelfTextHitState(false, null, msg, null, null, null);
return;
}
String keyword = gameKeywordLiveData.getValue();
if (keyword == null || keyword.isEmpty()) {
return;
}
// 判断是否命中了关键字这里是contains判断。接入方可根据自身业务使用equals或者其它自定义的条件。
if (msg.contains(keyword)) {
sudFSTAPPDecorator.notifyAPPCommonSelfTextHitState(true, keyword, msg, null, null, null);
gameKeywordLiveData.setValue(null);
}
}
// 返回该用户是否为游戏队长
public boolean isCaptain(long userId) {
String captainUserId = sudFSMMGDecorator.getCaptainUserId();
return (userId + "").equals(captainUserId);
}
public void onGameMGCommonSelfHeadphone(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfHeadphone model) {
if (gameControlListener != null) {
if (model != null && model.isOn) {
gameControlListener.soundStatus(true);
} else {
gameControlListener.soundStatus(false);
}
}
}
public void onGameMGCommonSelfMicrophone(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfMicrophone model) {
if (gameControlListener != null) {
if (model != null && model.isOn) {
gameControlListener.micStatus(true);
} else {
gameControlListener.micStatus(false);
}
}
}
public interface GameControlListener {
void soundStatus(boolean a);
void micStatus(boolean a);
}
}

View File

@@ -0,0 +1,30 @@
package com.yuyin.module_live.game;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
public class QuickStartUtils {
/** 随机生成一个userId用于演示 */
public static String genUserID() {
return md5Hex8(UUID.randomUUID().toString());
}
public static String md5Hex8(String plainText) {
byte[] secretBytes;
try {
secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
return plainText;
}
String md5code = new BigInteger(1, secretBytes).toString(16);
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = String.format("0%s", md5code);
}
return md5code.substring(8, 16);
}
}

View File

@@ -0,0 +1,43 @@
package com.yuyin.module_live.keepalive
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.os.SystemClock
import android.util.Log
// 同时启动两个service共享同一个NotificationID并且将他们同时置为前台状态
// 此时会出现两个前台服务,但通知管理器里只有一个关联的通知。
// 这时我们在其中一个服务中调用 stopForeground(true)
// 这个服务前台状态会被取消,同时状态栏通知也被移除。另外一个服务并没有受到影响,还是前台服务状态,但是此时,状态栏通知已经没了!
// 其oom_adj值还是没变的
class CancelNoticeService : Service() {
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (null == intent) {
//服务被系统kill掉之后重启进来的
return START_NOT_STICKY
}
ForegroundNotification.startForeground(this)
Thread {
SystemClock.sleep(1000)
// stopForeground(true)
Log.d("ForegroundService", "CancelNoticeService onStartCommand: CancelNoticeService" )
ForegroundNotification.stopForeground(this)
// stopSelf()
}.start()
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d("ForegroundService", "onDestroy: CancelNoticeService")
}
}

View File

@@ -0,0 +1,63 @@
package com.yuyin.module_live.keepalive
import android.app.Activity
import android.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
fun Context.startForegroundService() {
Intent(this, ForegroundService::class.java).also { intent ->
if (Build.VERSION.SDK_INT >= 34) {
this.startForegroundService(intent)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
this.startForegroundService(intent)
} else {
this.startService(intent)
}
}
}
fun Context.hideBackground(hide: Boolean) {
var appTasks: List<ActivityManager.AppTask>? = null
val activityManager = getSystemService(
Context.ACTIVITY_SERVICE
) as? ActivityManager
if (activityManager != null && activityManager.appTasks.also {
appTasks = it
} != null && appTasks?.isNotEmpty() == true) {
appTasks?.get(0)?.setExcludeFromRecents(hide)
}
}
fun Activity.ignoreBattery() {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
intent.data = Uri.parse("package:$packageName")
startActivityForResult(intent, 1)
}
fun Activity.startAccessibilitySetting() {
runCatching {
val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
}
fun isServiceRunning(context: Context, serviceName: String="com.voice.module_live.keepalive.ForegroundService"): Boolean {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
if (activityManager != null) {
for (service in activityManager.getRunningServices(Int.MAX_VALUE)) {
if (serviceName == service.service.className) {
return true
}
}
}
return false
}

View File

@@ -0,0 +1,89 @@
package com.yuyin.module_live.keepalive
import android.annotation.SuppressLint
import android.app.*
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.content.getSystemService
import com.yuyin.module_live.ui.room.AdminRoomActivity
@SuppressLint("StaticFieldLeak")
object ForegroundNotification {
private const val CHANNEL_FOREGROUND = "foreground-notification"
const val NOTICE_ID = 233
private var service: Service? = null
private fun createChannelIfNeeded(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
val foregroundChannel =
NotificationChannel(CHANNEL_FOREGROUND, "前台服务", NotificationManager.IMPORTANCE_MIN)
.apply {
setShowBadge(false)
enableLights(false)
enableVibration(false)
lockscreenVisibility = Notification.VISIBILITY_SECRET
}
context.getSystemService<NotificationManager>()
?.createNotificationChannel(foregroundChannel)
}
fun startForeground(service: Service) {
ForegroundNotification.service = service
createChannelIfNeeded(service)
val pendingIntent = PendingIntent.getActivity(
service,
0,
Intent(service, AdminRoomActivity::class.java),
PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(service, CHANNEL_FOREGROUND)
.setSmallIcon(com.yuyin.lib_base.R.mipmap.ic_launcher_app)
.setContentText("正在运行")
.setContentIntent(pendingIntent)
.setLocalOnly(true)
.setPriority(NotificationCompat.PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.setOngoing(true)
.setShowWhen(false)
.build()
service.startForeground(NOTICE_ID, notification)
}
fun stopForeground(service: Service) {
val manager = service.getSystemService(Service.NOTIFICATION_SERVICE) as? NotificationManager
manager?.cancel(NOTICE_ID)
service.stopForeground(true)
}
fun cancelNotice(service: Service) {
val manager = service.getSystemService(Service.NOTIFICATION_SERVICE) as? NotificationManager
manager?.cancel(NOTICE_ID)
}
fun stopForeground() {
val manager =
service?.getSystemService(Service.NOTIFICATION_SERVICE) as? NotificationManager
manager?.cancel(NOTICE_ID)
service?.stopForeground(true)
}
fun startForegroundIfNeed(service: Service) {
val manager = service.getSystemService(Service.NOTIFICATION_SERVICE) as? NotificationManager
var needStart = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager?.activeNotifications?.forEach {
needStart = (it.id == NOTICE_ID).not()
}
}
if (needStart) {
startForeground(service)
}
}
}

View File

@@ -0,0 +1,49 @@
package com.yuyin.module_live.keepalive
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import java.util.*
//前台服务
class ForegroundService : Service() {
private var logInt = 0
private var timer: Timer? = null
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
ForegroundNotification.startForeground(this)
timer = Timer()
timer?.schedule(object : TimerTask() {
override fun run() {
Log.d("ForegroundService", "Timer task ${logInt++}")
}
}, 0L, 300L)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (null == intent) {
//服务被系统kill掉之后重启进来的
return START_NOT_STICKY
}
ForegroundNotification.startForegroundIfNeed(this)
if (ServiceHelper.cancelNotice) {
Log.d("ForegroundService", "onStartCommand: CancelNoticeService")
val intent = Intent(this, CancelNoticeService::class.java)
startService(intent)
}
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d("ForegroundService", "onDestroy: $timer")
timer?.cancel()
ForegroundNotification.stopForeground(this)
// 重启自己
startForegroundService()
}
}

View File

@@ -0,0 +1,25 @@
package com.yuyin.module_live.keepalive;
import android.content.Context;
import android.os.PowerManager;
public class ScreenLocker {
private PowerManager.WakeLock wakeLock;
public ScreenLocker(Context context) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
}
public void acquireLock() {
if (wakeLock != null) {
wakeLock.acquire();
}
}
public void releaseLock() {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
}
}

View File

@@ -0,0 +1,6 @@
package com.yuyin.module_live.keepalive
object ServiceHelper {
var cancelNotice = false
}

View File

@@ -0,0 +1,40 @@
package com.yuyin.module_live.model
data class UserPackBean(
var num: Int = 0,
var gid: String = "",
var type: String = "",
var gift_name: String = "",
var gift_price: String = "",
var base_image: String = "",
var play_image: String = "",
var checked: Boolean = false,
var is_public_screen: String = "",
var is_public_server: String = "",
var mView: Any,
var page: Int = 0
)
data class GiftsBean(
var gid: String = "",
var type: String = "",
var checked: Boolean = false,
var gift_name: String = "",
var gift_price: String = "",
var base_image: String = "",
var play_image: String = "",
var is_public_screen: String = "",
var is_public_server: String = "",
var tag_name: String = "",
var mView: Any,
var page: Int = 0,
val nobility_name:String="",
var num: Int = 0,
)
data class MyGiftBean(
var integral: String = "",
var user_pack_gift_price: String ="",
var gift_list: List<GiftsBean> = ArrayList(),
)

View File

@@ -0,0 +1,956 @@
package com.yuyin.module_live.model
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.entity.MultiItemEntity
import com.orient.tea.barragephoto.model.DataSource
import com.yuyin.lib_base.socket.*
import com.yuyin.lib_base.socket.SocketSendBeanAllSub
import com.yuyin.module_live.R
import java.io.Serializable
data class OpenCCLBean(
var room_gashapon_join: String = "",
var user_gashapon_join: String = "",
var gid: String = "",
var room_gashapon_num: String = "",
var user_gashapon_list: ArrayList<CCLBean> = ArrayList(),
)
data class CCLBean(
var color_type: String = "",
var gashapon_number: String = "",
)
data class RoomMoneyLogBean(
val last_week_income: String,
val last_week_subsidy_money: String,
val room_subsidy_info: List<RoomSubsidyInfo>,
val week_income: String
)
data class RoomSubsidyInfo(
val id: Int,
val level_name: String,
val money: String,
val total_gift_price: String,
val type: Int
)
data class RoomMoneyLogSub(
var u_nick_name: String = "",//送礼人昵称
var r_nick_name: String = "",//收礼人昵称
var base_image: String = "",//收礼人昵称
var rid: String = "",
var gift_name: String = "",
var gift_price: String = "",
var gift_num: String = "",
var add_time: String = "",
var gift_total_price: String = "",
)
data class DialogBean(
var name: String = "",
var id: Int = 0,
)
data class TeQuanBean(
var level: Int = 0,
var level_image: String = "",
var man_head_decorate: TeQuanSubBean = TeQuanSubBean(),
var woman_head_decorate: TeQuanSubBean = TeQuanSubBean(),
var man_mount_decorate: TeQuanSubBean = TeQuanSubBean(),
var woman_mount_decorate: TeQuanSubBean = TeQuanSubBean()
)
data class TeQuanSubBean(
var title: String = "",
var base_image: String = "",
)
data class SocketSendBeanAllSub(
val room_info: SocketSendRoomBean = SocketSendRoomBean(),
val gift_list: ArrayList<SocketSendGiftBean> = ArrayList()
)
data class PushBean(
var type2: String = "",
var socketOpenBean: SocketOpenBean = SocketOpenBean(),
var sendBeanAllSub: SocketSendGiftBean = SocketSendGiftBean(),
var content: String = "",
var rid: String = "",
var u_nick_name: String = "",
var u_receive_name: String = "",
var gift_name: String = "",
var is_blind_gift: Int = 0,
) : DataSource {
override fun getType(): Int = 1
}
data class GameCategorySub(
var gid: String = "",
var game_name: String = "",
var game_ico: String = "",
var game_ico1: String = "",
var sort: String = "",
)
data class GameCategoryListBean(
val game_category_list: ArrayList<GameCategorySub> = ArrayList()
)
data class RoomUserVip(
var zq_play_image: String = "",
var contribution_level_image: String = "",
var qp_play_image: String,
var base_image: String,
var qp_base_image: String,
var font_color: String = "",
val charm_level_image: String = "",
var is_room_hiding: String = "",
val not_kick_out: Int = 0,
val qp_title: String = "",
val tx_play_image: String = "",
val tx_title: String = "",
val zq_title: String = "",
var cp_info: CPInfo = CPInfo()
)
data class CPInfo(
val head_pic: String = "",
val nick_name: String = "",
val receive_head_pic: String = "",
val receive_nick_name: String = "",
val receive_uid: Int = 0,
val uid: Int = 0,
val texiao_img: String = "",
val avatar_play_image: String = "",
val receive_avatar_play_image: String = "",
)
data class RoomUserList(
var showSearch: Boolean = false,
var position: Int = 0,
var micro_user_list: List<RoomUserSub> = ArrayList(),
var unmicro_user_list: List<RoomUserSub> = ArrayList()
)
data class RoomAdminList(
var room_admin_list: List<RoomUserSub> = ArrayList(),
var room_visitor_list: List<RoomUserSub> = ArrayList(),
var room_super_admin_list: List<RoomUserSub> = ArrayList()
)
data class RoomUserSub(
var uid: String = "",
var head_pic: String = "",
var sex: String = "",
var special_uid: String = "",
var charm_level: String = "",
var contribution_level: String = "",
var nick_name: String = "",
val user_type: Int = 0
)
data class OtherUserBean(
var uid: Int = 0,
var head_pic: String = "",
var is_room_black: Int = 0,
var sex: Int = 0,
var birthday: String = "",
var special_uid: String = "",
var ry_uid: String = "",
var ry_token: String = "",
var charm_level: Int = 0,
var contribution_level: Int = 0,
var nick_name: String = "",
var is_follow: Int = 0,
var user_micro_status: Int = 0,
var user_world_status: Int = 0,
var user_type: Int = 0,
var avatar_play_image: String = "",
var charm_level_image: String = "",
var contribution_level_image: String = "",
var is_can_recharge: Int = 0,
var is_super_admin: Int = 0,
var is_admin: Int = 0,
var nobility_image: String = "",
var user_cp_info: UserCPInfo = UserCPInfo(),
var relation_num: String = "",
var sign_contract_num: String = "",
var change_value: String = "",
val is_have_producer: Int = 0,
var producer_uid: Int = 0,
val producer_nick_name: String = "",
val producer_head_pic: String = "",
val is_new: Int = 0,
var social: String = ""
)
data class UserCPInfo(
val avatar_play_image: String = "",
val cp_level: Int = 0,
val cp_value: String = "",
val head_pic: String = "",
val next_level: Int = 0,
val next_value: Int = 0,
val nick_name: String = "",
val now_level: Int = 0,
val now_value: Int = 0,
val receive_avatar_play_image: String = "",
val receive_head_pic: String = "",
val receive_nick_name: String = "",
val receive_uid: Int = 0,
val receive_win_base_image: String = "",
val receive_win_play_image: String = "",
val uid: String = "",
val win_base_image: String = "",
val win_play_image: String = "",
var is_have_cp: Int = 0
)
data class EmojiDetailBean(
var image: String = "",
var type: String = "",
var name: String = "",
var second: String = "",
var result: String = ""
)
data class EmojiBean(
var eid: String = "", var name: String = "", var second: String = "", var image: String = ""
) : Serializable
data class ShouQiBangBean(
var uid: String = "",
var num: String = "",
var total_open_num: String = "",
var add_time: String = "",
var nick_name: String = "",
var head_pic: String = "",
var gift_name: String = "",
var base_image: String = "",
var box_type_name: String = "",
var win_total_price: String = ""
)
data class TopLineBean(
var pay_integral: Int = 0, //支付金币
var step_integral: Int = 0, //每次增加金币
)
data class MoneyBean(
var alipay_name: String = "",
var alipay_account: String = "",
var integral: String = "0",
var money: String = "0",
var is_bingd_alipay: Int = 0,
var europe_key: Int = 0
)
data class OpenBoxBean(
var user_money: Int = 0,
var user_win_gift_total_value: Int = 0,
var user_box_times: String = "",
var win_gift_list: List<OpenGiftBean> = ArrayList()
)
data class OpenGiftBean(
var gid: String = "",
var gift_name: String = "",
var gift_price: String = "",
var base_image: String = "",
var play_image: String = "",
var gift_type: String = "",
var open_num: String = "",
var is_public_screen: String = "",
var is_public_server: String = "",
var box_type: String = "",
var surprise: Int = 0,
)
data class BoxBaoLvBean(
var out_amount: String = "",
var in_amount: String = "",
var rate: String = "",
)
data class BoxJiLuBean(
var gid: String = "",
var num: String = "",
var add_time: String = "",
var gift_name: String = "",
var base_image: String = ""
)
data class BoxJiangChiListBean(
val one: ArrayList<BoxJiangChiBean> = ArrayList(),
val two: ArrayList<BoxJiangChiBean> = ArrayList(),
val three: ArrayList<BoxJiangChiBean> = ArrayList(),
)
data class BoxJiangChiBean(
var gid: String = "",
var gift_name: String = "",
var gift_price: String = "",
var base_image: String = "",
var play_image: String = ""
)
data class RoomMessageBean(
var message: String = "",
var messageType: String = "",
var nickName: String = "",
var user_id: String = "",
var contribution_level_image: String = "",
var is_room_hiding: String = "",
var type: String = "",
var open_box: SocketOpenBean = SocketOpenBean(),
var user_gashapon_list: ArrayList<CCLBean> = ArrayList(),
var send_gift: SocketSendGiftBean = SocketSendGiftBean(),
var emojiDetailBean: EmojiDetailBean = EmojiDetailBean(),
var qp_base_image: String = "",
var qp_title: String = "",
var font_color: String = "",
var siliao_id: String = "",
var zq_title: String = "",
var send_nick_name: String = "",
var send_head_pic: String = "",
var receive_nick_name: String = "",
var receive_head_pic: String = "",
var texiao_img: String = "",
var avatar_play_image: String = "",
var receive_avatar_play_image: String = "",
var position: String = "",
var receive_uid: String = "",
var img: String = "",
var Song_name: String = "",
var Song_code: String = "",
var Singer: String = "",
var Poster: String = "",
var ktvUid: String = "",
)
data class RoomMessageLhBean(
var data: RoomMessageDataBean=RoomMessageDataBean()
)
data class RoomMessageDataBean(
var rid: String = "",
)
data class RoomBgBean(
var bid: String = "",
var image_name: String = "",
var image_url: String = "",
var isSlect: Boolean = false
)
data class RoomCateBean(
var category_name:String="",
var cate_id: Int = 0,
var tid: Int = 0,
var isSelect: Boolean = false
)
data class RoomCateApplysBean(
var category_name:String="",
var tid: Int = 0,
var cate_id: Int = 0,
var apply_status:String="",
)
data class UserWorldStatus(
var lock_status: Int = 0, var lock_status_str: String = ""
)
data class CheckRealBean(
var is_real: Int = 0 //1已实名 2未实名
)
data class RankBean(
var hot_value_day: Int = 0,
var list: List<RankListBean> = ArrayList(),
var user_info: MyRankBean = MyRankBean()
)
data class BoxCountBean(
var user_box_times:String=""
)
data class MyRankBean(
var uid: String = "",
var nick_name: String = "",
var head_pic: String = "",
var contribution_image: String = "",
var charm_image: String = "",
var is_rank: String = "",
var my_rank: String = "",
var rank_value: String = "",
)
data class BlackBean(
var uid: String = "",
var nick_name: String = "",
var sex: String = "",
var head_pic: String = "",
var user_charm_contribution_info: userContributionInfo = userContributionInfo()
)
data class userContributionInfo(
var charm_level_image: String = "",
var contribution_level_image: String = "",
)
data class RankListBean(
var uid: String = "",
var head_pic: String = "",
var levels: Int = 0,
var level_value: String = "",
var sex: Int = 0,
var nick_name: String = "",
var special_uid: String = "",
var charm_value: String = "",
var contribution_value: String = "",
var charm_image: String = "",
var contribution_image: String = "",
var rank_value: String = "",
val base64_room_name: String = "",
val rid: Int = 0,
val room_cover: String = "",
val room_name: String = "",
val room_number: Int = 0,
val room_owner_uid: Int = 0,
val total_amount: String = ""
)
data class PKRecordBean(
val add_time: Int,
val is_close: Int,
val left_user_list: List<LeftUser>,
val pk_theme: String,
val pk_time: Int,
val pk_type: Int,
val pkid: Int,
val receive_uid: String,
val receive_uid_value: String,
val right_user_list: List<LeftUser>,
val uid: String,
val uid_value: String
)
data class LeftUser(
val head_pic: String, val uid: Int
)
data class SongListBean(
val add_time: Int,
val aid: Int,
val duration: Int,
val is_delete: Int,
val mv: Any,
val poster: String,
val release_time: Int,
val singer: String,
val song_code: String,
val song_name: String,
val status: Int,
val type: Int,
val update_time: Any,
val hid: Int,
val num: Int,
val price: Int,
val sid: Int,
)
data class RelationListBean(
val color: String, val day: Int, val id: Int, val name: String
)
data class GiftLoveBean(
val gid: String = "",
val gift_price: String = "",
val base_image: String = "",
val gift_name: String = "",
val tag_name: String = "",
var isSelect: Boolean = false
)
data class WishGiftInfo(
val uid: String,
val nick_name: String,
val head_pic: String,
val gift_name: String,
val base_image: String,
val gift_price: String
)
data class RoomSetCompereBean(
val type: Int = 0, val content: String = "", val roomHost: RoomHost = RoomHost()
) : MultiItemEntity {
override fun getItemType(): Int {
return type
}
}
data class RoomHostListBean(
val room_host_list: List<RoomHost>, val room_visitor_list: List<RoomHost>
)
data class RoomHost(
val base64_nick_name: String = "",
val head_pic: String = "",
val nick_name: String = "",
val uid: Int = 0,
var is_host: Boolean = false
)
data class CPListBean(
val list: List<CPList>
)
data class CPList(
val base64_nick_name: String,
val head_pic: String,
val nick_name: String,
val receive_base64_nick_name: String,
val receive_head_pic: String,
val receive_nick_name: String,
val receive_uid: Int,
val total_amount: String,
val uid: Int,
val win_base_image: String,
val win_play_image: String,
val receive_win_base_image: String,
val receive_win_play_image: String,
)
data class AuctionPriceListItem(
val price: Int
)
data class PrivacyRoomInfoBean(
var surplus_time: Int,
val receive_info: UserInfo,
val user_info: UserInfo,
val gift_list: List<PrivacyRoomGift>
)
data class PrivacyRoomGift(
var gid: Int = 0,
var duration: Int = 0,
var gift_name: String = "",
var base_image: String = "",
var gift_price: String = ""
)
data class SignedArtistBean(
val base64_nick_name: String,
val end_time: Int,
val head_pic: String,
val id: Int,
val nick_name: String,
val sex: Int,
val uid: Int
)
data class RelationTimeBean(
val day: String
)
data class AuctionBidGiftsBean(
val base_image: String,
val gid: Int,
val gift_name: String,
val gift_price: String,
val head_pic: String,
val integral: String,
val nick_name: String,
val uid: Int
)
data class RoomSetHostListBean(
val base64_nick_name: String,
val head_pic: String,
val id: String,
val nick_name: String,
var ratio: String,
val room_owner_ratio: String,
val today_host_time: String,
val today_profit: String,
val uid: String
)
data class RoomUserSubsidyListBean(
val room_owner_info: RoomOwnerInfo, val room_subsidy_list: List<RoomSubsidy>
)
data class RoomOwnerInfo(
val head_pic: String,
val nick_name: String,
val ratio: Int,
val subsidy_money: Int,
val uid: Int
)
data class GameListBean(
val gameId: Long,
val gameName: String,
val gameRoomPic: String
)
data class RoomSubsidy(
val base64_nick_name: String,
val head_pic: String,
val id: Int,
val nick_name: String,
val ratio: Int,
val rid: Int,
val subsidy_money: Int,
val uid: Int
)
data class UserGiftList(
var gid: String = "",
var gift_name: String = "",
var gift_price: String = "",
var gift_total_sum: String = "",
var gift_total_price: String = "",
var base_image: String = "",
val head_pic: String = "",
var isSelect: Boolean = false,
var num: String = "",
var max_gift_num_user: FriendBean
)
data class InvitationList(
val user_total_earnings: Double, val list: ArrayList<FriendBean>
)
data class FriendBean(
var add_time: String = "",
var base64_nick_name: String = "",
var head_pic: String = "",
var nick_name: String = "",
var uid: Int = 0,
var sex: Int = 0,
var special_uid: Int = 0,
var give_earnings: Double = 0.00,
var num: Int = 0,
)
data class UserChumBean(
val count: Int, val list: List<UserChum>
)
data class UserChum(
val color: String,
val end_time: Int,
val head_pic: String,
val id: Int,
val name: String,
val nick_name: String,
val relation_id: Int,
val sex: Int,
val surplus_time: Int,
val uid: Int
)
data class SendGiftSingle(
val nick_name: String, val head_pic: String, val uid: String
)
data class IsEarnings(
val is_earnings: Int
)
data class SpriteExchangeInfo(
var integral: String,
var airship: String,
)
data class MonsterLogBean(
val add_time: Int,
val id: Int,
val is_evil_wind: Int,
val is_join: Int,
val win_type: Int,
val win_type_data: List<WinTypeData>,
val win_gift_list: List<WinGift>,
val join_data: List<WinTypeData>,
val base_image: String,
val gift_name: String,
val gift_price: Int,
val num: Int,
val type_name: String,
)
data class WinTypeData(
val type: Int, val type_name: String,
val num: Int
)
data class NowGiftWeekRankData(
var my_user_info: GiftUserInfo,
val list: List<GiftWeekRankData>,
)
data class GiftWeekRankData(
val receive_uid: String = "",
val total_gift_num: String = "",
val gid: String = "",
val gift_name: String = "",
val base_image: String = "",
val nick_name: String = "",
val head_pic: String = "",
val uid: String = "",
val give_uid: String = "",
val give_head_pic: String = "",
val give_nick_name: String = "",
val give_total_gift_num: String = "",
)
data class GiftUserInfo(
val uid: String = "",
val nick_name: String = "",
val head_pic: String = "",
val is_top_rank: String = "",
val diff_num: String = "",
)
data class WeekStartGiftData(
val gid: String = "",
val gift_name: String = "",
val gift_price: String = "",
var isSelect: Boolean = false,
val base_image: String = "",
val tag_name: String = "",
)
data class MtlRankGiftData(
val uid: String = "",
val nick_name: String = "",
val head_pic: String = "",
val receive_uid: String = "",
val receive_nick_name: String = "",
val rank_value: String = "",
val receive_head_pic: String = "",
)
data class BoxListBean(
val integral: String,
val list: List<SocketBoxList>
)
data class Box4ResultBeanItem(
val base64_nick_name: String,
val head_pic: String,
val id: Int,
val nick_name: String,
val over_time: Long,
val uid: Int,
val nbl_sn: Int
)
data class Box4Note(
val note: String = ""
)
data class AuctionRankBean(
var auction_uid: String,
var charm_level_image: String,
var contribution_level_image: String,
var head_pic: String,
var nick_name: String,
var total_price: String
)
data class MonsterUserLogBean(
val add_time: Int,
val base64_nick_name: String,
val base_image: String,
val gift_name: String,
val gift_price: String,
val head_pic: String,
val id: Int,
val mid: Int,
val nick_name: String,
val num: Int,
val type_name: String,
val uid: Int,
val win_type: Int
)
data class MonsterInfoBean(
val integral: String,
val is_finsh: Int,
val multiple_list: List<Multiple>,
val open_monster_price: String,
val surplus_time: Int,
val win_number: Int
)
data class Multiple(
val id: Int,
val multiple: Double,
val type_name: String,
val num: Int,
val type: Int
)
data class MonsterResultBean(
val head_pic: String,
val id: String,
val integral: String,
val nick_name: String,
val num: Int,
val price: Int,
val type: String,
val type_name: String,
val uid: Int
)
data class MonsterEndBean(
val game_name: String,
val gift_name: String,
val is_finsh: Int,
val is_push_message: Int,
val multiple_list: List<Multiple>,
val num: Int,
val surplus_time: Int,
val total_gift_price: Int,
val win_count: Int,
val win_number: Int,
val win_type_name: String
)
data class OpenMonsterBean(
val base_image: String,
val gid: Int,
val gift_name: String,
val gift_price: String,
val is_win: Int,
val num: Int,
val total_gift_price: Int,
val type_name: String,
val win_type: Int
)
data class BlindBoxInitBean(
val blind_info: BlindInfo,
val end_time: Int,
val head_pic: String,
val lock_user_info: LockUserInfo,
val max_num: Int,
val min_num: Int,
val next_gift_image: String,
val next_multi: Int,
val now_gift_image: String,
val now_multi: Int,
val pattern_id: Int,
val send_gift_list: List<SendGiftList>,
val stage: Int,
val term_id: Int,
val is_open: Int,
val gift_name:String,
val now_gift_name:String,
var blind_uid: String,
var giftBean: GiftsBean,
var lock_gift_name:String,
val time_long:Int
)
data class BlindInfo(
val base_image: String,
val gift_name: String,
val gift_price: String
)
data class LockUserInfo(
val base_image: String,
val multi: Int,
val receive_head_pic: String,
val receive_nick_name: String,
val receive_uid: Int,
val send_head_pic: String,
val send_nick_name: String,
val send_uid: Int,
val end_time: Int,
val receive_base_image:String
)
data class SendGiftList(
val gift_name: String,
val gift_num: String,
val nick_name: String
)
data class BlindBoxRankBean(
val base64_nick_name: String,
val gift_list: ArrayList<Gift>,
val head_pic: String,
val nick_name: String,
val total_gift_price: String,
val uid: Int
)
data class Gift(
val base_image: String,
val gift_num: String,
val total_gift_price: String
)
data class BlindBoxRecordBean(
val base_image: String,
val gid: Int,
val gift_name: String,
val gift_num: Int,
val gift_price: Int,
val head_pic: String,
val nick_name: String,
val receive_head_pic: String,
val receive_nick_name: String,
val receive_uid: Int,
val uid: Int,
var receive_base_image:String,
val add_time:Int,
val receive_gift_name:String
)
data class SocketNewStatusInfo(
val code: Int,
val data: BlindBoxInitBean,
val msg: String
)
data class SocketLockUserInfo(
val code: Int,
val data: LockUserInfo,
val msg: String
)

View File

@@ -0,0 +1,10 @@
package com.yuyin.module_live.model;
public class RealTimeMessages<T> {
public T data;
public int code;
}

View File

@@ -0,0 +1,29 @@
package com.yuyin.module_live.model;
import com.chad.library.adapter.base.entity.MultiItemEntity;
public class RoomMultipleItem implements MultiItemEntity {
public static final int TITLE_MIC_UP = 1;
public static final int MIC_UP = 2;
public static final int TITLE_MIC_DOWN = 3;
public static final int MIC_DOWN = 4;
private int itemType;
private RoomUserSub micUserBean;
public RoomMultipleItem(int itemType, RoomUserSub data) {
this.itemType = itemType;
this.micUserBean = data;
}
@Override
public int getItemType() {
return itemType;
}
public RoomUserSub getData(){
return micUserBean;
}
}

View File

@@ -0,0 +1,11 @@
package com.yuyin.module_live.network
import com.yuyin.lib_base.http.RequestService
/**
* @author jhb
* @date 2020/10/23
*/
object LiveApiServer {
val api by lazy { RequestService.create<LiveApiService>() }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,994 @@
package com.yuyin.module_live.repository
import android.text.TextUtils
import com.yuyin.lib_base.http.BaseRepository
import com.yuyin.lib_base.http.ResponseData
import com.yuyin.lib_base.model.IsOpenBean
import com.yuyin.lib_base.model.McListBean
import com.yuyin.lib_base.socket.*
import com.yuyin.module_live.model.*
import com.yuyin.module_live.network.LiveApiServer
import com.yuyin.module_live.network.LiveApiService
import retrofit2.http.*
class LiveRepository : BaseRepository() {
suspend fun remove_mykeep(rid: String): ResponseData<Any> = request {
LiveApiServer.api.remove_mykeep(rid)
}
suspend fun get_room_money_log_list(
rid: String
): ResponseData<RoomMoneyLogBean> = request {
LiveApiServer.api.get_room_money_log_list(rid)
}
suspend fun room_lucky_subsidy_info(
rid: String
): ResponseData<RoomMoneyLogBean> = request {
LiveApiServer.api.room_lucky_subsidy_info(rid)
}
suspend fun room_mykeep(rid: String): ResponseData<Any> = request {
LiveApiServer.api.room_mykeep(rid)
}
suspend fun open_gashapon(rid: String): ResponseData<OpenCCLBean> = request {
LiveApiServer.api.open_gashapon(rid)
}
suspend fun open_room_gashapon(rid: String): ResponseData<Any> = request {
LiveApiServer.api.open_room_gashapon(rid)
}
suspend fun user_gashapon_info(rid: String): ResponseData<OpenCCLBean> = request {
LiveApiServer.api.user_gashapon_info(rid)
}
suspend fun edit_room_gashapon_num(rid: String, gashapon_num: String): ResponseData<Any> =
request {
LiveApiServer.api.edit_room_gashapon_num(rid, gashapon_num)
}
suspend fun user_dispose_gashapon(
@Field("rid") rid: String, @Field("gid") gid: String, @Field("type") type: String
): ResponseData<Any> = request {
LiveApiServer.api.user_dispose_gashapon(rid, gid, type)
}
suspend fun get_decorate_list(): ResponseData<ArrayList<TeQuanBean>> = request {
LiveApiServer.api.get_decorate_list()
}
suspend fun get_room_rank(
rid: String, time: String, type: String
): ResponseData<RankBean> = request {
if (TextUtils.isEmpty(rid) || rid == "null") {
LiveApiServer.api.get_user_rank(rid, time, type)
} else {
LiveApiServer.api.get_room_rank(rid, time, type)
}
}
suspend fun get_room_rank_top(rid: String): ResponseData<RankBean> = request {
LiveApiServer.api.get_room_rank_top(rid)
}
suspend fun get_user_box_times(): ResponseData<BoxCountBean> = request {
LiveApiServer.api.get_user_box_times()
}
suspend fun get_room_user_black_list(rid: String):ResponseData<List<BlackBean>> = request {
LiveApiServer.api.get_room_user_black_list(rid)
}
suspend fun remove_blacklist(user_id: String): ResponseData<Any> = request {
LiveApiServer.api.remove_blacklist(user_id)
}
suspend fun shut_microphone(rid: String, position: Int): ResponseData<Any> = request {
LiveApiServer.api.shut_microphone(rid, position)
}
suspend fun open_microphone(rid: String, position: Int): ResponseData<Any> = request {
LiveApiServer.api.open_microphone(rid, position)
}
suspend fun get_room_micro_info(rid: String): ResponseData<McListBean> = request {
LiveApiServer.api.get_room_micro_info(rid)
}
suspend fun get_room_background_list(): ResponseData<ArrayList<RoomBgBean>> = request {
LiveApiServer.api.get_room_background_list()
}
suspend fun get_power_room_cate(rid:String): ResponseData<ArrayList<RoomCateBean>> = request {
LiveApiServer.api.get_power_room_cate(rid)
}
suspend fun room_cate_applys(rid:String): ResponseData<ArrayList<RoomCateApplysBean>> = request {
LiveApiServer.api.room_cate_applys(rid)
}
suspend fun user_apply_room(rid:String,cate_id:String): ResponseData<Any> = request {
LiveApiServer.api.user_apply_room(rid,cate_id)
}
suspend fun user_up_micro(rid: String, micro_id: String): ResponseData<Any> = request {
LiveApiServer.api.user_up_micro(rid, micro_id)
}
suspend fun user_down_micro(rid: String, micro_id: String): ResponseData<Any> = request {
LiveApiServer.api.user_down_micro(rid, micro_id)
}
suspend fun get_box_list(tid: String): ResponseData<ArrayList<BoxJiangChiBean>> = request {
LiveApiServer.api.get_box_list(tid)
}
suspend fun get_bt_consume(type:String): ResponseData<SocketBTData> = request {
LiveApiServer.api.get_bt_consume(type)
}
suspend fun get_box_lists(): ResponseData<BoxJiangChiListBean> = request {
LiveApiServer.api.get_box_lists()
}
suspend fun get_box_note(tid: String): ResponseData<String> = request {
LiveApiServer.api.get_box_note(tid)
}
suspend fun get_user_box_count(type: String): ResponseData<BoxBaoLvBean> = request {
LiveApiServer.api.get_user_box_count(type)
}
suspend fun get_user_box_gift_list(
page: String, box_type: String
): ResponseData<ArrayList<BoxJiLuBean>> = request {
LiveApiServer.api.get_user_box_gift_list(page, box_type)
}
suspend fun open_box(
open_num: String, rid: String, tid: String
): ResponseData<OpenBoxBean> = request {
LiveApiServer.api.open_box(open_num, rid, tid)
}
suspend fun get_box_user_sqb_rank(
page: String, box_type: String
): ResponseData<ArrayList<ShouQiBangBean>> = request {
LiveApiServer.api.get_box_user_sqb_rank(page, box_type)
}
suspend fun get_gift_list(type: Int): ResponseData<MyGiftBean> = request {
LiveApiServer.api.get_gift_list(type)
}
suspend fun get_room_emoji(): ResponseData<ArrayList<EmojiBean>> = request {
LiveApiServer.api.get_room_emoji(1, 99)
}
suspend fun get_room_emoji_info(eid: String): ResponseData<EmojiDetailBean> = request {
LiveApiServer.api.get_room_emoji_info(eid)
}
suspend fun send_gift(
gid: String, rid: String, to_uid_list: String, num: String, pack: String, help_uid: String
): ResponseData<SocketSendBean> = request {
LiveApiServer.api.send_gift(gid, rid, to_uid_list, num, pack, help_uid)
}
suspend fun send_all_pack_gift(rid: String, recived_uid: String): ResponseData<Any> = request {
LiveApiServer.api.send_all_pack_gift(rid, recived_uid)
}
suspend fun get_other_user(
rid: String, uid: String
): ResponseData<OtherUserBean> = request {
LiveApiServer.api.get_other_user(rid, uid)
}
suspend fun cleargiftpricecount(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.cleargiftpricecount(uid, rid)
}
suspend fun host_up_micro(
rid: String
): ResponseData<Any> = request {
LiveApiServer.api.host_up_micro(rid)
}
suspend fun host_down_micro(
rid: String
): ResponseData<Any> = request {
LiveApiServer.api.host_down_micro(rid)
}
suspend fun clear_user_charm_all(
rid: String
): ResponseData<Any> = request {
LiveApiServer.api.clear_user_charm_all(rid)
}
suspend fun get_room_user_vip(
rid: String
): ResponseData<RoomUserVip> = request {
LiveApiServer.api.get_room_user_vip(rid)
}
suspend fun player_index(): ResponseData<GameCategoryListBean> = request {
LiveApiServer.api.player_index()
}
suspend fun user_edit_room(
map: MutableMap<String, String>
): ResponseData<Any> = request {
LiveApiServer.api.user_edit_room(map)
}
suspend fun room_owner_down_micro(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.room_owner_down_micro(rid, uid)
}
suspend fun room_owner_up_micro(
rid: String, uid: String, micro_id: String, time: String
): ResponseData<Any> = request {
LiveApiServer.api.room_owner_up_micro(rid, uid, micro_id,time)
}
suspend fun date_user_send_gift(
rid: String,
receive_uid: String,
): ResponseData<Any> = request {
LiveApiServer.api.date_user_send_gift(rid, receive_uid)
}
suspend fun out_room(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.out_room(rid, uid)
}
suspend fun get_user_world_status(
rid: String
): ResponseData<UserWorldStatus> = request {
LiveApiServer.api.get_user_world_status(rid)
}
suspend fun exec_room_user_black(
rid: String,
uid: String,
status: String,
): ResponseData<Any> = request {
LiveApiServer.api.exec_room_user_black(rid, uid, status)
}
suspend fun check_user_is_real(
): ResponseData<CheckRealBean> = request {
LiveApiServer.api.check_user_is_real()
}
suspend fun unlock_user_micro(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.unlock_user_micro(rid, uid)
}
suspend fun unlock_user_world(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.unlock_user_world(rid, uid)
}
suspend fun get_room_admin_list(
rid: String, uid: String
): ResponseData<RoomAdminList> = request {
LiveApiServer.api.get_room_admin_list(rid, uid)
}
suspend fun get_room_super_admin_list(
rid: String, uid: String
): ResponseData<RoomAdminList> = request {
LiveApiServer.api.get_room_super_admin_list(rid, uid)
}
suspend fun get_user_withdrawal_info(): ResponseData<MoneyBean> = request {
LiveApiServer.api.get_user_withdrawal_info()
}
suspend fun europe_key_num(): ResponseData<MoneyBean> = request {
LiveApiServer.api.europe_key_num()
}
suspend fun unset_room_admin(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.unset_room_admin(rid, uid)
}
suspend fun set_room_admin(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.set_room_admin(rid, uid)
}
suspend fun lock_user_micro(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.lock_user_micro(rid, uid)
}
suspend fun lock_user_world(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.lock_user_world(rid, uid)
}
suspend fun is_open_box(rid: String): ResponseData<IsOpenBean> = request {
LiveApiServer.api.is_open_box(rid)
}
suspend fun get_room_user_list(
rid: String
): ResponseData<RoomUserList> = request {
LiveApiServer.api.get_room_user_list(rid)
}
suspend fun set_room_super_admin(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.set_room_super_admin(rid, uid)
}
suspend fun unset_room_super_admin(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.unset_room_super_admin(rid, uid)
}
suspend fun lock_room(
rid: String
): ResponseData<Any> = request {
LiveApiServer.api.lock_room(rid)
}
suspend fun unlock_room(
rid: String
): ResponseData<Any> = request {
LiveApiServer.api.unlock_room(rid)
}
suspend fun launch_room_pk(
rid: String, pk_type: String, pk_theme: String, pk_time: String
): ResponseData<Any> = request {
LiveApiServer.api.launch_room_pk(rid, pk_type, pk_theme, pk_time)
}
suspend fun close_room_pk_by_rid(rid: String): ResponseData<Any> = request {
LiveApiServer.api.close_room_pk_by_rid(rid)
}
suspend fun get_room_pk_info(rid: String): ResponseData<SocketPkData> = request {
LiveApiServer.api.get_room_pk_info(rid)
}
suspend fun get_room_pk_list(
rid: String,
page: String,
): ResponseData<List<PKRecordBean>> = request {
LiveApiServer.api.get_room_pk_list(rid, page, "20")
}
suspend fun chat_hall_info(): ResponseData<SocketChatHallInfo> = request {
LiveApiServer.api.chat_hall_info()
}
suspend fun user_chat_hall_top(
price: String, content: String
): ResponseData<Any> = request {
LiveApiServer.api.user_chat_hall_top(price, content)
}
suspend fun chat_hall_top(): ResponseData<SocketChatHallInfo> = request {
LiveApiServer.api.chat_hall_top()
}
suspend fun song_list(
name: String, page: String, page_limit: String
): ResponseData<List<SongListBean>> = request {
LiveApiServer.api.song_list(name, page, page_limit)
}
suspend fun dot_song_list(rid: String): ResponseData<List<SocketSong>> = request {
LiveApiServer.api.dot_song_list(rid)
}
suspend fun dot_song(
rid: String, song_code: String, is_accapella: String
): ResponseData<Any> = request {
LiveApiServer.api.dot_song(rid, song_code, is_accapella);
}
suspend fun apply_room_micro(rid: String): ResponseData<Any> = request {
LiveApiServer.api.apply_room_micro(rid)
}
suspend fun get_room_micro_list(rid: String): ResponseData<SocketAisleBean> = request {
LiveApiServer.api.get_room_micro_list(rid)
}
suspend fun get_dating_room_micro_list(rid: String): ResponseData<SocketAisleBean> = request {
LiveApiServer.api.get_dating_room_micro_list(rid)
}
suspend fun operate_user_micro(
rid: String, id: String, type: String, seat: String,time:String
): ResponseData<Any> = request {
LiveApiServer.api.operate_user_micro(rid, id, type, seat,time)
}
suspend fun unapply_room_micro(
rid: String,
id: String,
): ResponseData<Any> = request {
LiveApiServer.api.unapply_room_micro(rid, id)
}
suspend fun open_heartbeat_line(rid: String): ResponseData<Any> = request {
LiveApiServer.api.open_heartbeat_line(rid)
}
suspend fun end_heartbeat_line(rid: String): ResponseData<Any> = request {
LiveApiServer.api.end_heartbeat_line(rid)
}
suspend fun end_push_binding_relation(rid: String): ResponseData<Any> = request {
LiveApiServer.api.end_push_binding_relation(rid)
}
suspend fun room_game_start(rid: String, game_id: String): ResponseData<Any> = request {
LiveApiServer.api.room_game_start(rid, game_id)
}
suspend fun room_game_end(rid: String): ResponseData<Any> = request {
LiveApiServer.api.room_game_end(rid)
}
suspend fun prepare_stage(rid: String): ResponseData<Any> = request {
LiveApiServer.api.prepare_stage(rid)
}
suspend fun choose_love_stage(rid: String): ResponseData<Any> = request {
LiveApiServer.api.choose_love_stage(rid)
}
suspend fun close_xq_activity(rid: String): ResponseData<Any> = request {
LiveApiServer.api.close_xq_activity(rid)
}
suspend fun modify_room_info(rid: String,cate_id:String): ResponseData<Any> = request {
LiveApiServer.api.modify_room_info(rid,cate_id)
}
suspend fun tease_all_send_gift(
rid: String,
to_uid_list: String,
): ResponseData<Any> = request {
LiveApiServer.api.tease_all_send_gift(rid, to_uid_list)
}
suspend fun tease_user_send_gift(
rid: String,
receive_uid: String,
): ResponseData<Any> = request {
LiveApiServer.api.tease_user_send_gift(rid, receive_uid)
}
suspend fun wish_gift_info(
rid: String,
receive_uid: String,
): ResponseData<WishGiftInfo> = request {
LiveApiServer.api.wish_gift_info(rid, receive_uid)
}
suspend fun get_wish_gift_list(): ResponseData<ArrayList<GiftsBean>> = request {
LiveApiServer.api.get_wish_gift_list("1", "1000")
}
suspend fun operate_room_owner_up_micro(
rid: String, id: String, micro_id: String, type: String
): ResponseData<Any> = request {
LiveApiServer.api.operate_room_owner_up_micro(rid, id, micro_id, type)
}
suspend fun oprate_user_wish_gift(
rid: String, micro_id: String, gid: String
): ResponseData<Any> = request {
LiveApiServer.api.oprate_user_wish_gift(rid, micro_id, gid)
}
suspend fun close_xq_light(rid: String): ResponseData<Any> = request {
LiveApiServer.api.close_xq_light(rid)
}
suspend fun show_xq_sf(rid: String): ResponseData<Any> = request {
LiveApiServer.api.show_xq_sf(rid)
}
suspend fun user_room_light(rid: String,num: String,light_type:String): ResponseData<Any> = request {
LiveApiServer.api.user_room_light(rid,num,light_type)
}
suspend fun xq_appoint_gift(type:String): ResponseData<List<GiftLoveBean>> = request {
LiveApiServer.api.xq_appoint_gift(type)
}
suspend fun xq_pd(receive_uid:String,rid:String): ResponseData<Any> = request {
LiveApiServer.api.xq_pd(receive_uid,rid)
}
suspend fun ju_guang_light(rid:String,micro_id:String,status:String): ResponseData<Any> = request {
LiveApiServer.api.ju_guang_light(rid,micro_id,status)
}
suspend fun xq_reverse_send_gift(rid:String,close_uid:String,gid:String,num:String): ResponseData<Any> = request {
LiveApiServer.api.xq_reverse_send_gift(rid,close_uid,gid,num)
}
suspend fun get_relation_list(type:String): ResponseData<List<RelationListBean>> = request {
LiveApiServer.api.get_relation_list(type)
}
suspend fun binding_user_relation(
rid: String,
user_id: String,
receive_uid: String,
id: String,
): ResponseData<Any> = request {
LiveApiServer.api.binding_user_relation(rid, user_id, receive_uid, id)
}
suspend fun add_heartbeat_line_duration(
rid: String, duration: String
): ResponseData<Any> = request {
LiveApiServer.api.add_heartbeat_line_duration(rid, duration)
}
suspend fun get_truth_or_dare_list(prid: String): ResponseData<SocketPrivateCard> = request {
LiveApiServer.api.get_truth_or_dare_list(prid)
}
suspend fun get_topic_card_list(prid: String): ResponseData<SocketPrivateCard> = request {
LiveApiServer.api.get_topic_card_list(prid)
}
suspend fun get_room_host_list(rid: String): ResponseData<RoomHostListBean> = request {
LiveApiServer.api.get_room_host_list(rid)
}
suspend fun set_room_host(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.set_room_host(rid, uid)
}
suspend fun unset_room_host(
rid: String, uid: String
): ResponseData<Any> = request {
LiveApiServer.api.unset_room_host(rid, uid)
}
suspend fun send_gift_user_micro_help(
rid: String, help_uid: String, gid: String, num: String
): ResponseData<Any> = request {
LiveApiServer.api.send_gift_user_micro_help(rid, help_uid, gid, num)
}
suspend fun get_help_gift_list(
page: String, page_limit: String
): ResponseData<List<GiftsBean>> = request {
LiveApiServer.api.get_help_gift_list(page, page_limit)
}
suspend fun operate_room_help_gift(
rid: String, gid: String
): ResponseData<Any> = request {
LiveApiServer.api.operate_room_help_gift(rid, gid)
}
suspend fun get_cp_rank(
page: String, page_limit: String, time: String
): ResponseData<CPListBean> = request {
LiveApiServer.api.get_cp_rank(page, page_limit, time)
}
suspend fun user_agree_up_micro(
rid: String, micro_id: String, type: String
): ResponseData<Any> = request {
LiveApiServer.api.user_agree_up_micro(rid, micro_id, type)
}
suspend fun get_room_auction_price_list(): ResponseData<List<AuctionPriceListItem>> = request {
LiveApiServer.api.get_room_auction_price_list()
}
suspend fun user_auction_price(rid: String, price: String): ResponseData<Any> = request {
LiveApiServer.api.user_auction_price(rid, price)
}
suspend fun new_open_auction(rid: String): ResponseData<Any> = request {
LiveApiServer.api.new_open_auction(rid)
}
suspend fun finish_auction(rid: String): ResponseData<Any> = request {
LiveApiServer.api.finish_auction(rid)
}
suspend fun get_privacy_room_info(prid: String): ResponseData<PrivacyRoomInfoBean> = request {
LiveApiServer.api.get_privacy_room_info(prid)
}
suspend fun dating_send_gift(
prid: String, receive_uid: String, gid: String, num: String
): ResponseData<Any> = request {
LiveApiServer.api.dating_send_gift(prid, receive_uid, gid, num)
}
suspend fun end_room_privacy(prid: String): ResponseData<Any> = request {
LiveApiServer.api.end_room_privacy(prid)
}
suspend fun get_user_contract_list(
uid: String, page: String, page_limit: String
): ResponseData<List<SignedArtistBean>> = request {
LiveApiServer.api.get_user_contract_list(uid, page, page_limit)
}
suspend fun get_rooms_rank(time: String): ResponseData<RankBean> = request {
LiveApiServer.api.get_rooms_rank(time)
}
suspend fun get_day_list(): ResponseData<List<RelationTimeBean>> = request {
LiveApiServer.api.get_day_list()
}
suspend fun get_gift_list(): ResponseData<List<GiftsBean>> = request {
LiveApiServer.api.get_gift_list()
}
suspend fun options_user_auction_info(
rid: String, relation_id: String, gid: String, day: String
): ResponseData<Any> = request {
LiveApiServer.api.options_user_auction_info(rid, relation_id, gid, day)
}
suspend fun auction_open_auction(rid: String): ResponseData<Any> = request {
LiveApiServer.api.auction_open_auction(rid)
}
suspend fun get_auction_info(rid: String): ResponseData<AuctionBidGiftsBean> = request {
LiveApiServer.api.get_auction_info(rid)
}
suspend fun auction_finish_auction(rid: String): ResponseData<Any> = request {
LiveApiServer.api.auction_finish_auction(rid)
}
suspend fun add_auction_time(rid: String): ResponseData<Any> = request {
LiveApiServer.api.add_auction_time(rid)
}
suspend fun auction_room_rank(rid: String, page: String, page_limit: String): ResponseData<List<AuctionRankBean>> = request {
LiveApiServer.api.auction_room_rank(rid, page, page_limit)
}
suspend fun ktv_open_auction(rid: String): ResponseData<Any> = request {
LiveApiServer.api.ktv_open_auction(rid)
}
suspend fun user_auction_price(
rid: String, user_id: String, price: String
): ResponseData<Any> = request {
LiveApiServer.api.user_auction_price(rid, user_id, price);
}
suspend fun ktv_finish_auction(
rid: String, user_id: String
): ResponseData<Any> = request {
LiveApiServer.api.ktv_finish_auction(rid, user_id)
}
suspend fun dot_song_del(
rid: String, user_id: String
): ResponseData<Any> = request {
LiveApiServer.api.dot_song_del(rid, user_id)
}
suspend fun get_room_micro_charm_list(
rid: String, user_id: String
): ResponseData<List<OtherUserBean>> = request {
LiveApiServer.api.get_room_micro_charm_list(rid, user_id)
}
suspend fun get_room_host_info(rid: String): ResponseData<List<RoomSetHostListBean>> = request {
LiveApiServer.api.get_room_host_info(rid)
}
suspend fun update_room_host_ratio(
rid: String, uid: String, ratio: String
): ResponseData<Any> = request {
LiveApiServer.api.update_room_host_ratio(rid, uid, ratio)
}
suspend fun get_room_user_subsidy_list(rid: String): ResponseData<RoomUserSubsidyListBean> =
request {
LiveApiServer.api.get_room_user_subsidy_list(rid)
}
suspend fun user_search(
rid: String, keywords: String
): ResponseData<List<RankListBean>> = request {
LiveApiServer.api.user_search(rid, keywords)
}
suspend fun add_room_user_subsidy(
rid: String, uid: String, ratio: String
): ResponseData<Any> = request {
LiveApiServer.api.add_room_user_subsidy(rid, uid, ratio)
}
suspend fun update_room_user_subsidy(
rid: String, uid: String, ratio: String
): ResponseData<Any> = request {
LiveApiServer.api.update_room_user_subsidy(rid, uid, ratio)
}
suspend fun del_room_user_subsidy(
rid: String, id: String
): ResponseData<Any> = request {
LiveApiServer.api.del_room_user_subsidy(rid, id)
}
suspend fun get_room_pendant_gift_info(rid: String): ResponseData<SocketBindHeartLine> =
request {
LiveApiServer.api.get_room_pendant_gift_info(rid)
}
suspend fun clears_room_micro_list(rid: String): ResponseData<Any> = request {
LiveApiServer.api.clears_room_micro_list(rid)
}
suspend fun get_user_unillume_gift_wall(
user_id: String, page: String, page_limit: String
): ResponseData<List<UserGiftList>> = request {
LiveApiServer.api.get_user_unillume_gift_wall(user_id, page, page_limit)
}
suspend fun get_user_illume_gift_wall(
user_id: String, page: String, page_limit: String
): ResponseData<List<UserGiftList>> = request {
LiveApiServer.api.get_user_illume_gift_wall(user_id, page, page_limit)
}
suspend fun get_user_relation_list(
user_id: String, page: String, page_limit: String
): ResponseData<UserChumBean> = request {
LiveApiServer.api.get_user_relation_list(user_id, page, page_limit)
}
suspend fun get_room_new_auction_rank(rid: String): ResponseData<NewsComerRankBean> = request {
LiveApiServer.api.get_room_new_auction_rank(rid)
}
suspend fun get_room_is_earnings_info(rid: String): ResponseData<IsEarnings> = request {
LiveApiServer.api.get_room_is_earnings_info(rid)
}
suspend fun get_monster_info(): ResponseData<SpriteMonsterInfo> = request {
LiveApiServer.api.get_monster_info()
}
suspend fun get_monster_info_box(): ResponseData<MonsterInfoBean> = request {
LiveApiServer.api.get_monster_info_box()
}
suspend fun exchange_airship(
rid: String,
num: String,
): ResponseData<SpriteExchangeInfo> = request {
LiveApiServer.api.exchange_airship(rid, num)
}
suspend fun open_explore_star(
rid: String,
open_data: String,
): ResponseData<SpriteMonsterInfo> = request {
LiveApiServer.api.open_explore_star(rid, open_data)
}
suspend fun get_monster_box_list(): ResponseData<ArrayList<BoxJiangChiBean>> = request {
LiveApiServer.api.get_monster_box_list()
}
suspend fun get_monster_log(page: String, page_limit: String): ResponseData<ArrayList<MonsterLogBean>> = request {
LiveApiServer.api.get_monster_log(page, page_limit)
}
suspend fun get_monster_note(): ResponseData<String> = request {
LiveApiServer.api.get_monster_note()
}
suspend fun get_user_monster_rank():ResponseData<ArrayList<ShouQiBangBean>> =request {
LiveApiServer.api.get_user_monster_rank()
}
suspend fun user_send_trumpet(
rid: String,
pay_price: String,
content: String,
): ResponseData<Any> = request {
LiveApiServer.api.user_send_trumpet(rid, pay_price, content)
}
suspend fun get_trumpet_list(): ResponseData<SocketNotificationData> = request {
LiveApiServer.api.get_trumpet_list()
}
suspend fun get_top_line_integral(): ResponseData<TopLineBean> = request {
LiveApiServer.api.get_top_line_integral()
}
suspend fun last_week_rank(): ResponseData<ArrayList<GiftWeekRankData>> = request {
LiveApiServer.api.last_week_rank()
}
suspend fun week_star_gift_list(): ResponseData<ArrayList<WeekStartGiftData>> = request {
LiveApiServer.api.week_star_gift_list()
}
suspend fun now_week_rank(gid:String): ResponseData<NowGiftWeekRankData> = request {
LiveApiServer.api.now_week_rank(gid)
}
suspend fun get_motian_rank(gid:String): ResponseData<ArrayList<MtlRankGiftData>> = request {
LiveApiServer.api.get_motian_rank(gid)
}
suspend fun del_user_relation(
user_relation_id: String,
): ResponseData<Any> = request {
LiveApiServer.api.del_user_relation(user_relation_id)
}
suspend fun get_new_box_win_user(
box_type: String,
page: String,
): ResponseData<List<Box4ResultBeanItem>> = request {
LiveApiServer.api.get_new_box_win_user(box_type, page, "20")
}
suspend fun open_new_box(
rid: String,
nbl_id: String,
pay_amount: String
): ResponseData<BoxListBean> = request {
LiveApiServer.api.open_new_box(rid, nbl_id, pay_amount)
}
suspend fun get_new_box_note(): ResponseData<Box4Note> = request {
LiveApiServer.api.get_new_box_note()
}
suspend fun get_my_new_box_log(
box_type: String,
type: String,
page: String,
): ResponseData<List<BoxOpenCJBean>> = request {
LiveApiServer.api.get_my_new_box_log(box_type, type, page, "20")
}
suspend fun get_new_box_list(): ResponseData<BoxListBean> = request {
LiveApiServer.api.get_new_box_list()
}
suspend fun open_beat_monster(
rid: String,
type: String,
num: String
): ResponseData<MonsterResultBean> = request {
LiveApiServer.api.open_beat_monster(rid, type, num)
}
suspend fun get_user_monster_log(page: String): ResponseData<ArrayList<MonsterUserLogBean>> =
request {
LiveApiServer.api.get_user_monster_log(page)
}
suspend fun blind_box_init(
to_uid: String,
gid: String
): ResponseData<BlindBoxInitBean> = request {
LiveApiServer.api.blind_box_init(to_uid, gid)
}
suspend fun get_blind_box_note(): ResponseData<String> = request {
LiveApiServer.api.get_blind_box_note()
}
suspend fun get_blind_box_win_log(
page: String,
page_limit: String = "20"
): ResponseData<ArrayList<BlindBoxRecordBean>> = request {
LiveApiServer.api.get_blind_box_win_log(page, page_limit)
}
suspend fun get_blind_box_rank(
time_type: String,
page: String,
page_limit: String = "20"
): ResponseData<ArrayList<BlindBoxRankBean>> = request {
LiveApiServer.api.get_blind_box_rank(time_type, page, page_limit)
}
}

View File

@@ -0,0 +1,448 @@
package com.yuyin.module_live.rtc
import io.agora.mediaplayer.Constants
import io.agora.mediaplayer.IMediaPlayer
import io.agora.musiccontentcenter.IAgoraMusicContentCenter
import io.agora.musiccontentcenter.Music
import io.agora.musiccontentcenter.MusicChartInfo
import io.agora.rtc2.IRtcEngineEventHandler
import io.agora.rtc2.RtcEngine
/**
* KTV场景类型
* @param Normal 普通独唱或多人合唱
* @param SingBattle 嗨歌抢唱
*/
enum class KTVType(val value: Int) {
Normal(0),
SingBattle(1)
}
/**
* 在KTVApi中的身份
* @param SoloSinger 独唱者: 当前只有自己在唱歌
* @param CoSinger 合唱者: 加入合唱需要通过调用switchSingerRole将切换身份成合唱
* @param LeadSinger 主唱: 有合唱者加入后需要通过调用switchSingerRole切换身份成主唱
* @param Audience 观众: 默认状态
*/
enum class KTVSingRole(val value: Int) {
SoloSinger(0),
CoSinger(1),
LeadSinger(2),
Audience(3)
}
/**
* loadSong失败的原因
* @param NO_LYRIC_URL 没有歌词,不影响音乐正常播放
* @param MUSIC_PRELOAD_FAIL 音乐加载失败
* @param CANCELED 本次加载已终止
*/
enum class KTVLoadSongFailReason(val value: Int) {
NO_LYRIC_URL(0),
MUSIC_PRELOAD_FAIL(1),
CANCELED(2)
}
/**
* switchSingerRole的失败的原因
* @param JOIN_CHANNEL_FAIL 加入channel2失败
* @param NO_PERMISSION switchSingerRole传入了错误的目标角色不能从当前角色切换到目标角色
*/
enum class SwitchRoleFailReason(val value: Int) {
JOIN_CHANNEL_FAIL(0),
NO_PERMISSION(1)
}
/**
* 加载音乐的模式
* @param LOAD_MUSIC_ONLY 只加载音乐(通常加入合唱前使用此模式)
* @param LOAD_LRC_ONLY 只加载歌词(通常歌曲开始播放时观众使用此模式)
* @param LOAD_MUSIC_AND_LRC 默认模式,加载歌词和音乐(通常歌曲开始播放时主唱使用此模式)
*/
enum class KTVLoadMusicMode(val value: Int) {
LOAD_NONE(-1),
LOAD_MUSIC_ONLY(0),
LOAD_LRC_ONLY(1),
LOAD_MUSIC_AND_LRC(2)
}
/**
* 加载音乐的状态
* @param COMPLETED 加载完成, 进度为100
* @param FAILED 加载失败
* @param INPROGRESS 加载中
*/
enum class MusicLoadStatus(val value: Int) {
COMPLETED(0),
FAILED(1),
INPROGRESS(2),
}
/**
* 歌词组件接口您setLrcView传入的歌词组件需要继承此接口类并实现以下三个方法
*/
interface ILrcView {
/**
* ktvApi内部更新音高pitch时会主动调用此方法将pitch值传给你的歌词组件
* @param pitch 音高值
*/
fun onUpdatePitch(pitch: Float?)
/**
* ktvApi内部更新音乐播放进度progress时会主动调用此方法将进度值progress传给你的歌词组件50ms回调一次
* @param progress 歌曲播放的真实进度 20ms回调一次
*/
fun onUpdateProgress(progress: Long?)
/**
* ktvApi获取到歌词地址时会主动调用此方法将歌词地址url传给你的歌词组件您需要在这个回调内完成歌词的下载
*/
fun onDownloadLrcData(url: String?)
/**
* ktvApi获取到抢唱切片歌曲副歌片段时间时会调用此方法回调给歌词组件
*/
fun onHighPartTime(highStartTime: Long, highEndTime: Long)
}
/**
* 音乐加载状态接口
*/
interface IMusicLoadStateListener {
/**
* 音乐加载成功
* @param songCode 歌曲编码, 和你loadMusic传入的songCode一致
* @param lyricUrl 歌词地址
*/
fun onMusicLoadSuccess(songCode: Long, lyricUrl: String)
/**
* 音乐加载失败
* @param reason 歌曲加载失败的原因
*/
fun onMusicLoadFail(songCode: Long, reason: KTVLoadSongFailReason)
/**
* 音乐加载进度
* @param songCode 歌曲编码
* @param percent 歌曲加载进度
* @param status 歌曲加载的状态
* @param msg
* @param lyricUrl
*/
fun onMusicLoadProgress(songCode: Long, percent: Int, status: MusicLoadStatus, msg: String?, lyricUrl: String?)
}
/**
* 切换演唱角色状态接口
*/
interface ISwitchRoleStateListener {
/**
* 切换演唱角色成功
*/
fun onSwitchRoleSuccess()
/**
* 切换演唱角色失败
* @param reason 切换演唱角色失败的原因
*/
fun onSwitchRoleFail(reason: SwitchRoleFailReason)
}
/**
* KTVApi事件回调
*/
abstract class IKTVApiEventHandler {
/**
* 播放器状态变化
* @param state MediaPlayer 播放状态
* @param error MediaPlayer Error 信息
* @param isLocal 本地还是主唱端的 Player 信息
*/
open fun onMusicPlayerStateChanged(
state: Constants.MediaPlayerState, error: Constants.MediaPlayerError, isLocal: Boolean
) {
}
/**
* ktvApi内部角色切换
* @param oldRole 老角色
* @param newRole 新角色
*/
open fun onSingerRoleChanged(oldRole: KTVSingRole, newRole: KTVSingRole) {}
/**
* rtm或合唱频道token将要过期回调需要renew这个token
*/
open fun onTokenPrivilegeWillExpire() {}
/**
* 合唱频道人声音量提示
* @param speakers 不同用户音量信息
* @param totalVolume 总音量
*/
open fun onChorusChannelAudioVolumeIndication(
speakers: Array<out IRtcEngineEventHandler.AudioVolumeInfo>?,
totalVolume: Int) {}
}
/**
* 初始化KTVApi的配置
* @param appId 用来初始化 Mcc Engine
* @param rtmToken 创建 Mcc Engine 需要
* @param engine RTC engine 对象
* @param channelName 频道号,子频道名以基于主频道名 + "_ex" 固定规则生成频道号
* @param localUid 创建 Mcc engine 和 加入子频道需要用到
* @param chorusChannelName 子频道名 加入子频道需要用到
* @param chorusChannelToken 子频道token 加入子频道需要用到
* @param maxCacheSize 最大缓存歌曲数
* @param type KTV场景
*/
data class KTVApiConfig(
val appId: String,
val rtmToken: String,
val engine: RtcEngine,
val channelName: String,
val localUid: Int,
val chorusChannelName: String,
val chorusChannelToken: String,
val maxCacheSize: Int = 10,
val type: KTVType = KTVType.Normal
)
/**
* 加载歌曲的配置不允许在一首歌没有load完成前成功/失败均算完成)进行下一首歌的加载
* @param autoPlay 是否自动播放歌曲通常主唱选择true默认为false
* @param mode 歌曲加载的模式, 默认为音乐和歌词均加载
* @param songCode 歌曲 id
* @param mainSingerUid 主唱的 Uid如果是伴唱伴唱需要根据这个信息 mute 主频道主唱的声音
*/
data class KTVLoadMusicConfiguration(
val songIdentifier: String,
val autoPlay: Boolean = false,
val mainSingerUid: Int,
val mode: KTVLoadMusicMode = KTVLoadMusicMode.LOAD_MUSIC_AND_LRC
)
interface KTVApi {
/**
* 初始化内部变量/缓存数据并注册相应的监听必须在其他KTVApi调用前调用initialize初始化KTVApi
* @param config 初始化KTVApi的配置
*/
fun initialize(config: KTVApiConfig)
/**
* 更新ktvapi内部使用的streamId每次加入频道需要更新内部streamId
*/
fun renewInnerDataStreamId()
/**
* 订阅KTVApi事件, 支持多注册
* @param ktvApiEventHandler KTVApi事件接口实例
*/
fun addEventHandler(ktvApiEventHandler: IKTVApiEventHandler)
/**
* 取消订阅KTVApi事件
* @param ktvApiEventHandler KTVApi事件接口实例
*/
fun removeEventHandler(ktvApiEventHandler: IKTVApiEventHandler)
/**
* 清空内部变量/缓存取消在initWithRtcEngine时的监听以及取消网络请求等
*/
fun release()
/**
* 收到 IKTVApiEventHandler.onTokenPrivilegeWillExpire 回调时需要主动调用方法更新Token
* @param rtmToken musicContentCenter模块需要的rtm token
* @param chorusChannelRtcToken 合唱需要的频道rtc token
*/
fun renewToken(
rtmToken: String,
chorusChannelRtcToken: String
)
/**
* 获取歌曲榜单
* @param onMusicChartResultListener 榜单列表回调
*/
fun fetchMusicCharts(
onMusicChartResultListener: (
requestId: String?, // TODO 不需要?
status: Int, // status=2 时token过期
list: Array<out MusicChartInfo>?
) -> Unit
)
/**
* 根据歌曲榜单类型获取歌单
* @param musicChartId 榜单id
* @param page 歌曲列表回调
* @param pageSize 歌曲列表回调
* @param jsonOption 自定义过滤模式
* @param onMusicCollectionResultListener 歌曲列表回调
*/
fun searchMusicByMusicChartId(
musicChartId: Int,
page: Int,
pageSize: Int,
jsonOption: String,
onMusicCollectionResultListener: (
requestId: String?, // TODO 不需要?
status: Int, // status=2 时token过期
page: Int,
pageSize: Int,
total: Int,
list: Array<out Music>?
) -> Unit
)
/**
* 根据关键字搜索歌曲
* @param keyword 关键字
* @param page 歌曲列表回调
* @param jsonOption 自定义过滤模式
* @param onMusicCollectionResultListener 歌曲列表回调
*/
fun searchMusicByKeyword(
keyword: String,
page: Int, pageSize: Int,
jsonOption: String,
onMusicCollectionResultListener: (
requestId: String?, // TODO 不需要?
status: Int, // status=2 时token过期
page: Int,
pageSize: Int,
total: Int,
list: Array<out Music>?
) -> Unit
)
/**
* 异步加载歌曲同时只能为一首歌loadSongloadSong结果会通过回调通知业务层
* @param songCode 歌曲唯一编码
* @param config 加载歌曲配置
* @param musicLoadStateListener 加载歌曲结果回调
*
* 推荐调用:
* 歌曲开始时:
* 主唱 loadMusic(KTVLoadMusicConfiguration(autoPlay=true, mode=LOAD_MUSIC_AND_LRC, songCode, mainSingerUid)) switchSingerRole(SoloSinger)
* 观众 loadMusic(KTVLoadMusicConfiguration(autoPlay=false, mode=LOAD_LRC_ONLY, songCode, mainSingerUid))
* 加入合唱时:
* 准备加入合唱者loadMusic(KTVLoadMusicConfiguration(autoPlay=false, mode=LOAD_MUSIC_ONLY, songCode, mainSingerUid))
* loadMusic成功后switchSingerRole(CoSinger)
*/
fun loadMusic(
songCode: Long,
config: KTVLoadMusicConfiguration,
musicLoadStateListener: IMusicLoadStateListener
)
/**
* 加载歌曲同时只能为一首歌loadSong同步调用 一般使用此loadSong是歌曲已经preload成功url为本地文件地址
* @param config 加载歌曲配置
* @param url 歌曲地址
*
* 推荐调用:
* 歌曲开始时:
* 主唱 loadMusic(KTVLoadMusicConfiguration(autoPlay=true, mode=LOAD_MUSIC_AND_LRC, url, mainSingerUid)) switchSingerRole(SoloSinger)
* 观众 loadMusic(KTVLoadMusicConfiguration(autoPlay=false, mode=LOAD_LRC_ONLY, url, mainSingerUid))
* 加入合唱时:
* 准备加入合唱者loadMusic(KTVLoadMusicConfiguration(autoPlay=false, mode=LOAD_MUSIC_ONLY, url, mainSingerUid))
* loadMusic成功后switchSingerRole(CoSinger)
*/
fun loadMusic(
url: String,
config: KTVLoadMusicConfiguration
)
/**
* 异步切换演唱身份,结果会通过回调通知业务层
* @param newRole 新演唱身份
* @param switchRoleStateListener 切换演唱身份结果
*
* 允许的调用路径:
* 1、Audience -》SoloSinger 自己点的歌播放时
* 2、Audience -》LeadSinger 自己点的歌播放时, 且歌曲开始时就有合唱者加入
* 3、SoloSinger -》Audience 独唱结束时
* 4、Audience -》CoSinger 加入合唱时
* 5、CoSinger -》Audience 退出合唱时
* 6、SoloSinger -》LeadSinger 当前第一个合唱者加入合唱时,主唱由独唱切换成领唱
* 7、LeadSinger -》SoloSinger 最后一个合唱者退出合唱时,主唱由领唱切换成独唱
* 8、LeadSinger -》Audience 以领唱的身份结束歌曲时
*/
fun switchSingerRole(
newRole: KTVSingRole,
switchRoleStateListener: ISwitchRoleStateListener?
)
/**
* 播放歌曲
* @param songCode 歌曲唯一编码
* @param startPos 开始播放的位置
* 对于主唱:
* 如果loadMusic时你选择了autoPlay = true 则不需要主动调用startSing
* 如果loadMusic时你选择了autoPlay = false 则需要在loadMusic成功后调用startSing
*/
fun startSing(songCode: Long, startPos: Long)
/**
* 播放歌曲
* @param url 歌曲地址
* @param startPos 开始播放的位置
* 对于主唱:
* 如果loadMusic时你选择了autoPlay = true 则不需要主动调用startSing
* 如果loadMusic时你选择了autoPlay = false 则需要在loadMusic成功后调用startSing
*/
fun startSing(url: String, startPos: Long)
/**
* 恢复播放
*/
fun resumeSing()
/**
* 暂停播放
*/
fun pauseSing()
fun stopMusic()
/**
* 调整进度
*/
fun seekSing(time: Long)
/**
* 设置歌词组件,在任意时机设置都可以生效
* @param view 传入的歌词组件view 需要继承ILrcView并实现ILrcView的三个接口
*/
fun setLrcView(view: ILrcView)
/**
* 设置当前mic开关状态
* 目前关麦调用 adjustRecordSignalVolume(0) 后 onAudioVolumeIndication 仍然会执行, ktvApi需要增加一个变量判断当前是否关麦 如果关麦把设置给歌词组件的pitch改为0
*/
fun setMicStatus(isOnMicOpen: Boolean)
/**
* 设置当前音频播放delay 适用于音频自采集的情况
* @param audioPlayoutDelay 音频帧处理和播放的时间差
*/
fun setAudioPlayoutDelay(audioPlayoutDelay: Int)
/**
* 获取mpk实例
*/
fun getMediaPlayer() : IMediaPlayer
/**
* 获取mcc实例
*/
fun getMusicContentCenter() : IAgoraMusicContentCenter
fun loadData(code :Long)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
package com.yuyin.module_live.rtc
data class RoomSeatModel(
val isMaster: Boolean,// 是否是房主
val headUrl: String,// 头像
val userNo: String,// 座位上用户no
val rtcUid: String,// 座位上用户id与rtc的userId一致
val name: String,// 座位上用户昵称
val seatIndex: Int,// 座位编号
val chorusSongCode: String = "",// 是否合唱
val isAudioMuted: Int,// 是否静音
val isVideoMuted: Int,// 是否开启视频
) : java.io.Serializable {
companion object {
val MUTED_VALUE_TRUE = 1
}
}
data class RoomSelSongModel(
// 获取歌词列表返回的歌词信息
val songName: String = "",// 歌曲名
val songNo: String = "", // 歌词唯一标识
val singer: String = "", // 演唱者
val imageUrl: String = "",// 歌曲封面
// 获取已点歌记返回的歌词信息,同时也包含上面信息
val userNo: String? = null,// 点歌人No
val isOriginal: Int = 0, //是否原唱
// 排序字段
val status: Int, // 0 未开始 1.已唱 2.正在唱
val is_accapella: Int, // 是否清唱
)
data class ScoringAlgoControlModel(
val level: Int,
val offset: Int
)
data class ScoringAverageModel(
val isLocal: Boolean,
val score: Int
)

View File

@@ -0,0 +1,118 @@
package com.yuyin.module_live.rtc;
public class MusicSettingBean {
private final MusicSettingDialog.Callback mCallback;
private boolean isEar;
private int volMic;
private int volMusic;
private int effect;
private int beautifier = 0;
private int toneValue;
private int audioEffectParams1 = 0;
private int audioEffectParams2 = 0;
private int remoteVolume = 40;
private boolean isOriginal;
private int isPlay=-1;
public MusicSettingBean(boolean isEar, int volMic, int volMusic, MusicSettingDialog.Callback mCallback) {
this.isEar = isEar;
this.volMic = volMic;
this.volMusic = volMusic;
this.mCallback = mCallback;
}
public MusicSettingDialog.Callback getCallback() {
return mCallback;
}
public boolean isEar() {
return isEar;
}
public void setEar(boolean ear) {
isEar = ear;
mCallback.onEarChanged(ear);
}
public boolean isOriginal() {
return isOriginal;
}
public void setOriginal(boolean original) {
isOriginal = original;
mCallback.onOriginalChanged(original);
}
public int getVolMic() {
return volMic;
}
public void setVolMic(int volMic) {
this.volMic = volMic;
this.mCallback.onMicVolChanged(volMic);
}
public int getVolMusic() {
return volMusic;
}
public void setVolMusic(int volMusic) {
this.volMusic = volMusic;
this.mCallback.onMusicVolChanged(volMusic);
}
public int getEffect() {
return effect;
}
public void setEffect(int effect) {
this.effect = effect;
this.mCallback.onEffectChanged(effect);
}
public int getBeautifier() {
return beautifier;
}
public void setBeautifier(int beautifier) {
this.beautifier = beautifier;
this.mCallback.onBeautifierPresetChanged(beautifier);
}
public int getAudioEffectParams1() {
return audioEffectParams1;
}
public int getAudioEffectParams2() {
return audioEffectParams2;
}
public void setAudioEffectParameters(int params1, int params2) {
this.audioEffectParams1 = params1;
this.audioEffectParams2 = params2;
this.mCallback.setAudioEffectParameters(params1, params2);
}
public void playSong(int isPlay){
this.isPlay = isPlay;
this.mCallback.playSong(isPlay);
}
public void playSongHC(int isPlay){
this.isPlay = isPlay;
this.mCallback.playSongHC(isPlay);
}
public int isPlay() {
return isPlay;
}
public void setPlay(int play) {
isPlay = play;
}
}

View File

@@ -0,0 +1,143 @@
package com.yuyin.module_live.rtc;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import com.yuyin.lib_base.base.BaseBottomSheetDialogFragment;
import com.yuyin.module_live.R;
import com.yuyin.module_live.ui.adapter.ReverberationAdapter;
import com.yuyin.module_live.databinding.KtvDialogMusicSettingBinding;
import java.util.Arrays;
/**
* 控制台
*/
public class MusicSettingDialog extends BaseBottomSheetDialogFragment<KtvDialogMusicSettingBinding> {
public static final String TAG = "MusicSettingDialog";
private MusicSettingBean mSetting;
public MusicSettingDialog(MusicSettingBean mSetting) {
this.mSetting = mSetting;
}
@SuppressLint("SetTextI18n")
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewCompat.setOnApplyWindowInsetsListener(requireDialog().getWindow().getDecorView(), (v, insets) -> {
Insets inset = insets.getInsets(WindowInsetsCompat.Type.systemBars());
mBinding.getRoot().setPadding(inset.left, 0, inset.right, inset.bottom);
return WindowInsetsCompat.CONSUMED;
});
mBinding.switchOriginal.setChecked(this.mSetting.isOriginal());
mBinding.switchEar.setChecked(this.mSetting.isEar());
mBinding.sbVol1.setProgress(this.mSetting.getVolMic());
mBinding.sbVol2.setProgress(this.mSetting.getVolMusic());
setSoundMode();
if (mSetting.isPlay() == 0) {
mBinding.playSong.setText("暂停");
} else {
mBinding.playSong.setText("播放");
}
mBinding.switchEar.setOnCheckedChangeListener((buttonView, isChecked) -> this.mSetting.setEar(isChecked));
mBinding.switchOriginal.setOnCheckedChangeListener((buttonView, isChecked) -> {
this.mSetting.setOriginal(isChecked);
});
mBinding.sbVol1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mSetting.setVolMic(i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mBinding.sbVol2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mSetting.setVolMusic(i);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mBinding.playSong.setOnClickListener(v -> {
if (mSetting.isPlay() == 0) {
mSetting.playSong(1);
mBinding.playSong.setText("播放");
} else {
mSetting.playSong(0);
mBinding.playSong.setText("暂停");
}
dismiss();
});
}
private void setSoundMode() {
String[] stringArray = getResources().getStringArray(R.array.ktv_audioPreset);
mBinding.rvContainer.setLayoutManager(new GridLayoutManager(requireContext(), 4));
ReverberationAdapter reverberationAdapter = new ReverberationAdapter();
reverberationAdapter.setNewData(Arrays.asList(stringArray));
mBinding.rvContainer.setAdapter(reverberationAdapter);
reverberationAdapter.setSelectPosition(mSetting.getEffect());
reverberationAdapter.setOnItemClickListener((adapter, view, position) -> {
reverberationAdapter.setSelectPosition(position);
mSetting.setEffect(position);
});
}
public interface Callback {
void onEarChanged(boolean isEar);
void onOriginalChanged(boolean isOriginal);
void onMicVolChanged(int vol);
void onMusicVolChanged(int vol);
void onEffectChanged(int effect);
void onBeautifierPresetChanged(int effect);
void setAudioEffectParameters(int param1, int param2);
void playSong(int isPlay);
void playSongHC(int isPlay);
}
}

View File

@@ -0,0 +1,4 @@
package com.yuyin.module_live.rtc
class RTMViewModel {
}

View File

@@ -0,0 +1,192 @@
package com.yuyin.module_live.rtc;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.Gson;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMSendCallback;
import com.yuyin.lib_base.base.UserManager;
import com.yuyin.module_live.model.RoomMessageBean;
import static com.yuyin.lib_base.Const.ROOM_CHAT_PUBLIC_JOIN_ROOM;
/**
* 有关房间的操作均在此
*/
public class RoomManager {
public static RoomManager getInstance() {
return RoomManagerHelper.INSTANCE;
}
private static class RoomManagerHelper {
private static final RoomManager INSTANCE = new RoomManager();
}
private RoomManager() {
}
/**
* 主播退出房间
*/
public void micQuitRoom(String roomId) {
V2TIMManager.getInstance().quitGroup(roomId, new V2TIMCallback() {
@Override
public void onSuccess() {
// 退出群组成功
}
@Override
public void onError(int code, String desc) {
// 退出群组失败
}
});
}
/**
* 观众加入聊天室
*/
public void audienceJoinRoomMic(final String roomId,String zq_title,String contribution_level_image, String is_hide_enter_room) {
// 加入群组
V2TIMManager.getInstance().joinGroup(roomId, "", new V2TIMCallback() {
@Override
public void onSuccess() {
// 加入群组成功
LogUtils.e("观众加入群组成功");
RoomMessageBean roomMessageBean = new RoomMessageBean();
roomMessageBean.setMessageType(ROOM_CHAT_PUBLIC_JOIN_ROOM);
roomMessageBean.setMessage("进入直播间");
roomMessageBean.setZq_title(zq_title);
roomMessageBean.setContribution_level_image(contribution_level_image);
roomMessageBean.setUser_id(UserManager.INSTANCE.getUser().getUid() + "");
if (is_hide_enter_room.equals("1")) {
roomMessageBean.setNickName("神秘人");
} else {
roomMessageBean.setNickName(UserManager.INSTANCE.getUser().getNick_name());
}
sendChatRoomMessage(roomId, new Gson().toJson(roomMessageBean),0);
}
@Override
public void onError(int code, String desc) {
// 加入群组失败 如果加入失败 就创建新的
LogUtils.e(code, desc + "观众");
// createGroup(roomId);
}
});
}
public void audienceJoinRoomMic(final String roomId) {
// 加入群组
V2TIMManager.getInstance().joinGroup(roomId, "", new V2TIMCallback() {
@Override
public void onSuccess() {
// 加入群组成功
LogUtils.e("观众加入群组成功");
RoomMessageBean roomMessageBean = new RoomMessageBean();
roomMessageBean.setMessageType(ROOM_CHAT_PUBLIC_JOIN_ROOM);
roomMessageBean.setMessage("进入了直播间");
roomMessageBean.setUser_id(UserManager.INSTANCE.getUser().getUid() + "");
roomMessageBean.setNickName(UserManager.INSTANCE.getUser().getNick_name());
sendChatRoomMessage(roomId, new Gson().toJson(roomMessageBean),0);
}
@Override
public void onError(int code, String desc) {
// 加入群组失败 如果加入失败 就创建新的
LogUtils.e(code, desc + "观众");
// createGroup(roomId);
}
});
}
/**
* 赠送聊天礼物
*/
public void sendPrivateMessage3(String userID, String messageContent) {
// Gson gson = new Gson();
// CustomHelloMessage customLinkMessageBean = new CustomHelloMessage();
// customLinkMessageBean.text = messageContent;
// String data = gson.toJson(customLinkMessageBean);
// // 创建文本消息
// V2TIMManager.getInstance().sendC2CCustomMessage(data.getBytes(), userID, null);
}
public void sendPrivateMessage2(String userID, String messageContent) {
// V2TIMManager.getInstance().sendC2CTextMessage(messageContent, userID, null);
}
/**
* 发送聊天室消息
*/
public void sendPrivateMessage(String userID, String messageContent) {
// 创建文本消息
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(messageContent.getBytes());
// 发送消息
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, userID, null, V2TIMMessage.V2TIM_PRIORITY_NORMAL, true, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onProgress(int progress) {
// 文本消息不会回调进度
}
@Override
public void onSuccess(V2TIMMessage message) {
// 文本消息发送成功
LogUtils.e(message);
}
@Override
public void onError(int code, String desc) {
// 文本消息发送失败
LogUtils.e(code, desc);
}
});
}
/**
* 发送聊天室消息
*/
public void sendChatRoomMessage(String roomId, String messageContent,int type) {
// 创建自定义消息
V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(messageContent.getBytes());
// 发送消息
V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, null, roomId, V2TIMMessage.V2TIM_PRIORITY_NORMAL, false, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onProgress(int progress) {
// 自定义消息不会回调进度
}
@Override
public void onSuccess(V2TIMMessage message) {
// 发送群聊自定义消息成功
// LogUtils.e(message);
}
@Override
public void onError(int code, String desc) {
// 发送群聊自定义消息失败
LogUtils.e(code, desc);
if (code == 10016 && type == 1) {
ToastUtils.showShort(desc);
}
}
});
}
}

View File

@@ -0,0 +1,741 @@
package com.yuyin.module_live.rtc;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.yuyin.lib_base.App;
import com.yuyin.lib_base.base.BaseViewModel;
import com.yuyin.lib_base.base.UserManager;
import com.yuyin.lib_base.socket.SocketSong;
import com.yuyin.module_live.ui.room.RoomViewModel;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.agora.rtc2.ChannelMediaOptions;
import io.agora.rtc2.Constants;
import io.agora.rtc2.DataStreamConfig;
import io.agora.rtc2.IRtcEngineEventHandler;
import io.agora.rtc2.RtcEngine;
import io.agora.rtc2.RtcEngineConfig;
import io.agora.rtc2.RtcEngineEx;
public class RoomRTCViewModel extends BaseViewModel {
private final String TAG = "KTV_Scene_LOG";
private final KTVApi ktvApiProtocol = new KTVApiImpl();
RoomViewModel roomViewModel;
private RtcAudioVolumeIndication rtcAudioVolumeIndication;
public RoomRTCViewModel(RoomViewModel roomViewModel) {
this.roomViewModel = roomViewModel;
}
public enum PlayerMusicStatus {
ON_PREPARE, ON_PLAYING, ON_PAUSE, ON_STOP, ON_LRC_RESET, ON_CHANGING_START, ON_CHANGING_END
}
public final MutableLiveData<PlayerMusicStatus> playerMusicStatusLiveData = new MutableLiveData<>();
final int UID = (int) UserManager.INSTANCE.getUser().getUid();
public final MutableLiveData<String> agoraAppId = new MutableLiveData<>();
public final MutableLiveData<String> agoraToken = new MutableLiveData<>();
public final MutableLiveData<String> channelId = new MutableLiveData<>();
enum JoinChorusStatus {
ON_IDLE, ON_JOIN_CHORUS, ON_JOIN_FAILED, ON_LEAVE_CHORUS,
}
public class LineScore {
public int score;
public int index;
public int cumulativeScore;
public int total;
}
public String smrUid="";
/**
* Rtc引擎
*/
public RtcEngineEx mRtcEngine;
/**
* 主版本的音频设置
*/
private final ChannelMediaOptions mainChannelMediaOption = new ChannelMediaOptions();
/**
* 播放器配置
*/
public MusicSettingBean mSetting;
/**
* 是否开启后台播放
*/
private boolean isBackPlay = false;
/**
* 是否开启耳返
*/
private boolean isOpnEar = false;
/**
* 合唱人数
*/
public int chorusNum = 0;
/**
* 麦位信息
*/
boolean isOnSeat = false;
/**
* Player/RTC信息
*/
int streamId = 0;
final MutableLiveData<JoinChorusStatus> joinchorusStatusLiveData = new MutableLiveData<>();
final MutableLiveData<Boolean> noLrcLiveData = new MutableLiveData<>();
final MutableLiveData<Long> playerMusicOpenDurationLiveData = new MutableLiveData<>();
final MutableLiveData<ScoringAverageModel> playerMusicPlayCompleteLiveData = new MutableLiveData<>();
final MutableLiveData<Integer> playerMusicCountDownLiveData = new MutableLiveData<>();
// final MutableLiveData<NetWorkEvent> networkStatusLiveData = new MutableLiveData<>();
final MutableLiveData<ScoringAlgoControlModel> scoringAlgoControlLiveData = new MutableLiveData<>();
final MutableLiveData<List<RoomSeatModel>> seatListLiveData = new MutableLiveData<>(new ArrayList<>());
final MutableLiveData<RoomSeatModel> seatLocalLiveData = new MutableLiveData<>();
public final MutableLiveData<RoomRTCViewModel.LineScore> mainSingerScoreLiveData = new MutableLiveData<>();
/**
* 歌词信息
*/
final MutableLiveData<List<RoomSelSongModel>> songsOrderedLiveData = new MutableLiveData<>();
public final MutableLiveData<RoomSelSongModel> songPlayingLiveData = new MutableLiveData<>();
public void init() {
LogUtils.e("初始化成功");
agoraAppId.setValue(roomViewModel.getRoomInfo().getValue().getAgora_app_id());
agoraToken.setValue(roomViewModel.getRoomInfo().getValue().getAgora_token());
channelId.setValue(roomViewModel.getRoomInfo().getValue().getRid());
initRTCPlayer();
}
public void initDating() {
initRTCPlayer();
}
public boolean release() {
LogUtils.d(TAG, "release called");
streamId = 0;
if (mRtcEngine != null) {
ktvApiProtocol.release();
}
if (mRtcEngine != null) {
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_AUDIENCE);
mRtcEngine.enableLocalAudio(false);
mRtcEngine.enableInEarMonitoring(false, Constants.EAR_MONITORING_FILTER_NOISE_SUPPRESSION);
mRtcEngine.leaveChannel();
mRtcEngine = null;
return true;
}
return false;
}
/**
* 设置歌词view
*/
public void setLrcView(ILrcView view) {
ktvApiProtocol.setLrcView(view);
}
public void loadData(Long songCode) {
ktvApiProtocol.loadData(songCode);
}
// ======================= Player/RTC/MPK相关 =======================
private void initRTCPlayer() {
if (TextUtils.isEmpty(agoraAppId.getValue())) {
throw new NullPointerException("please check \"strings_config.xml\"");
}
if (mRtcEngine != null) return;
// ------------------ 初始化RTC ------------------
RtcEngineConfig config = new RtcEngineConfig();
config.mContext = App.Companion.getInstance();
config.mAppId = agoraAppId.getValue();
config.mEventHandler = new IRtcEngineEventHandler() {
@Override
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
super.onJoinChannelSuccess(channel, uid, elapsed);
LogUtils.e("加入频道成功");
}
@Override
public void onStreamMessage(int uid, int streamId, byte[] data) {
// JSONObject jsonMsg;
// try {
// String strMsg = new String(data);
// jsonMsg = new JSONObject(strMsg);
// if (jsonMsg.getString("cmd").equals("singleLineScore")) {
// int score = jsonMsg.getInt("score");
// int index = jsonMsg.getInt("index");
// int cumulativeScore = jsonMsg.getInt("cumulativeScore");
// int total = jsonMsg.getInt("total");
//
// LineScore lineScore = new LineScore();
// lineScore.score = score;
// lineScore.index = index;
// lineScore.cumulativeScore = cumulativeScore;
// lineScore.total = total;
// mainSingerScoreLiveData.postValue(lineScore);
// } else if (jsonMsg.getString("cmd").equals("SingingScore")) {
// float score = (float) jsonMsg.getDouble("score");
// playerMusicPlayCompleteLiveData.postValue(new ScoringAverageModel(false, (int) score));
// }
// } catch (JSONException exp) {
// LogUtils.e(TAG, "onStreamMessage:" + exp);
// }
}
@Override
public void onAudioVolumeIndication(AudioVolumeInfo[] speakers, int totalVolume) {
super.onAudioVolumeIndication(speakers, totalVolume);
if (rtcAudioVolumeIndication != null) {
rtcAudioVolumeIndication.onRtcAudioVolumeIndication(speakers, totalVolume);
}
}
};
config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
config.mAudioScenario = Constants.AUDIO_SCENARIO_CHORUS;
try {
mRtcEngine = (RtcEngineEx) RtcEngine.create(config);
} catch (Exception e) {
e.printStackTrace();
LogUtils.e(TAG, "RtcEngine.create() called error: " + e);
}
mRtcEngine.loadExtensionProvider("agora_drm_loader");
// ------------------ 场景化api初始化 ------------------
ktvApiProtocol.initialize(new KTVApiConfig(roomViewModel.getRoomInfo().getValue().getAgora_app_id(),
roomViewModel.getRoomInfo().getValue().getAgora_rtm_token(),
mRtcEngine, roomViewModel.getRoomInfo().getValue().getRid(), UID,
roomViewModel.getRoomInfo().getValue().getRid() + "_ex",
"", 10, KTVType.Normal));
ktvApiProtocol.addEventHandler(new IKTVApiEventHandler() {
@Override
public void onMusicPlayerStateChanged(@NonNull io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerError error, boolean isLocal) {
switch (state) {
case PLAYER_STATE_OPEN_COMPLETED:
playerMusicOpenDurationLiveData.postValue(ktvApiProtocol.getMediaPlayer().getDuration());
break;
case PLAYER_STATE_PLAYING:
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PLAYING);
break;
case PLAYER_STATE_PAUSED:
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PAUSE);
break;
case PLAYER_STATE_STOPPED:
case PLAYER_STATE_PLAYBACK_ALL_LOOPS_COMPLETED:
if (isLocal) {
playerMusicPlayCompleteLiveData.postValue(new ScoringAverageModel(true, 0));
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_LRC_RESET);
mSetting.setPlay(-1);
mSetting.setOriginal(false);
mSetting.setEar(false);
resetMusicStatus();
mSetting.setEffect(0);
setAudioEffectPreset(getEffectIndex(0));
}
break;
default:
}
}
});
ktvApiProtocol.renewInnerDataStreamId();
// ------------------ 加入频道 ------------------
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
mRtcEngine.enableAudio();
mRtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY, Constants.AUDIO_SCENARIO_GAME_STREAMING);
mRtcEngine.enableAudioVolumeIndication(50, 10, true);
mRtcEngine.setClientRole(isOnSeat ? Constants.CLIENT_ROLE_BROADCASTER : Constants.CLIENT_ROLE_AUDIENCE);
int ret = mRtcEngine.joinChannel(agoraToken.getValue(), channelId.getValue(), null, UID);
if (ret != Constants.ERR_OK) {
LogUtils.e(TAG, "joinRTC() called error: " + ret);
}
mSetting = new MusicSettingBean(false, 100, 0, new MusicSettingDialog.Callback() {
@Override
public void onEarChanged(boolean isEar) {
if (mRtcEngine != null) {
mRtcEngine.enableInEarMonitoring(isEar, Constants.EAR_MONITORING_FILTER_NONE);
}
}
@Override
public void onOriginalChanged(boolean isOriginal) {
musicToggleOriginal();
}
@Override
public void onMicVolChanged(int vol) {
setMicVolume(vol);
}
@Override
public void onMusicVolChanged(int vol) {
setMusicVolume(vol);
}
@Override
public void onEffectChanged(int effect) {
setAudioEffectPreset(getEffectIndex(effect));
}
@Override
public void onBeautifierPresetChanged(int effect) {
if (mRtcEngine != null) {
switch (effect) {
case 0:
mRtcEngine.setVoiceBeautifierParameters(Constants.VOICE_BEAUTIFIER_OFF, 0, 0);
case 1:
mRtcEngine.setVoiceBeautifierParameters(Constants.SINGING_BEAUTIFIER, 1, 2);
case 2:
mRtcEngine.setVoiceBeautifierParameters(Constants.SINGING_BEAUTIFIER, 1, 1);
case 3:
mRtcEngine.setVoiceBeautifierParameters(Constants.SINGING_BEAUTIFIER, 2, 2);
case 4:
mRtcEngine.setVoiceBeautifierParameters(Constants.SINGING_BEAUTIFIER, 2, 1);
}
}
}
@Override
public void setAudioEffectParameters(int param1, int param2) {
if (mRtcEngine != null) {
if (param1 == 0) {
mRtcEngine.setAudioEffectParameters(Constants.VOICE_CONVERSION_OFF, param1, param2);
} else {
mRtcEngine.setAudioEffectParameters(Constants.PITCH_CORRECTION, param1, param2);
}
}
}
@Override
public void playSong(int isPlay) {
if (isPlay == 0) {
if (playerMusicStatusLiveData.getValue() == RoomRTCViewModel.PlayerMusicStatus.ON_PAUSE) {
musicToggleStart();
} else {
if (roomViewModel.getDotSongList().getValue().size() > 0) {
if (roomViewModel.getRoomInfo().getValue().getCate_id().equals("36") || roomViewModel.getRoomInfo().getValue().getCate_id().equals("37")) {
for (int i = 0; i < roomViewModel.getDotSongList().getValue().size(); i++) {
if (roomViewModel.getDotSongList().getValue().get(i).getUid() == UserManager.INSTANCE.getUser().getUid()) {
SocketSong socketSong = roomViewModel.getDotSongList().getValue().get(i);
if (socketSong.getUid() == UserManager.INSTANCE.getUser().getUid()) {
RoomSelSongModel songModel = new RoomSelSongModel(socketSong.getSong_name(), socketSong.getSong_code(), socketSong.getSinger(), socketSong.getPoster(), String.valueOf(socketSong.getUid()), 0, 0, socketSong.is_accapella());
LogUtils.e(socketSong.getSong_name());
songPlayingLiveData.setValue(songModel);
musicStartPlay(songModel);
}
return;
}
}
} else {
for (int i = 0; i < roomViewModel.getDotSongList().getValue().size(); i++) {
if (roomViewModel.getDotSongList().getValue().get(i).getUid() == roomViewModel.getMcListBean_old().getValue().getRoom_song_info().getUser_info().getUid()) {
SocketSong socketSong = roomViewModel.getDotSongList().getValue().get(i);
if (socketSong.getUid() == UserManager.INSTANCE.getUser().getUid()) {
RoomSelSongModel songModel = new RoomSelSongModel(socketSong.getSong_name(), socketSong.getSong_code(), socketSong.getSinger(), socketSong.getPoster(), String.valueOf(socketSong.getUid()), 0, 0, socketSong.is_accapella());
songPlayingLiveData.setValue(songModel);
musicStartPlay(songModel);
}
return;
}
}
}
}
}
} else {
musicToggleStart();
}
}
@Override
public void playSongHC(int isPlay) {
if (isPlay == 0) {
if (playerMusicStatusLiveData.getValue() == RoomRTCViewModel.PlayerMusicStatus.ON_PAUSE) {
musicToggleStart();
} else {
if (roomViewModel.getDotSongList().getValue().size() > 0) {
SocketSong socketSong = roomViewModel.getDotSongList().getValue().get(roomViewModel.getDotSongList().getValue().size()-1);
LogUtils.e(socketSong.getSong_code(),socketSong.getSong_name());
RoomSelSongModel songModel = new RoomSelSongModel(socketSong.getSong_name(), socketSong.getSong_code(),
socketSong.getSinger(), socketSong.getPoster(), String.valueOf(socketSong.getUid()),
0, 0, socketSong.is_accapella());
songPlayingLiveData.setValue(songModel);
musicStartPlay2(songModel);
// for (int i = 0; i < roomViewModel.getDotSongList().getValue().size(); i++) {
// SocketSong socketSong = roomViewModel.getDotSongList().getValue().get(i);
// String Song_code=roomViewModel.getSongBean().getValue().getSong_code();
// if (socketSong.getSong_code().equals(Song_code)) {
// RoomSelSongModel songModel = new RoomSelSongModel(socketSong.getSong_name(), socketSong.getSong_code(), socketSong.getSinger(), socketSong.getPoster(), String.valueOf(socketSong.getUid()), 0, 0, socketSong.is_accapella());
// songPlayingLiveData.setValue(songModel);
// musicStartPlay2(songModel);
// }
// return;
// }
}
}
} else {
musicToggleStart();
}
}
});
// 外部使用的StreamId
if (streamId == 0) {
DataStreamConfig cfg = new DataStreamConfig();
cfg.syncWithAudio = false;
cfg.ordered = false;
streamId = mRtcEngine.createDataStream(cfg);
}
}
private void setAudioEffectPreset(int effect) {
if (mRtcEngine == null) {
return;
}
mRtcEngine.setAudioEffectPreset(effect);
}
// ======================= settings =======================
// ------------------ 音效调整 ------------------
private int getEffectIndex(int index) {
switch (index) {
// 原声
case 0:
return Constants.AUDIO_EFFECT_OFF;
// 流行
case 1:
return Constants.STYLE_TRANSFORMATION_POPULAR;
// 空旷
case 2:
return Constants.ROOM_ACOUSTICS_SPACIAL;
// R&B
case 3:
return Constants.STYLE_TRANSFORMATION_RNB;
// 演唱会
case 4:
return Constants.ROOM_ACOUSTICS_VOCAL_CONCERT;
// 录音棚
case 5:
return Constants.ROOM_ACOUSTICS_STUDIO;
// KTV
case 6:
return Constants.ROOM_ACOUSTICS_KTV;
// 留声机
case 7:
return Constants.ROOM_ACOUSTICS_PHONOGRAPH;
// 空灵
case 8:
return Constants.ROOM_ACOUSTICS_ETHEREAL;
}
// 原声
return Constants.AUDIO_EFFECT_OFF;
}
// ------------------ 暂停/播放 ------------------
public void musicToggleStart() {
if (playerMusicStatusLiveData.getValue() == PlayerMusicStatus.ON_PLAYING) {
ktvApiProtocol.pauseSing();
} else if (playerMusicStatusLiveData.getValue() == PlayerMusicStatus.ON_PAUSE) {
ktvApiProtocol.resumeSing();
}
}
// ------------------ 音量调整 ------------------
private int micVolume = 100;
private int micOldVolume = 100;
private void setMusicVolume(int v) {
ktvApiProtocol.getMediaPlayer().adjustPlayoutVolume(v);
ktvApiProtocol.getMediaPlayer().adjustPublishSignalVolume(v);
}
private void setMicVolume(int v) {
RoomSeatModel value = seatLocalLiveData.getValue();
int isMuted = value == null ? RoomSeatModel.Companion.getMUTED_VALUE_TRUE() : value.isAudioMuted();
if (isMuted == RoomSeatModel.Companion.getMUTED_VALUE_TRUE()) {
micOldVolume = v;
LogUtils.d(TAG, "muted! setMicVolume: " + v);
return;
}
LogUtils.d(TAG, "unmute! setMicVolume: " + v);
micVolume = v;
if (mRtcEngine != null) {
mRtcEngine.adjustRecordingSignalVolume(v);
}
}
// ------------------ 原唱/伴奏 ------------------
private enum KTVPlayerTrackMode {
Origin, Acc
}
protected KTVPlayerTrackMode mAudioTrackMode = KTVPlayerTrackMode.Acc;
public void musicToggleOriginal() {
if (mAudioTrackMode == KTVPlayerTrackMode.Origin) {
ktvApiProtocol.getMediaPlayer().selectAudioTrack(1);
mAudioTrackMode = KTVPlayerTrackMode.Acc;
} else {
ktvApiProtocol.getMediaPlayer().selectAudioTrack(0);
mAudioTrackMode = KTVPlayerTrackMode.Origin;
}
}
public boolean isOriginalMode() {
return mAudioTrackMode == KTVPlayerTrackMode.Origin;
}
// ------------------ 重置歌曲状态(歌曲切换时) ------------------
public void resetMusicStatus() {
LogUtils.d(TAG, "RoomLivingViewModel.resetMusicStatus() called");
chorusNum = 0;
retryTimes = 0;
mAudioTrackMode = KTVPlayerTrackMode.Acc;
ktvApiProtocol.stopMusic();
joinchorusStatusLiveData.postValue(JoinChorusStatus.ON_IDLE);
ktvApiProtocol.switchSingerRole(KTVSingRole.Audience, null);
}
// ------------------ 歌曲开始播放 ------------------
private int retryTimes = 0;
public void musicStartPlay(@NonNull RoomSelSongModel music) {
LogUtils.d(TAG, "RoomLivingViewModel.musicStartPlay() called");
if (music.getUserNo() == null) return;
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PREPARE);
boolean isOwnSong = TextUtils.equals(music.getUserNo(), String.valueOf(UID));
long songCode = Long.parseLong(music.getSongNo());
LogUtils.e("当前歌曲:" + songCode);
int mainSingerUid = Integer.parseInt(music.getUserNo());
if (isOwnSong) {
// 主唱加载歌曲
loadMusic(new KTVLoadMusicConfiguration(music.getSongNo(), true, mainSingerUid,
KTVLoadMusicMode.LOAD_MUSIC_AND_LRC), songCode, music.is_accapella());
} else {
loadMusic(new KTVLoadMusicConfiguration(music.getSongNo(), false, mainSingerUid, KTVLoadMusicMode.LOAD_LRC_ONLY), songCode, music.is_accapella());
}
// 标记歌曲为播放中
// ktvServiceProtocol.makeSongDidPlay(music, e -> {
// if (e != null) {
// // failure
// ToastUtils.showToast(e.getMessage());
// }
// return null;
// });
}
public void musicStartPlay2(@NonNull RoomSelSongModel music) {
LogUtils.d(TAG, "RoomLivingViewModel.musicStartPlay() called");
if (music.getUserNo() == null) return;
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PREPARE);
long songCode = Long.parseLong(music.getSongNo());
int mainSingerUid = Integer.parseInt(music.getUserNo());
LogUtils.e(TAG, mainSingerUid);
loadMusic(new KTVLoadMusicConfiguration(music.getSongNo(), false, mainSingerUid, KTVLoadMusicMode.LOAD_LRC_ONLY), songCode, music.is_accapella());
}
private void loadMusic(KTVLoadMusicConfiguration config, Long songCode, int is_accapella) {
ktvApiProtocol.loadMusic(songCode, config, new IMusicLoadStateListener() {
@Override
public void onMusicLoadProgress(long songCode, int percent, @NonNull MusicLoadStatus status, @Nullable String msg, @Nullable String lyricUrl) {
LogUtils.d(TAG, "onMusicLoadProgress, songCode: " + songCode + " percent: " + percent + " lyricUrl: " + lyricUrl);
}
@Override
public void onMusicLoadSuccess(long songCode, @NonNull String lyricUrl) {
// 当前已被切歌
if (songPlayingLiveData.getValue() == null) {
ToastUtils.showLong("load失败当前已无歌曲");
return;
}
// 重置settings
LogUtils.e(TAG, "onMusicLoadSuccess reason: " + lyricUrl);
retryTimes = 0;
if (is_accapella == 1) {
mSetting.setVolMic(100);
mSetting.setVolMusic(0);
ktvApiProtocol.getMediaPlayer().adjustPlayoutVolume(0);
ktvApiProtocol.getMediaPlayer().adjustPublishSignalVolume(0);
} else {
mSetting.setVolMic(100);
mSetting.setVolMusic(50);
ktvApiProtocol.getMediaPlayer().adjustPlayoutVolume(50);
ktvApiProtocol.getMediaPlayer().adjustPublishSignalVolume(50);
}
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PLAYING);
LogUtils.e(TAG, "PlayerMusicStatus.ON_PLAYING reason: ");
}
@Override
public void onMusicLoadFail(long songCode, @NonNull KTVLoadSongFailReason reason) {
// 当前已被切歌
if (songPlayingLiveData.getValue() == null) {
ToastUtils.showLong("load失败当前已无歌曲");
return;
}
LogUtils.e(TAG, "onMusicLoadFail reason: " + reason);
if (reason == KTVLoadSongFailReason.NO_LYRIC_URL) {
// 未获取到歌词 正常播放
retryTimes = 0;
mSetting.setVolMic(100);
mSetting.setVolMusic(50);
ktvApiProtocol.getMediaPlayer().adjustPlayoutVolume(50);
ktvApiProtocol.getMediaPlayer().adjustPublishSignalVolume(50);
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PLAYING);
noLrcLiveData.postValue(true);
} else if (reason == KTVLoadSongFailReason.MUSIC_PRELOAD_FAIL) {
// 歌曲加载失败 重试3次
ToastUtils.showLong("歌曲加载失败");
retryTimes = retryTimes + 1;
if (retryTimes < 3) {
loadMusic(config, songCode, 2);
} else {
playerMusicStatusLiveData.postValue(PlayerMusicStatus.ON_PLAYING);
ToastUtils.showLong("已尝试三次,请自动切歌");
}
} else if (reason == KTVLoadSongFailReason.CANCELED) {
// 当前已被切歌
ToastUtils.showLong("load失败当前已切换到另一首歌");
}
}
});
}
// ------------------ 重新获取歌词url ------------------
public void reGetLrcUrl() {
if (songPlayingLiveData.getValue() == null) return;
loadMusic(new KTVLoadMusicConfiguration(songPlayingLiveData.getValue().getSongNo(), true, Integer.parseInt(songPlayingLiveData.getValue().getUserNo()), KTVLoadMusicMode.LOAD_LRC_ONLY), Long.parseLong(songPlayingLiveData.getValue().getSongNo()), 2);
}
// ------------------ 歌曲seek ------------------
public void musicSeek(long time) {
ktvApiProtocol.seekSing(time);
}
public Long getSongDuration() {
return ktvApiProtocol.getMediaPlayer().getDuration();
}
// ------------------ 歌曲结束播放 ------------------
public void musicStop() {
LogUtils.d(TAG, "RoomLivingViewModel.musicStop() called");
// 列表中无歌曲, 还原状态
resetMusicStatus();
}
// ------------------ 歌词组件相关 ------------------
public void syncSingleLineScore(int score, int cumulativeScore, int index, int total) {
if (mRtcEngine == null) return;
Map<String, Object> msg = new HashMap<>();
msg.put("cmd", "singleLineScore");
msg.put("score", score);
msg.put("index", index);
msg.put("cumulativeScore", cumulativeScore);
msg.put("total", total);
JSONObject jsonMsg = new JSONObject(msg);
int ret = mRtcEngine.sendStreamMessage(streamId, jsonMsg.toString().getBytes());
if (ret < 0) {
LogUtils.e(TAG, "syncSingleLineScore() sendStreamMessage called returned: " + ret);
}
}
public void syncSingingAverageScore(double score) {
if (mRtcEngine == null) return;
Map<String, Object> msg = new HashMap<>();
msg.put("cmd", "SingingScore");
msg.put("score", score);
JSONObject jsonMsg = new JSONObject(msg);
int ret = mRtcEngine.sendStreamMessage(streamId, jsonMsg.toString().getBytes());
if (ret < 0) {
LogUtils.e(TAG, "syncSingingAverageScore() sendStreamMessage called returned: " + ret);
}
}
public interface RtcAudioVolumeIndication {
void onRtcAudioVolumeIndication(IRtcEngineEventHandler.AudioVolumeInfo[] speakers, int totalVolume);
}
public void setRtcAudioVolumeIndication(RtcAudioVolumeIndication rtcAudioVolumeIndication) {
this.rtcAudioVolumeIndication = rtcAudioVolumeIndication;
}
public void soloSingerJoinChorusMode(boolean isJoin) {
if (songPlayingLiveData.getValue() == null || seatListLiveData.getValue() == null) return;
if (songPlayingLiveData.getValue().getUserNo().equals(UserManager.INSTANCE.getUser().getUid())) {
if (isJoin) {
// 有人加入合唱
ktvApiProtocol.switchSingerRole(KTVSingRole.LeadSinger, null);
} else {
// 最后一人退出合唱
ktvApiProtocol.switchSingerRole(KTVSingRole.SoloSinger, null);
}
}
}
}

View File

@@ -0,0 +1,19 @@
package com.yuyin.module_live.rtc
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.yuyin.module_live.ui.room.RoomViewModel
class RtcViewModelFactory(var roomViewModel: RoomViewModel): ViewModelProvider.Factory {
// override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//
// return RoomRTCViewModel(roomViewModel) as T;
//
// }
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return RoomRTCViewModel(roomViewModel) as T;
}
}

View File

@@ -0,0 +1,67 @@
package com.yuyin.module_live.rtc.listener;
import android.content.Context;
import com.yuyin.module_live.rtc.RoomRTCViewModel;
import com.yuyin.module_live.view.LrcControlView;
import io.agora.karaoke_view.v11.model.LyricsLineModel;
import io.agora.karaoke_view.v11.model.LyricsModel;
public class LrcActionListenerImpl implements LrcControlView.OnKaraokeEventListener {
private final RoomRTCViewModel mViewModel;
private final LrcControlView mLrcControlView;
public LrcActionListenerImpl(RoomRTCViewModel viewModel, LrcControlView lrcControlView) {
mViewModel = viewModel;
mLrcControlView = lrcControlView;
}
@Override
public void onSwitchOriginalClick() {
LrcControlView.OnKaraokeEventListener.super.onSwitchOriginalClick();
mViewModel.musicToggleOriginal();
mLrcControlView.setSwitchOriginalChecked(mViewModel.isOriginalMode());
}
@Override
public void onDragTo(long time) {
mViewModel.musicSeek(time);
}
@Override
public void onLineFinished(LyricsLineModel line, int score, int cumulativeScore, int index, int total) {
mLrcControlView.updateScore(score, cumulativeScore, /** Workaround(Hai_Guo)*/total * 100);
mViewModel.syncSingleLineScore(score, cumulativeScore, index, total * 100);
}
// @Override
// public void onSkipPreludeClick() {
// LyricsModel lyrics = mLrcControlView.getKaraokeView().getLyricsData();
// if (lyrics == null) {
// return;
// }
// // Experience will be better when seeking 2000 milliseconds ahead
// long seekPosition = lyrics.startOfVerse - 2000;
// mViewModel.musicSeek(seekPosition > 0 ? seekPosition : 0);
// }
//
// @Override
// public void onSkipPostludeClick() {
// LyricsModel lyrics = mLrcControlView.getKaraokeView().getLyricsData();
// if (lyrics == null) {
// return;
// }
// mViewModel.musicSeek(mViewModel.getSongDuration() - 500);
// }
@Override
public void onReGetLrcUrl() {
mViewModel.reGetLrcUrl();
}
}

View File

@@ -0,0 +1,24 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.RoomSubsidy
class AllocationListAdapter :
BaseQuickAdapter<RoomSubsidy, BaseViewHolder>(R.layout.item_allocation_list) {
override fun convert(helper: BaseViewHolder, item: RoomSubsidy) {
helper.setVisible(R.id.view_line, helper.position != data.size - 1)
GlideUtil.loadImglogo(mContext,item.head_pic,helper.getView(R.id.iv_head))
helper.addOnClickListener(R.id.iv_delete)
.addOnClickListener(R.id.iv_set_proportion)
.setText(R.id.tv_nick_name,item.nick_name)
.setText(R.id.tv_user_id,"ID:"+item.uid)
.setText(R.id.tv_radio,item.ratio.toString()+"%")
.setText(R.id.tv_subsidy_money,"该用户可得${item.subsidy_money}")
}
}

View File

@@ -0,0 +1,23 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
import com.yuyin.module_live.model.AuctionPriceListItem
class ApplyChannelOutbidAdapter :
BaseQuickAdapter<AuctionPriceListItem, BaseViewHolder>(R.layout.item_apply_channel_outbid) {
private var selectPosition = -1
override fun convert(helper: BaseViewHolder, item: AuctionPriceListItem) {
val select = helper.layoutPosition == selectPosition
helper.itemView.isSelected = select
helper.setText(R.id.tv_price,item.price.toString())
}
fun setSelectPosition(index: Int) {
notifyItemChanged(selectPosition)
notifyItemChanged(index)
selectPosition = index
}
}

View File

@@ -0,0 +1,40 @@
package com.yuyin.module_live.ui.adapter
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.AppCompatCheckBox
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.socket.CommonAisle
import com.yuyin.lib_base.socket.SocketAisleBean
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
class ApplyChannelOwnerAdapter(@LayoutRes layoutResId: Int) :
BaseQuickAdapter<CommonAisle, BaseViewHolder>(layoutResId) {
private var selectPosition = -1
override fun convert(helper: BaseViewHolder, item: CommonAisle) {
helper.addOnClickListener(R.id.checkbox)
.addOnClickListener(R.id.iv_head)
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
helper.setText(R.id.tv_nick_name, item.nick_name)
if (helper.getView<TextView>(R.id.tv_help) != null) {
helper.addOnClickListener(R.id.tv_help)
}
if (helper.getView<TextView>(R.id.tv_price) != null) {
helper.setText(R.id.tv_price, item.rank_value.toString())
}
// val select = helper.layoutPosition == selectPosition
helper.getView<AppCompatCheckBox>(R.id.checkbox).isChecked = item.check
}
fun setSelectPosition(index: Int) {
notifyItemChanged(selectPosition)
notifyItemChanged(index)
selectPosition = index
}
}

View File

@@ -0,0 +1,38 @@
package com.yuyin.module_live.ui.adapter
import android.widget.TextView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftsBean
class ApplyChannelSetGiftAdapter :
BaseQuickAdapter<GiftsBean, BaseViewHolder>(R.layout.item_apply_channel_set_gift) {
private var selectPosition = -1
override fun convert(helper: BaseViewHolder, item: GiftsBean) {
val tvName = helper.getView<TextView>(R.id.tv_name)
val tvPrice = helper.getView<TextView>(R.id.tv_price)
val select = helper.layoutPosition == selectPosition
helper.itemView.isSelected = select
tvName.isSelected = select
tvPrice.isSelected = select
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_gift))
helper.setText(R.id.tv_name, item.gift_name)
.setText(R.id.tv_price, item.gift_price)
}
fun setSelectPosition(index: Int) {
notifyItemChanged(selectPosition)
notifyItemChanged(index)
selectPosition = index
}
}

View File

@@ -0,0 +1,28 @@
package com.yuyin.module_live.ui.adapter
import android.widget.TextView
import androidx.annotation.LayoutRes
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.socket.CommonAisle
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
class ApplyChannelUserAdapter(@LayoutRes layoutResId: Int) :
BaseQuickAdapter<CommonAisle, BaseViewHolder>(layoutResId) {
override fun convert(helper: BaseViewHolder, item: CommonAisle) {
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
helper.setText(R.id.tv_nick_name, item.nick_name)
helper.addOnClickListener(R.id.iv_head)
if (helper.getView<TextView>(R.id.tv_price) != null) {
helper.setText(R.id.tv_price, item.rank_value.toString())
}
if (helper.getView<TextView>(R.id.tv_help) != null) {
helper.addOnClickListener(R.id.tv_help)
}
}
}

View File

@@ -0,0 +1,31 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.OpenGiftBean;
import java.util.ArrayList;
public class BXAdapter extends BaseQuickAdapter<OpenGiftBean, BaseViewHolder> {
public BXAdapter() {
super(R.layout.bx_item, new ArrayList<>());
}
@Override
protected void convert(BaseViewHolder helper, OpenGiftBean item) {
if (!item.getBase_image().isEmpty()) {
Glide.with(mContext).load(item.getBase_image()).error(R.mipmap.no_tu).circleCrop().into((ImageView) helper.getView(R.id.liwu));
}
helper.setText(R.id.num, "");
helper.setText(R.id.name, item.getGift_name());
helper.setText(R.id.jiazhi, "x" + item.getOpen_num() + " (" + item.getGift_price() + ")");
helper.getView(R.id.liwu).setBackgroundResource(item.getSurprise() == 0 ? R.mipmap.xin_biankuang_daliwu1 : R.mipmap.xin_biankuang_daliwu12);
}
}

View File

@@ -0,0 +1,29 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.OpenGiftBean;
import java.util.ArrayList;
public class BXAdapter2 extends BaseQuickAdapter<OpenGiftBean, BaseViewHolder> {
public BXAdapter2() {
super(R.layout.bx_item2, new ArrayList<>());
}
@Override
protected void convert(BaseViewHolder helper, OpenGiftBean item) {
if (!item.getBase_image().isEmpty()) {
Glide.with(mContext).load(item.getBase_image()).error(R.mipmap.no_tu).circleCrop().into((ImageView) helper.getView(R.id.liwu));
}
helper.setText(R.id.num, "x" + item.getOpen_num());
helper.setText(R.id.name, item.getGift_name());
helper.setText(R.id.jiazhi, item.getGift_price() + "金币");
helper.getView(R.id.liwu).setBackgroundResource(item.getSurprise() == 0 ? R.mipmap.xin_biankuang_daliwu11 : R.mipmap.xin_biankuang_daliwu22);
}
}

View File

@@ -0,0 +1,69 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.OpenGiftBean;
import java.util.ArrayList;
public class BXAdapter3 extends BaseQuickAdapter<OpenGiftBean, BaseViewHolder> {
public BXAdapter3() {
super(R.layout.bx_item3, new ArrayList<>());
}
@Override
protected void convert(BaseViewHolder helper, OpenGiftBean item) {
if (!item.getBase_image().isEmpty()) {
Glide.with(mContext).load(item.getBase_image()).error(R.mipmap.no_tu).circleCrop().into((ImageView) helper.getView(R.id.liwu));
}
helper.setText(R.id.num, "x" + item.getOpen_num());
helper.setText(R.id.name, item.getGift_name() + " x" + item.getOpen_num());
helper.setText(R.id.jiazhi, item.getGift_price());
// ImageView liwu = helper.getView(R.id.liwu);
ImageView svgaImageView = helper.getView(R.id.liwu);
if (item.getSurprise() == 0) {
svgaImageView
.setBackgroundResource(R.mipmap.xin_biankuang_daliwu111);
} else {
svgaImageView
.setBackgroundResource(R.mipmap.xin_biankuang_daliwu222);
}
// SVGAParser parser = new SVGAParser(mContext);
// try {
// parser.decodeFromAssets("box_result.svga", new SVGAParser.ParseCompletion() {
// @Override
// public void onComplete(@NonNull SVGAVideoEntity svgaVideoEntity) {
// svgaImageView.setVideoItem(svgaVideoEntity);
// svgaImageView.setLoops(0);
// svgaImageView.stepToFrame(1, true);
// }
//
// @Override
// public void onError() {
//
// }
// });
// } catch (Exception e) {
// e.printStackTrace();
// }
// View view = helper.getView(R.id.view);
// if (mData.indexOf(item) == (mData.size() - 1)) {
// scale(view);
// }
}
// public void scale(View view) {
// Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.scale);
// view.startAnimation(animation);
// }
}

View File

@@ -0,0 +1,32 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.lib_base.socket.SocketBoxList;
import com.yuyin.lib_base.util.GlideUtil;
import com.yuyin.module_live.R;
public class Baoxiang5ListAdapter extends BaseQuickAdapter<SocketBoxList, BaseViewHolder> {
public Baoxiang5ListAdapter() {
super(R.layout.item_baoxiang5_list);
}
@Override
protected void convert(@NonNull BaseViewHolder helper, SocketBoxList item) {
GlideUtil.INSTANCE.loadImglogo(mContext, item.getBase_image(), helper.getView(R.id.iv_gift));
helper.setText(R.id.tv_gift_name, item.getGift_name())
.setText(R.id.price, "金币总数:" + item.getTotal_amount())
.setText(R.id.batch, "" + item.getNbl_sn() + "")
.setText(R.id.tv_progress, item.getAmount() + "")
.setText(R.id.tv_price, "金币"+item.getGift_price());
ProgressBar progressBar = helper.getView(R.id.progress);
progressBar.setMax(item.getTotal_amount());
progressBar.setProgress(item.getAmount());
helper.addOnClickListener(R.id.iv_record, R.id.tv_feeding);
}
}

View File

@@ -0,0 +1,21 @@
package com.yuyin.module_live.adapter
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.lib_base.util.TimeUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.Box4ResultBeanItem
class Baoxiang5RecordAdapter :
BaseQuickAdapter<Box4ResultBeanItem, BaseViewHolder>(R.layout.item_baoxiang5_record) {
override fun convert(helper: BaseViewHolder, item: Box4ResultBeanItem) {
helper.setText(R.id.tv_num, "" + item.nbl_sn + "")
.setText(R.id.tv_name, item.nick_name)
.setText(R.id.tv_time, TimeUtil.toDateYmd5(item.over_time))
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.civ_head))
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.module_live.ui.adapter
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.BlindBoxRankBean
import com.yuyin.module_live.model.Gift
class BlindBoxRankAdapter :
BaseQuickAdapter<BlindBoxRankBean, BaseViewHolder>(R.layout.item_blind_box_rank) {
override fun convert(helper: BaseViewHolder, item: BlindBoxRankBean) {
helper.setText(R.id.tv_num, (helper.layoutPosition + 1).toString())
.setText(R.id.tv_nick_name, item.nick_name)
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
helper.getView<RecyclerView>(R.id.rv_container).layoutManager =
LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)
helper.getView<RecyclerView>(R.id.rv_container).adapter =
BlindBoxRankChildAdapter(item.gift_list)
}
}
class BlindBoxRankChildAdapter(data: ArrayList<Gift>) :
BaseQuickAdapter<Gift, BaseViewHolder>(R.layout.item_blind_box_rank_child, data) {
override fun convert(helper: BaseViewHolder, item: Gift) {
helper.setText(R.id.num, item.gift_num)
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_gift))
}
}

View File

@@ -0,0 +1,29 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.lib_base.util.TimeUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.BlindBoxRecordBean
class BlindBoxRecordAdapter :
BaseQuickAdapter<BlindBoxRecordBean, BaseViewHolder>(R.layout.item_blind_box_record) {
override fun convert(helper: BaseViewHolder, item: BlindBoxRecordBean) {
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
GlideUtil.loadImglogo(mContext, item.receive_head_pic, helper.getView(R.id.iv_head2))
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.gift))
GlideUtil.loadImglogo(mContext, item.receive_base_image, helper.getView(R.id.gift2))
helper.setText(R.id.tv_nick_name, item.nick_name)
.setText(R.id.receive_nick_name, item.receive_nick_name)
.setText(R.id.tex4, item.gift_name)
.setText(R.id.text2, item.receive_gift_name)
.setText(R.id.num1, item.gift_num.toString())
.setText(R.id.num2, item.gift_num.toString())
.setText(R.id.tv_time, "获得时间:" + TimeUtil.toDateYmdHan3(item.add_time.toLong()))
}
}

View File

@@ -0,0 +1,18 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
import com.yuyin.module_live.model.SendGiftList
class BlindBoxSendGiftAdapter :
BaseQuickAdapter<SendGiftList, BaseViewHolder>(R.layout.item_send_blind_box_gift) {
override fun convert(helper: BaseViewHolder, item: SendGiftList) {
helper.setText(
R.id.content,
"" + "赠送" + item.nick_name + "" + item.gift_name + "x" + item.gift_num
)
}
}

View File

@@ -0,0 +1,34 @@
package com.yuyin.module_live.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.socket.BoxOpenCJBean
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
class Box5ChengJiuAdapter(val status: Int) :
BaseQuickAdapter<BoxOpenCJBean, BaseViewHolder>(R.layout.item_baoxiang5_cj) {
override fun convert(helper: BaseViewHolder, item: BoxOpenCJBean) {
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_gift))
helper.setText(R.id.batch, "" + item.nbl_sn + "")
.setText(R.id.tv_gift_name, item.gift_name)
.setText(R.id.price, item.total_amount.toString())
.setText(R.id.price2, item.amount.toString())
when (status) {
1 -> {
helper.setImageResource(R.id.iv_status, R.mipmap.dialog_baoxiang5_cj_item)
}
2 -> {
helper.setImageResource(R.id.iv_status, R.mipmap.dialog_baoxiang5_cj_item2)
}
3 -> {
helper.setImageResource(R.id.iv_status, R.mipmap.dialog_baoxiang5_cj_item3)
}
}
}
}

View File

@@ -0,0 +1,24 @@
package com.yuyin.module_live.ui.adapter
import android.content.Context
import android.view.ViewGroup
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.BoxJiangChiBean
class BoxJackpotListAdapter2 :
BaseQuickAdapter<BoxJiangChiBean, BaseViewHolder>(R.layout.item_box_jackpot_list2) {
override fun convert(helper: BaseViewHolder, item: BoxJiangChiBean) {
item.let {
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_cover))
helper.setText(R.id.tv_name, it.gift_name)
.setText(R.id.tv_num, item.gift_price)
}
}
}

View File

@@ -0,0 +1,31 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.yuyin.lib_base.util.TimeUtil;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiLuBean;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
public class BoxJiLuAdapter extends BaseQuickAdapter<BoxJiLuBean, BaseViewHolder> {
public BoxJiLuAdapter(List<BoxJiLuBean> data) {
super(R.layout.box_jilu_item, data);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiLuBean item) {
try {
helper.setText(R.id.tv_text, item.getGift_name() + "*" + item.getNum());
helper.setText(R.id.tv_text2, TimeUtil.toDateYmd(Long.parseLong(item.getAdd_time())));
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,80 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.beloo.widget.chipslayoutmanager.anchor.IAnchorFactory;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.lib_base.util.GlideUtil;
import com.yuyin.lib_base.util.TimeUtil;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiLuBean;
import com.yuyin.module_live.model.MonsterLogBean;
import java.util.List;
public class BoxJiLuAdapter2 extends BaseQuickAdapter<MonsterLogBean, BaseViewHolder> {
public BoxJiLuAdapter2() {
super(R.layout.box_jilu_item2);
}
@Override
protected void convert(BaseViewHolder helper, MonsterLogBean item) {
helper.setText(R.id.tv_time, TimeUtil.toDateYmdHan(item.getAdd_time()));
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < item.getWin_type_data().size(); i++) {
stringBuilder.append(item.getWin_type_data().get(i).getType_name()).append(",");
}
helper.setText(R.id.tv_name, stringBuilder.substring(0, stringBuilder.length() - 1));
StringBuilder stringBuilder2 = new StringBuilder();
for (int i = 0; i < item.getJoin_data().size(); i++) {
stringBuilder2.append(item.getJoin_data().get(i).getType_name() + "(" + item.getJoin_data().get(i).getNum() + ")").append(",");
}
if(item.getJoin_data().size()>0) {
helper.setGone(R.id.tv_content,true);
helper.setText(R.id.tv_content, "我的弹奏:" + stringBuilder2.substring(0, stringBuilder2.length() - 1));
}else {
helper.setGone(R.id.tv_content,false);
}
if (item.is_join() == 1) {
helper.setGone(R.id.tv_result, false);
helper.setText(R.id.tv_result, "");
if (item.getWin_gift_list().size() > 0) {
helper.setGone(R.id.fl_gift1, true);
helper.setText(R.id.tv_gift_num1, item.getWin_gift_list().get(0).getNum() + "");
GlideUtil.INSTANCE.loadImglogo(mContext, item.getWin_gift_list().get(0).getBase_image(), helper.getView(R.id.iv_gift));
} else {
helper.setGone(R.id.fl_gift1, false);
}
if (item.getWin_gift_list().size() > 1) {
helper.setGone(R.id.fl_gift2, true);
helper.setText(R.id.tv_gift_num2, item.getWin_gift_list().get(1).getNum() + "");
GlideUtil.INSTANCE.loadImglogo(mContext, item.getWin_gift_list().get(1).getBase_image(), helper.getView(R.id.iv_gift2));
} else {
helper.setGone(R.id.fl_gift2, false);
}
} else if (item.is_join() == 2) {
helper.setGone(R.id.tv_result, true);
helper.setText(R.id.tv_result, "未中奖");
helper.setGone(R.id.fl_gift1, false);
helper.setGone(R.id.fl_gift2, false);
} else {
helper.setGone(R.id.tv_result, true);
helper.setText(R.id.tv_result, "未参与");
helper.setGone(R.id.fl_gift1, false);
helper.setGone(R.id.fl_gift2, false);
}
}
}

View File

@@ -0,0 +1,33 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.lib_base.util.TimeUtil;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiLuBean;
import java.util.List;
public class BoxJiLuAdapter3 extends BaseQuickAdapter<BoxJiLuBean, BaseViewHolder> {
public BoxJiLuAdapter3(List<BoxJiLuBean> data) {
super(R.layout.box_jilu_item3, data);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiLuBean item) {
try {
helper.setText(R.id.tv_text, item.getGift_name() + "*" + item.getNum());
helper.setText(R.id.tv_text2, TimeUtil.toDateYmd(Long.parseLong(item.getAdd_time())));
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,31 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiangChiBean;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
public class BoxJiangChiAdapter extends BaseQuickAdapter<BoxJiangChiBean, BaseViewHolder> {
public BoxJiangChiAdapter(List<BoxJiangChiBean> data) {
super(R.layout.box_jiangchi_item, data);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiangChiBean item) {
try {
helper.setText(R.id.tv_num, item.getGift_price() + "");
helper.setText(R.id.tv_name, item.getGift_name());
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,30 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiangChiBean;
import java.util.List;
public class BoxJiangChiAdapter2 extends BaseQuickAdapter<BoxJiangChiBean, BaseViewHolder> {
public BoxJiangChiAdapter2(List<BoxJiangChiBean> data) {
super(R.layout.box_jiangchi_item2, data);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiangChiBean item) {
try {
helper.setText(R.id.tv_num, item.getGift_price() + "");
helper.setText(R.id.tv_name, item.getGift_name());
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,30 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiangChiBean;
import java.util.List;
public class BoxJiangChiAdapter3 extends BaseQuickAdapter<BoxJiangChiBean, BaseViewHolder> {
public BoxJiangChiAdapter3(List<BoxJiangChiBean> data) {
super(R.layout.box_jiangchi_item3, data);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiangChiBean item) {
try {
helper.setText(R.id.tv_num, item.getGift_price() + "");
helper.setText(R.id.tv_name, item.getGift_name());
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.yuyin.module_live.ui.adapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.BoxJiangChiBean;
public class BoxJiangChiAdapter4 extends BaseQuickAdapter<BoxJiangChiBean, BaseViewHolder> {
public BoxJiangChiAdapter4() {
super(R.layout.box_jiangchi_item4);
}
@Override
protected void convert(BaseViewHolder helper, BoxJiangChiBean item) {
try {
helper.setText(R.id.tv_num, item.getGift_price() + "");
helper.setText(R.id.tv_name, item.getGift_name());
Glide.with(mContext).load(item.getBase_image()).into((ImageView) helper.getView(R.id.iv_cover));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,24 @@
package com.yuyin.module_live.ui.adapter
import android.content.Context
import android.view.ViewGroup
import com.blankj.utilcode.util.TimeUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
import com.yuyin.module_live.model.MonsterUserLogBean
class BoxRankListAdapter2 :
BaseQuickAdapter<MonsterUserLogBean, BaseViewHolder>(R.layout.item_box_rank_list2) {
override fun convert(helper: BaseViewHolder, item: MonsterUserLogBean) {
helper.setText(R.id.tv_time,TimeUtils.millis2String(item.add_time.toLong() * 1000))
.setText(R.id.tv_type_name,"炼仙传说:" + item.type_name)
.setText(R.id.tv_result,"${item.mid}${item.nick_name}中了${item.gift_name}(${item.gift_price})*${item.num}")
}
}

View File

@@ -0,0 +1,39 @@
package com.yuyin.module_live.ui.adapter
import com.blankj.utilcode.util.TimeUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
import com.yuyin.module_live.model.MonsterLogBean
class BoxRecordListAdapter2 :
BaseQuickAdapter<MonsterLogBean, BaseViewHolder>(R.layout.item_box_record_list2) {
override fun convert(helper: BaseViewHolder, item: MonsterLogBean) {
item.let {
helper.setText(R.id.tv_time, TimeUtils.millis2String(item.add_time.toLong() * 1000))
when(item.is_join){
// 1已中奖2未中奖3未参与
1->{
helper.setText(R.id.tv_result,"${it.id}期 炼仙传说 ${it.type_name} 获得 ${item.gift_name}(${item.gift_price})*${item.num}")
}
2->{
helper.setText(R.id.tv_result,"${it.id}期 炼仙传说 ${it.type_name}")
.setText(R.id.tv_join,"未中奖")
}
3->{
helper.setText(R.id.tv_result,"${it.id}期 炼仙传说 ${it.type_name}")
.setText(R.id.tv_join,"未参与")
}
else -> {
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.google.gson.Gson
import com.tencent.qcloud.tuikit.tuichat.bean.CustomHelloMessage
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo
import com.tencent.qcloud.tuikit.tuiconversation.classicui.util.TUIConversationUtils
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.lib_base.util.TimeUtil
import com.yuyin.module_live.R
class ChatMsgAdapter :
BaseQuickAdapter<ConversationInfo, BaseViewHolder>(R.layout.item_chat_message) {
override fun convert(helper: BaseViewHolder, item: ConversationInfo) {
helper.setText(R.id.tv_nick_name, item.conversation.showName)
if (item.lastMessage != null) {
if (item.lastMessage.textElem != null) {
helper.setText(R.id.tv_content, item.lastMessage.textElem.text)
} else if (item.lastMessage.customElem != null) {
if (item.lastMessage.customElem.description.isNotEmpty()) {
helper.setText(R.id.tv_content, item.lastMessage.customElem.description)
} else {
try {
val msg = Gson().fromJson(
String(item.lastMessage.customElem.data),
CustomHelloMessage::class.java
)
helper.setText(R.id.tv_content, msg.text)
} catch (e: Exception) {
e.printStackTrace()
}
}
} else {
helper.setText(R.id.tv_content, "")
}
}
GlideUtil.loadImglogo(mContext, item.conversation.faceUrl, helper.getView(R.id.ci_head))
if (item.unRead > 0) {
helper.setText(R.id.tv_num, item.unRead.toString())
helper.setVisible(R.id.tv_num, true)
} else {
helper.setVisible(R.id.tv_num, false)
}
helper.itemView.setOnClickListener {
TUIConversationUtils.startChatActivity(item)
}
helper.setText(R.id.tv_time, TimeUtil.toDateYmdHan3(item.lastMessageTime))
// V2TIMManager.getConversationManager()
// .pinConversation(item.conversationId, true, object : V2TIMCallback {
// override fun onSuccess() {
// Log.i("imsdk", "success")
// Collections.swap(datas, 1, position)
// proxyNotifyDataSetChanged()
// }
//
// override fun onError(code: Int, desc: String) {
// Log.i("imsdk", "failure, code:$code, desc:$desc")
// }
// })
// holder.dataBinding.tvDelete.setOnClickListener {
// // 删除消息
// V2TIMManager.getConversationManager()
// .deleteConversation(
// item.conversationId,
// object : V2TIMCallback {
// override fun onSuccess() {
// Log.i("imsdk", "success")
// datas.removeAt(position)
// notifyItemRemoved(position)
// }
//
// override fun onError(code: Int, desc: String) {
// Log.i("imsdk", "failure, code:$code, desc:$desc")
// }
// })
// }
}
}

View File

@@ -0,0 +1,170 @@
package com.yuyin.module_live.ui.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.blankj.utilcode.util.LogUtils;
import com.bumptech.glide.Glide;
import com.makeramen.roundedimageview.RoundedImageView;
import com.orient.tea.barragephoto.adapter.BarrageAdapter;
import com.yuyin.lib_base.socket.SocketGiftList;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.PushBean;
import com.yuyin.module_live.ui.room.AdminRoomActivity;
public class DanMuViewHolder extends BarrageAdapter.BarrageViewHolder<PushBean> {
private Context mContext;
private RoundedImageView imgGift, imgGift_stone;
private TextView textUSer1, textUSer2, textNumber, textGiftName, box, OkBtn, wuYongOne,tv_follow1,tv_follow2;
private TextView textGiftName_stone, textNumber_stone;
private RelativeLayout mLayoutGift, mLayoutGemStone,ll_juwewei;
private TextView mTvGemStone,tv_gift_info;
private LinearLayout llBox;
public DanMuViewHolder(View itemView, Context context) {
super(itemView);
this.mContext = context;
//礼物
mLayoutGift = itemView.findViewById(R.id.layout_gift_notification);
imgGift = itemView.findViewById(R.id.imgGift);
textUSer1 = itemView.findViewById(R.id.textUSer1);
textUSer2 = itemView.findViewById(R.id.textUSer2);
textNumber = itemView.findViewById(R.id.textNumber);
textGiftName = itemView.findViewById(R.id.textGiftName);
box = itemView.findViewById(R.id.box);
OkBtn = itemView.findViewById(R.id.ok_btn);
wuYongOne = itemView.findViewById(R.id.wuyong_one);
//砸蛋
mLayoutGemStone = itemView.findViewById(R.id.layout_gemstone_notification);
mTvGemStone = itemView.findViewById(R.id.tv_gemstone_info);
imgGift_stone = itemView.findViewById(R.id.imgGift_stone);
textGiftName_stone = itemView.findViewById(R.id.textGiftName_stone);
textNumber_stone = itemView.findViewById(R.id.textNumber_stone);
llBox = itemView.findViewById(R.id.llBox);
tv_follow1 = itemView.findViewById(R.id.tv_follow1);
tv_follow2 = itemView.findViewById(R.id.tv_follow2);
// tv_gift_info = itemView.findViewById(R.id.tv_gift_info);
// ll_juwewei = itemView.findViewById(R.id.ll_juwewei);
}
@SuppressLint("SetTextI18n")
@Override
protected void onBind(PushBean pushBean) {
if (pushBean != null) {
if ("gift".equals(pushBean.getType2())) {
if ("gift".equals(pushBean.getType2())) {
mLayoutGift.setVisibility(View.VISIBLE);
mLayoutGemStone.setVisibility(View.GONE);
// mTvGift.setText(pushBean.getData().getFrom_name() + "赠送给" + pushBean.getData().getUser_name() + pushBean.getData().getGift_name() + "x" + pushBean.getData().getNum());
// wuYongOne.setText("惊现土豪~");
textUSer1.setText(pushBean.getSendBeanAllSub().getSend_user_info().getNick_name());
// box.setText(" 在 "+pushBean.getSendBeanAllSub().getRoom_info().getRoom_name()+"房间 送给" );
box.setText(" 送给 ");
textUSer2.setText(pushBean.getSendBeanAllSub().getRecived_user_info().getNick_name());
String imgUrls = pushBean.getSendBeanAllSub().getBase_image();
LogUtils.d("收到开礼物通知了===imgUrls=" + imgUrls);
if (!TextUtils.isEmpty(imgUrls)) {
imgGift.setVisibility(View.VISIBLE);
try {
Glide.with(mContext).load(imgUrls).into(imgGift);
} catch (Exception e) {
e.printStackTrace();
}
} else {
imgGift.setVisibility(View.GONE);
}
textGiftName.setText(pushBean.getSendBeanAllSub().getGift_name());
textNumber.setText("x" + pushBean.getSendBeanAllSub().getNum());
}
tv_follow1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
LogUtils.e("aaaaaaaaaaaaaaaaaaaaa");
// if(mContext instanceof AdminRoomActivity) {
//
// ((AdminRoomActivity) mContext).viewModel.enterRoom(pushBean.getSendBeanAllSub().getRid(),"", (AppCompatActivity) mContext);
// }
return false;
}
});
} else if ("award".equals(pushBean.getType2())) {
if (pushBean.getSocketOpenBean().is_europe() == 1) {
llBox.setBackgroundResource(R.mipmap.icon_gemstone_bg_nofication);
}
// boolean isBig = false;
// for (int i = 0; i < pushBean.getSocketOpenBean().getGift_list().size(); i++) {
// if (Integer.parseInt(pushBean.getSocketOpenBean().getGift_list().get(i).getGift_price()) > 30000) {
// isBig = true;
// }
// }
// if (isBig) {
// llBox.setBackgroundResource(R.mipmap.icon_gemstone_bg_nofication3);
// } else {
// llBox.setBackgroundResource(R.mipmap.icon_gemstone_bg_nofication2);
// }
LogUtils.d("砸蛋====");
mLayoutGift.setVisibility(View.GONE);
mLayoutGemStone.setVisibility(View.VISIBLE);
mTvGemStone.setText("");
mTvGemStone.setTextColor(mContext.getResources().getColor(R.color.white));
SocketGiftList socketGiftList = pushBean.getSocketOpenBean().getGift_list().get(pushBean.getSocketOpenBean().getGift_list().size() - 1);
mTvGemStone.setText("恭喜!" + pushBean.getSocketOpenBean().getUser_info().getNick_name() + "" + socketGiftList.getType_name() + "开出了");
String imgUrl = socketGiftList.getBase_image();
LogUtils.d("砸蛋消息===imgUrl=" + imgUrl);
// if (!TextUtils.isEmpty(imgUrl)) {
// imgGift_stone.setVisibility(View.VISIBLE);
// try {
// Glide.with(mContext).load(imgUrl).into(imgGift_stone);
// } catch (Exception e) {
// e.printStackTrace();
// }
// } else {
// imgGift_stone.setVisibility(View.GONE);
// }
textGiftName_stone.setText("" + socketGiftList.getGift_name());
textNumber_stone.setText("x" + socketGiftList.getOpen_num());
tv_follow2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
LogUtils.e("aaaaaaaaaaaaaaaaaaaaa");
// if(mContext instanceof AdminRoomActivity) {
//
// ((AdminRoomActivity) mContext).viewModel.enterRoom(pushBean.getRid(),"", (AppCompatActivity) mContext);
// }
return false;
}
});
}
// else
// if ("juewei".equals(pushBean.getType2())) {
//
// mLayoutGift.setVisibility(View.GONE);
// mLayoutGemStone.setVisibility(View.GONE);
// ll_juwewei.setVisibility(View.VISIBLE);
// tv_gift_info.setText(pushBean.getContent());
//
//
// }
}
}
}

View File

@@ -0,0 +1,24 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GameListBean
class GameListAdapter : BaseQuickAdapter<GameListBean, BaseViewHolder>(R.layout.item_game_list) {
override fun convert(helper: BaseViewHolder, item: GameListBean) {
helper.setText(R.id.tv_name, item.gameName)
when (item.gameName) {
"狼人杀" -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.game_lrs)
}
"桌球" -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.game_zq)
}
"碰碰我最强" -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.game_ppwzq)
}
}
}
}

View File

@@ -0,0 +1,23 @@
package com.yuyin.module_live.ui.adapter
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.OpenGiftBean
class JackpotAdapter : BaseQuickAdapter<OpenGiftBean, BaseViewHolder>(R.layout.item_jackpot) {
override fun convert(helper: BaseViewHolder, item: OpenGiftBean) {
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_gift))
helper.setText(R.id.tv_title, item.gift_name + "x" + item.open_num)
.setText(R.id.tv_price, item.gift_price)
helper.getView<ImageView>(R.id.iv_gift)
.setBackgroundResource(if (item.surprise == 0) R.mipmap.baoxiang4_get_jackpot_bg1 else R.mipmap.baoxiang4_get_jackpot_bg2);
}
}

View File

@@ -0,0 +1,22 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftWeekRankData
import com.yuyin.module_live.model.RoomSubsidy
class LastWeekAdapter :
BaseQuickAdapter<GiftWeekRankData, BaseViewHolder>(R.layout.item_weekly_last) {
override fun convert(helper: BaseViewHolder, item: GiftWeekRankData) {
GlideUtil.loadImglogo(mContext,item.base_image,helper.getView(R.id.iv_sz_gift))
GlideUtil.loadImglogo(mContext,item.head_pic,helper.getView(R.id.iv_sz_head))
helper
.setText(R.id.tv_sz_gift,item.gift_name)
.setText(R.id.tv_sz_name,item.nick_name)
.setText(R.id.tv_sz_num,"收到${item.total_gift_num}")
}
}

View File

@@ -0,0 +1,25 @@
package com.yuyin.module_live.ui.adapter
import android.widget.LinearLayout
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftLoveBean
import com.yuyin.module_live.model.RoomSubsidy
class LoveGiftAdapter :
BaseQuickAdapter<GiftLoveBean, BaseViewHolder>(R.layout.item_love_gift) {
override fun convert(helper: BaseViewHolder, item: GiftLoveBean) {
GlideUtil.loadImglogo(mContext,item.base_image,helper.getView(R.id.iv_gift1))
helper
.setText(R.id.tv_gift_price1,item.gift_price)
.setText(R.id.tv_gift_name1,item.gift_name)
.setText(R.id.tv_tag1,item.tag_name)
if(item.isSelect){
helper.getView<LinearLayout>(R.id.ll_gift1).isSelected=true
}else{
helper.getView<LinearLayout>(R.id.ll_gift1).isSelected=false
}
}
}

View File

@@ -0,0 +1,33 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftWeekRankData
import com.yuyin.module_live.model.MtlRankGiftData
import com.yuyin.module_live.model.RoomSubsidy
import com.yuyin.module_live.model.WeekStartGiftData
class MtlRankAdapter :
BaseQuickAdapter<MtlRankGiftData, BaseViewHolder>(R.layout.item_love_mtl) {
override fun convert(helper: BaseViewHolder, item: MtlRankGiftData) {
GlideUtil.loadImglogo(mContext,item.head_pic,helper.getView(R.id.head1))
GlideUtil.loadImglogo(mContext,item.receive_head_pic,helper.getView(R.id.head2))
if(helper.position==0){
helper.setImageResource(R.id.iv_loeve_num,R.mipmap.love_mtl_icon3)
}else if(helper.position==1){
helper.setImageResource(R.id.iv_loeve_num,R.mipmap.love_mtl_icon4)
}else if(helper.position==2){
helper.setImageResource(R.id.iv_loeve_num,R.mipmap.love_mtl_icon5)
}else if(helper.position==3){
helper.setImageResource(R.id.iv_loeve_num,R.mipmap.love_mtl_icon6)
}else if(helper.position==4){
helper.setImageResource(R.id.iv_loeve_num,R.mipmap.love_mtl_icon7)
}
helper
.setText(R.id.tv_name1,item.nick_name)
.setText(R.id.tv_name2,item.receive_nick_name)
.setText(R.id.tv_value,item.rank_value)
}
}

View File

@@ -0,0 +1,25 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftWeekRankData
import com.yuyin.module_live.model.MtlRankGiftData
import com.yuyin.module_live.model.RoomSubsidy
import com.yuyin.module_live.model.WeekStartGiftData
class MtlRankListAdapter :
BaseQuickAdapter<MtlRankGiftData, BaseViewHolder>(R.layout.item_love_mtl_list) {
override fun convert(helper: BaseViewHolder, item: MtlRankGiftData) {
GlideUtil.loadImglogo(mContext,item.head_pic,helper.getView(R.id.civ_head))
GlideUtil.loadImglogo(mContext,item.receive_head_pic,helper.getView(R.id.civ_head2))
helper
helper
.setText(R.id.tv_rank,(helper.position+6).toString())
.setText(R.id.tv_nick_name,item.nick_name)
.setText(R.id.tv_user_id,item.receive_nick_name)
.setText(R.id.tv_charm_value,"亲密度:"+item.rank_value)
}
}

View File

@@ -0,0 +1,97 @@
package com.yuyin.module_live.ui.adapter;
import android.content.Context;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.yuyin.module_live.R;
import com.yuyin.module_live.ui.room.music.Song;
import java.util.List;
/**
* 音乐列表适配器
*
* @author llw
*/
public class MusicListAdapter extends BaseQuickAdapter<Song, BaseViewHolder> {
Context mContext;
public int selPos = 0;
public MusicListAdapter(int layoutResId, @Nullable List<Song> data, Context mContext) {
super(layoutResId, data);
this.mContext = mContext;
}
/**
* 将秒数转换为日时分秒,
*
* @param second
* @return
*/
public static String secondToTime(long second) {
long days = second / 86400; //转换天数
second = second % 86400; //剩余秒数
long hours = second / 3600; //转换小时
second = second % 3600; //剩余秒数
long minutes = second / 60; //转换分钟
second = second % 60; //剩余秒数
if (days > 0) {
return days + "" + hours + "小时" + minutes + "" + second + "";
} else if (hours > 0) {
return hours + "小时" + minutes + "" + second + "";
} else {
return (minutes < 10 ? "0" + minutes : minutes) + ":" + (second < 10 ? "0" + second : second) + "";
}
}
@Override
protected void convert(BaseViewHolder helper, Song item) {
//给控件赋值
int duration = item.duration;
String time = secondToTime(duration / 1000) + "";
//歌曲名称
helper.setText(R.id.tv_song_name, item.getSong().trim())
//歌手 - 专辑
.setText(R.id.tv_singer, " - " + item.getSinger())
//歌曲时间
.setText(R.id.tv_duration_time, time)
//歌曲序号因为getAdapterPosition得到的位置是从0开始故而加1
//是因为位置和1都是整数类型直接赋值给TextView会报错故而拼接了""
.setText(R.id.tv_position, helper.getAdapterPosition() + 1 + "");
ImageView imageView = helper.getView(R.id.ivvvv);
// //点击后改变文字颜色
// if (helper.getPosition() == selPos) {
// imageView.setImageResource(R.mipmap.music_mubg3);
// helper.setTextColor(R.id.tv_position, Color.parseColor("#23C9FF"))
// .setTextColor(R.id.tv_song_name, Color.parseColor("#23C9FF"))
// .setTextColor(R.id.tv_singer, Color.parseColor("#23C9FF"))
// .setTextColor(R.id.tv_duration_time, Color.parseColor("#23C9FF"));
// } else {
// imageView.setImageResource(R.mipmap.music_mubg2);
// helper.setTextColor(R.id.tv_position, mContext.getColor(R.color.white))
// .setTextColor(R.id.tv_song_name, mContext.getColor(R.color.white))
// .setTextColor(R.id.tv_singer, mContext.getColor(R.color.white))
// .setTextColor(R.id.tv_duration_time, mContext.getColor(R.color.white));
// }
}
/**
* 刷新数据
*/
public void changeState() {
notifyDataSetChanged();
}
}

View File

@@ -0,0 +1,32 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.socket.NewsComerRank
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
class NewComerRankAdapter :
BaseQuickAdapter<NewsComerRank, BaseViewHolder>(R.layout.item_new_comer_ranl) {
override fun convert(helper: BaseViewHolder, item: NewsComerRank) {
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
helper.setText(R.id.tv_nick_name, item.nick_name)
.setText(R.id.tv_price, item.price)
when (helper.layoutPosition) {
0 -> {
helper.setText(R.id.tv_num, "1")
}
1 -> {
helper.setText(R.id.tv_num, "2")
}
2 -> {
helper.setText(R.id.tv_num, "3")
}
}
}
}

View File

@@ -0,0 +1,37 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.GiftWeekRankData
import com.yuyin.module_live.model.RoomSubsidy
class NowWeekAdapter :
BaseQuickAdapter<GiftWeekRankData, BaseViewHolder>(R.layout.item_weekly_star_list) {
override fun convert(helper: BaseViewHolder, item: GiftWeekRankData) {
if(helper.position==0){
helper.setBackgroundRes(R.id.tv_rank,R.mipmap.week_rank_icon6)
helper.setText(R.id.tv_rank,"")
}else if(helper.position==1){
helper.setBackgroundRes(R.id.tv_rank,R.mipmap.week_rank_icon7)
helper.setText(R.id.tv_rank,"")
}else if(helper.position==2){
helper.setText(R.id.tv_rank,"")
helper.setBackgroundRes(R.id.tv_rank,R.mipmap.week_rank_icon8)
}else{
helper.setBackgroundRes(R.id.tv_rank,0)
helper.setText(R.id.tv_rank,(helper.position+1).toString())
}
GlideUtil.loadImglogo(mContext,item.give_head_pic,helper.getView(R.id.civ_head2))
GlideUtil.loadImglogo(mContext,item.head_pic,helper.getView(R.id.civ_head))
helper
.addOnClickListener(R.id.civ_head)
.addOnClickListener(R.id.civ_head2)
.setText(R.id.tv_user_id,"收到${item.total_gift_num}${item.gift_name}")
.setText(R.id.tv_nick_name,item.nick_name)
.setText(R.id.tv_charm_value,"打赏${item.give_total_gift_num}")
}
}

View File

@@ -0,0 +1,21 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.PrivacyRoomGift
class PrivateCottageGiftAdapter :
BaseQuickAdapter<PrivacyRoomGift, BaseViewHolder>(R.layout.item_dating_private_gift) {
override fun convert(helper: BaseViewHolder, item: PrivacyRoomGift) {
helper.setText(R.id.tv_gift_name, item.gift_name)
.setText(R.id.tv_price, item.gift_price + "金币")
.setText(R.id.tv_duration_time, "+" + item.duration + "s")
GlideUtil.loadImglogo(mContext, item.base_image, helper.getView(R.id.iv_gift))
}
}

View File

@@ -0,0 +1,82 @@
package com.yuyin.module_live.ui.adapter;
import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.yuyin.module_live.R;
import com.yuyin.module_live.model.RankListBean;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.ArrayList;
public class RankAdapter extends BaseQuickAdapter<RankListBean, BaseViewHolder> {
private int type;
private Context context;
BaseViewHolder mHelper;
private boolean isRoom;
public RankAdapter(int type, Context context,boolean isRoom) {
super(R.layout.item_rank, new ArrayList<>());
this.type = type;
this.context = context;
this.isRoom = isRoom;
}
@Override
protected void convert(BaseViewHolder helper, RankListBean item) {
mHelper = helper;
// helper.addOnClickListener(R.id.ci_head);
if (type == 3) {
TextView roomRankId1 = helper.getView(R.id.tv_user_id);
roomRankId1.setText(String.valueOf(item.getRoom_number()));
helper.getView(R.id.image_one).setVisibility(View.GONE);
helper.getView(R.id.image_two).setVisibility(View.GONE);
if (!TextUtils.isEmpty(item.getRoom_cover())) {
Glide.with(context).load(item.getRoom_cover()).error(R.mipmap.ic_launcher_app).placeholder(R.mipmap.ic_launcher_app).into((ImageView) helper.getView(R.id.ci_head));
}
helper.setText(R.id.text1, String.valueOf(helper.getPosition() + 4)).setText(R.id.tv_title, item.getRoom_name()).setText(R.id.textNum, item.getTotal_amount());
} else {
TextView roomRankId1 = helper.getView(R.id.tv_user_id);
roomRankId1.setText(item.getUid());
helper.getView(R.id.image_one).setVisibility(View.VISIBLE);
helper.getView(R.id.image_two).setVisibility(View.VISIBLE);
Glide.with(context).load(item.getContribution_image()).into((ImageView) helper.getView(R.id.image_one));
Glide.with(context).load(item.getCharm_image()).into((ImageView) helper.getView(R.id.image_two));
helper.setText(R.id.text1, String.valueOf(helper.getPosition() + 4)).setText(R.id.tv_title, item.getNick_name()).setText(R.id.textNum, item.getRank_value());
if (!TextUtils.isEmpty(item.getHead_pic())) {
Glide.with(context).load(item.getHead_pic()).error(R.mipmap.ic_launcher_app).placeholder(R.mipmap.ic_launcher_app).into((ImageView) helper.getView(R.id.ci_head));
}
}
if (isRoom) {
helper.setTextColor(R.id.tv_title, Color.parseColor("#FFFFFF"));
helper.setTextColor(R.id.textNum, Color.parseColor("#FFFFFF"));
helper.setTextColor(R.id.text1, Color.parseColor("#FFFFFF"));
}else {
helper.setTextColor(R.id.tv_title, Color.parseColor("#333333"));
helper.setTextColor(R.id.textNum, Color.parseColor("#333333"));
helper.setTextColor(R.id.text1, Color.parseColor("#333333"));
}
// if (type == 1) {
// helper.setTextColor(R.id.textNum, Color.parseColor("#FFFFFF"));
// helper.setBackgroundRes(R.id.item_back, R.drawable.shape_rank_bg15_top1);
// } else if (type == 2) {
// helper.setTextColor(R.id.textNum, Color.parseColor("#FFFFFF"));
// helper.setBackgroundRes(R.id.item_back, R.drawable.shape_rank_bg15_top2);
// } else {
// helper.setTextColor(R.id.textNum, Color.parseColor("#FFFFFF"));
// helper.setBackgroundRes(R.id.item_back, R.drawable.shape_rank_bg15_top3);
// }
}
}

View File

@@ -0,0 +1,50 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.CPList
class RankRoomCpAdapter : BaseQuickAdapter<CPList, BaseViewHolder>(R.layout.item_room_cp_rank) {
override fun convert(helper: BaseViewHolder, item: CPList) {
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_left_head))
GlideUtil.loadImglogo(mContext, item.receive_head_pic, helper.getView(R.id.iv_right_head))
helper.setText(R.id.tv_left_name, item.nick_name)
.setText(R.id.tv_right_name, item.receive_nick_name)
.setText(R.id.tv_rank_value, item.total_amount)
GlideUtil.loadImglogo2(mContext,item.win_base_image,helper.getView(R.id.left_frame))
GlideUtil.loadImglogo2(mContext,item.receive_win_base_image,helper.getView(R.id.right_frame))
// when (helper.layoutPosition) {
// 0 -> {
// helper.setImageResource(R.id.iv_num, R.mipmap.item_room_cp_rank1)
// helper.setVisible(R.id.iv_num, true)
// helper.setVisible(R.id.tv_num, false)
// }
// 1 -> {
// helper.setImageResource(R.id.iv_num, R.mipmap.item_room_cp_rank2)
// helper.setVisible(R.id.iv_num, true)
// helper.setVisible(R.id.tv_num, false)
// }
// 2 -> {
// helper.setImageResource(R.id.iv_num, R.mipmap.item_room_cp_rank3)
// helper.setVisible(R.id.iv_num, true)
// helper.setVisible(R.id.tv_num, false)
// }
// else -> {
// helper.setVisible(R.id.iv_num, false)
// helper.setVisible(R.id.tv_num, true)
// helper.setText(R.id.tv_num, (helper.layoutPosition + 1).toString())
// }
// }
helper.setVisible(R.id.iv_num, false)
helper.setVisible(R.id.tv_num, true)
helper.setText(R.id.tv_num, (helper.layoutPosition + 1).toString())
}
}

View File

@@ -0,0 +1,61 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.module_live.R
class ReverberationAdapter :
BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_reverberation) {
private var selectPosition = 0
override fun convert(helper: BaseViewHolder, item: String) {
when (helper.position) {
0 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.yuanchang)
}
1 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.liuxing)
}
2 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.dixiashi)
}
3 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.yaogun)
}
4 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.yanchanghui)
}
5 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.luyinpeng)
}
6 -> {
helper.setImageResource(R.id.iv_cover, R.mipmap.ktv)
}
}
helper.setText(R.id.tv_name, item)
val isSelected = helper.layoutPosition === selectPosition
helper.setVisible(R.id.iv_select, isSelected)
}
fun setSelectPosition(index: Int) {
notifyItemChanged(selectPosition)
notifyItemChanged(index)
selectPosition = index
}
}

View File

@@ -0,0 +1,17 @@
package com.yuyin.module_live.ui.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yuyin.lib_base.util.GlideUtil
import com.yuyin.module_live.R
import com.yuyin.module_live.model.RoomUserSub
class RoomAvatarListAdapter :
BaseQuickAdapter<RoomUserSub, BaseViewHolder>(R.layout.item_avatar_list) {
override fun convert(helper: BaseViewHolder, item: RoomUserSub) {
GlideUtil.loadImglogo(mContext, item.head_pic, helper.getView(R.id.iv_head))
}
}

Some files were not shown because too many files have changed in this diff Show More