需要添加直播接口
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package uts.sdk.modules.atomicx.kotlin
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.text.TextUtils
|
||||
import com.google.gson.Gson
|
||||
import com.tencent.cloud.tuikit.engine.room.TUIRoomDefine
|
||||
import com.tencent.cloud.tuikit.engine.room.TUIRoomEngine
|
||||
|
||||
private const val TAG = "UTS-CallExperimentalApi: "
|
||||
|
||||
object ExperimentalApiInvoker {
|
||||
private val gson = Gson()
|
||||
|
||||
// const data = { "api": "setTestEnvironment", "params": { "enableRoomTestEnv": true } } // 设置 IM 测试环境
|
||||
// const data = { "api": "setLocalVideoMuteImage", "params": { "image": "filePath" } } // 设置垫片
|
||||
// const giftData = { "api": "setCurrentLanguage", "params": { "language" : "en"} } // 礼物功能设置语言
|
||||
public fun callExperimentalAPI(
|
||||
jsonString: String,
|
||||
callback: TUIRoomDefine.ExperimentalAPIResponseCallback?,
|
||||
) {
|
||||
val requestData: RequestData = gson.fromJson(jsonString, RequestData::class.java)
|
||||
if (requestData.api == "setLocalVideoMuteImage") {
|
||||
setLocalVideoMuteImage(requestData, callback)
|
||||
return
|
||||
}
|
||||
|
||||
TUIRoomEngine.sharedInstance().callExperimentalAPI(jsonString) { jsonData ->
|
||||
// Logger.i(TAG + "${requestData.api}: onResponse: $jsonData")
|
||||
callback?.onResponse(jsonData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setLocalVideoMuteImage(
|
||||
data: RequestData,
|
||||
callback: TUIRoomDefine.ExperimentalAPIResponseCallback?,
|
||||
) {
|
||||
try {
|
||||
val filePath = data.params?.image
|
||||
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
// Logger.e(TAG + "setLocalVideoMuteImage: filePath is empty")
|
||||
callback?.onResponse("setLocalVideoMuteImage: filePath is empty")
|
||||
return
|
||||
}
|
||||
|
||||
val bitmap = BitmapFactory.decodeFile(filePath)
|
||||
TUIRoomEngine.sharedInstance().setLocalVideoMuteImage(bitmap)
|
||||
} catch (e: Exception) {
|
||||
// Logger.e(TAG + "setLocalVideoMuteImage: ${e.message}")
|
||||
callback?.onResponse("setLocalVideoMuteImage: unexpected error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class RequestData(
|
||||
val api: String,
|
||||
val params: Params?,
|
||||
)
|
||||
|
||||
// 不要修改数据,每个数据对应一个关键字
|
||||
data class Params(
|
||||
val image: String?,
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
package uts.sdk.modules.atomicx.kotlin
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Outline
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import io.dcloud.uts.console
|
||||
import io.trtc.tuikit.atomicxcore.api.view.CoreViewType
|
||||
import io.trtc.tuikit.atomicxcore.api.view.LiveCoreView
|
||||
|
||||
private const val TAG = "UTS-LiveRenderView: "
|
||||
|
||||
class LiveRenderView(context: Context, attrs: AttributeSet? = null) : ConstraintLayout(context, attrs) {
|
||||
private var cornerRadius: Float = 48f // 圆角半径
|
||||
private var nativeViewType = CoreViewType.PLAY_VIEW
|
||||
|
||||
init {
|
||||
clipToOutline = true
|
||||
outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(0, 0, view.width, view.height, cornerRadius)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
outlineProvider.getOutline(this, Outline())
|
||||
invalidateOutline()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
Log.w(TAG, "onAttachedToWindow")
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
Log.w(TAG, "onDetachedFromWindow")
|
||||
}
|
||||
|
||||
public fun updateViewType(viewType: Any) {
|
||||
if (viewType == null) {
|
||||
return
|
||||
}
|
||||
if (viewType !is String) {
|
||||
return
|
||||
}
|
||||
if (viewType == "PUSH_VIEW") {
|
||||
nativeViewType = CoreViewType.PUSH_VIEW
|
||||
}
|
||||
}
|
||||
|
||||
public fun updateRenderView(liveID: Any) {
|
||||
console.warn("StreamView, updateRenderView liveID: ", liveID, nativeViewType)
|
||||
Logger.i(TAG + "updateRenderView: liveID:" + liveID + ", viewType: " + nativeViewType)
|
||||
if (liveID == null) {
|
||||
console.error("StreamView, updateRenderView liveID is invalid")
|
||||
Logger.e(TAG + "updateRenderView: liveID is invalid")
|
||||
return
|
||||
}
|
||||
if (liveID !is String) {
|
||||
console.error("StreamView, updateRenderView liveID is not String")
|
||||
Logger.e(TAG + "updateRenderView: liveID is not String")
|
||||
return
|
||||
}
|
||||
|
||||
if(liveID.isEmpty()) {
|
||||
console.error("StreamView, updateRenderView liveID is empty")
|
||||
Logger.e(TAG + "updateRenderView: liveID is empty")
|
||||
return
|
||||
}
|
||||
removeAllViews()
|
||||
val renderView = LiveCoreView(context, null, 0, nativeViewType)
|
||||
renderView.setLiveId(liveID)
|
||||
val lp = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
||||
addView(renderView, lp)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package uts.sdk.modules.atomicx.kotlin
|
||||
|
||||
import android.util.Log
|
||||
import com.tencent.liteav.base.ContextUtils
|
||||
import com.tencent.trtc.TRTCCloud
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
class Logger {
|
||||
companion object {
|
||||
private const val API = "TuikitLog"
|
||||
private const val LOG_KEY_API = "api"
|
||||
private const val LOG_KEY_PARAMS = "params"
|
||||
private const val LOG_KEY_PARAMS_LEVEL = "level"
|
||||
private const val LOG_KEY_PARAMS_MESSAGE = "message"
|
||||
private const val LOG_KEY_PARAMS_FILE = "file"
|
||||
private const val LOG_KEY_PARAMS_LINE = "line"
|
||||
private const val LOG_KEY_PARAMS_MODULE = "module"
|
||||
private const val LOG_VALUE_PARAMS_MODULE = "call_state"
|
||||
private const val LOG_LEVEL_INFO = 0
|
||||
private const val LOG_LEVEL_WARNING = 1
|
||||
private const val LOG_LEVEL_ERROR = 2
|
||||
private const val LOG_FUNCTION_CALLER_INDEX = 5
|
||||
|
||||
fun i(message: String) {
|
||||
log(LOG_LEVEL_INFO, message)
|
||||
}
|
||||
|
||||
fun w(message: String) {
|
||||
log(LOG_LEVEL_WARNING, message)
|
||||
}
|
||||
|
||||
fun e(message: String) {
|
||||
log(LOG_LEVEL_ERROR, message)
|
||||
}
|
||||
|
||||
private fun log(
|
||||
level: Int,
|
||||
message: String,
|
||||
) {
|
||||
var context = ContextUtils.getApplicationContext()
|
||||
if (context == null) {
|
||||
ContextUtils.initContextFromNative("liteav")
|
||||
context = ContextUtils.getApplicationContext()
|
||||
}
|
||||
if (context == null) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
val paramsJson = JSONObject()
|
||||
paramsJson.put(LOG_KEY_PARAMS_LEVEL, level)
|
||||
paramsJson.put(LOG_KEY_PARAMS_MESSAGE, message)
|
||||
paramsJson.put(LOG_KEY_PARAMS_MODULE, LOG_VALUE_PARAMS_MODULE)
|
||||
paramsJson.put(LOG_KEY_PARAMS_FILE, getCallerFileName())
|
||||
paramsJson.put(LOG_KEY_PARAMS_LINE, getCallerLineNumber())
|
||||
|
||||
val loggerJson = JSONObject()
|
||||
loggerJson.put(LOG_KEY_API, API)
|
||||
loggerJson.put(LOG_KEY_PARAMS, paramsJson)
|
||||
|
||||
TRTCCloud.sharedInstance(context).callExperimentalAPI(loggerJson.toString())
|
||||
} catch (e: JSONException) {
|
||||
Log.e("Logger", e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCallerFileName(): String {
|
||||
val stackTrace = Thread.currentThread().stackTrace
|
||||
if (stackTrace.size < LOG_FUNCTION_CALLER_INDEX + 1) return ""
|
||||
return stackTrace[LOG_FUNCTION_CALLER_INDEX].fileName
|
||||
}
|
||||
|
||||
private fun getCallerLineNumber(): Int {
|
||||
val stackTrace = Thread.currentThread().stackTrace
|
||||
if (stackTrace.size < LOG_FUNCTION_CALLER_INDEX + 1) return 0
|
||||
return stackTrace[LOG_FUNCTION_CALLER_INDEX].lineNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package uts.sdk.modules.atomicx.kotlin
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.opensource.svgaplayer.SVGACallback
|
||||
import com.opensource.svgaplayer.SVGAImageView
|
||||
import com.opensource.svgaplayer.SVGAParser
|
||||
import com.opensource.svgaplayer.SVGAVideoEntity
|
||||
import io.dcloud.uts.console
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
|
||||
class SVGAAnimationView(context: Context) : FrameLayout(context), SVGACallback {
|
||||
private val svgaParser: SVGAParser
|
||||
private val svgaImageView: SVGAImageView
|
||||
private var svgaCallback: SVGACallback? = null
|
||||
|
||||
init {
|
||||
svgaImageView = SVGAImageView(context)
|
||||
val lp: FrameLayout.LayoutParams =
|
||||
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
addView(svgaImageView, lp)
|
||||
svgaImageView.loops = 1
|
||||
svgaImageView.callback = this
|
||||
svgaParser = SVGAParser.shareParser()
|
||||
svgaParser.init(context)
|
||||
}
|
||||
|
||||
fun setCallback(callback: SVGACallback) {
|
||||
svgaCallback = callback
|
||||
}
|
||||
|
||||
// val playUrl = "/sdcard/Android/data/uni.app.UNIFA697C8/images/sports_car.svga"
|
||||
fun startAnimation(playUrl: String) {
|
||||
console.log("startAnimation playUrl: ", playUrl)
|
||||
// Logger.e(TAG + "startAnimation, playUrl: $playUrl")
|
||||
|
||||
if (playUrl.isNullOrEmpty()) {
|
||||
console.error("startAnimation, playUrl is empty")
|
||||
// Logger.e(TAG + "startAnimation, playUrl is empty")
|
||||
svgaCallback?.onFinished()
|
||||
return
|
||||
}
|
||||
|
||||
if (playUrl.endsWith(".svga") && isUrl(playUrl)) {
|
||||
decodeFromURL(playUrl)
|
||||
} else {
|
||||
decodeFromInputStream(playUrl)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isUrl(url: String): Boolean = url.startsWith("http") || url.startsWith("https")
|
||||
|
||||
fun stopAnimation() {
|
||||
svgaImageView.stopAnimation(true)
|
||||
}
|
||||
|
||||
private fun decodeFromURL(playUrl: String) {
|
||||
console.log("decodeFromURL, playUrl: ", playUrl)
|
||||
|
||||
svgaParser.decodeFromURL(URL(playUrl), object : SVGAParser.ParseCompletion {
|
||||
override fun onComplete(videoItem: SVGAVideoEntity) {
|
||||
console.log("decodeFromURL onComplete, videoItem: ", videoItem)
|
||||
// Logger.i(TAG + "startAnimation decodeFromURL, videoItem: $videoItem")
|
||||
|
||||
svgaImageView.setVisibility(View.VISIBLE)
|
||||
svgaImageView.setVideoItem(videoItem)
|
||||
svgaImageView.startAnimation()
|
||||
}
|
||||
|
||||
override fun onError() {
|
||||
console.log("===== decodeFromURL failed")
|
||||
// Logger.e(TAG + "decodeFromURL failed, playUrl: $playUrl")
|
||||
svgaCallback?.onFinished()
|
||||
}
|
||||
},)
|
||||
}
|
||||
|
||||
private fun decodeFromInputStream(filePath: String) {
|
||||
console.log("decodeFromInputStream, filePath: ", filePath)
|
||||
val stream = openInputStream(filePath)
|
||||
if (stream == null) {
|
||||
console.log("decodeFromInputStream, filePath is null")
|
||||
// Logger.e(TAG + "decodeFromInputStream failed, filePath is null")
|
||||
return
|
||||
}
|
||||
svgaParser.decodeFromInputStream(stream, "", object : SVGAParser.ParseCompletion {
|
||||
override fun onComplete(videoItem: SVGAVideoEntity) {
|
||||
console.log("======startAnimation decodeFromInputStream start: ", videoItem)
|
||||
// Logger.i(TAG + "decodeFromInputStream start: videoItem: $videoItem")
|
||||
svgaImageView.setVisibility(VISIBLE)
|
||||
svgaImageView.setVideoItem(videoItem)
|
||||
svgaImageView.startAnimation()
|
||||
}
|
||||
|
||||
override fun onError() {
|
||||
console.log("======decodeFromInputStream parse failed: ", filePath)
|
||||
// Logger.e(TAG + "decodeFromInputStream parse failed, filePath: $filePath")
|
||||
svgaCallback?.onFinished()
|
||||
}
|
||||
}, true, null, "", )
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
console.log("SVGAAnimationView onFinished")
|
||||
// Logger.i(TAG + "onFinished")
|
||||
svgaImageView.setVisibility(View.GONE)
|
||||
svgaCallback?.onFinished()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
}
|
||||
|
||||
override fun onRepeat() {
|
||||
}
|
||||
|
||||
override fun onStep(frame: Int, percentage: Double) {
|
||||
}
|
||||
|
||||
private fun openInputStream(path: String): InputStream? {
|
||||
try {
|
||||
val file = File(path)
|
||||
if (file.exists()) {
|
||||
return FileInputStream(file)
|
||||
}
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.i(TAG, " " + e.localizedMessage)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "UTS-SVGAAnimationView: "
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.device.AudioEffectStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object AudioEffectStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
fun audioEffectStoreChanged(callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
AudioEffectStore.shared().audioEffectState.isEarMonitorOpened
|
||||
.collect { enable ->
|
||||
callback("isEarMonitorOpened", gson.toJson(enable))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
AudioEffectStore.shared().audioEffectState.earMonitorVolume
|
||||
.collect { volume ->
|
||||
callback("earMonitorVolume", gson.toJson(volume))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
AudioEffectStore.shared().audioEffectState.audioChangerType
|
||||
.collect { type ->
|
||||
callback("audioChangerType", gson.toJson(type.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
AudioEffectStore.shared().audioEffectState.audioReverbType
|
||||
.collect { type ->
|
||||
callback("audioReverbType", gson.toJson(type.value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.barrage.Barrage
|
||||
import io.trtc.tuikit.atomicxcore.api.barrage.BarrageStore
|
||||
import io.trtc.tuikit.atomicxcore.api.barrage.BarrageType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object BarrageStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun barrageStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
BarrageStore.create(liveID).barrageState.messageList.collect { messageList ->
|
||||
callback("messageList", gson.toJson(messageList))
|
||||
}
|
||||
}
|
||||
// TODO: 底层未实现,暂时隐藏
|
||||
// launch {
|
||||
// BarrageStore.create(liveID).barrageState.allowSendMessage.collect { allowSendMessage ->
|
||||
// callback("allowSendMessage", gson.toJson(allowSendMessage))
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.device.BaseBeautyStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object BaseBeautyStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun beautyStoreChanged(callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
BaseBeautyStore.shared().baseBeautyState.smoothLevel.collect { level ->
|
||||
callback("smoothLevel", gson.toJson(level))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
BaseBeautyStore.shared().baseBeautyState.whitenessLevel.collect { level ->
|
||||
callback("whitenessLevel", gson.toJson(level))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
BaseBeautyStore.shared().baseBeautyState.ruddyLevel.collect { level ->
|
||||
callback("ruddyLevel", gson.toJson(level))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.BattleStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object BattleStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun battleStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
BattleStore.create(liveID).battleState.currentBattleInfo.collect { currentBattleInfo ->
|
||||
callback("currentBattleInfo", gson.toJson(currentBattleInfo))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
BattleStore.create(liveID).battleState.battleUsers.collect { battleUsers ->
|
||||
callback("battleUsers", gson.toJson(battleUsers))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
BattleStore.create(liveID).battleState.battleScore.collect { battleScore ->
|
||||
callback("battleScore", gson.toJson(battleScore))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.CoGuestStore
|
||||
import io.trtc.tuikit.atomicxcore.api.device.DeviceStatus
|
||||
import io.trtc.tuikit.atomicxcore.api.live.Role
|
||||
import io.trtc.tuikit.atomicxcore.api.live.SeatUserInfo
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object CoGuestStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun coGuestStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
CoGuestStore.create(liveID).coGuestState.connected.collect { connected ->
|
||||
val list = connected.map { convertSeatInfoToMap(it) }
|
||||
callback("connected", gson.toJson(list)) // SeatUserInfo
|
||||
}
|
||||
}
|
||||
launch {
|
||||
CoGuestStore.create(liveID).coGuestState.invitees.collect { invitees ->
|
||||
callback("invitees", gson.toJson(invitees)) // LiveUserInfo
|
||||
}
|
||||
}
|
||||
launch {
|
||||
CoGuestStore.create(liveID).coGuestState.applicants.collect { applicants ->
|
||||
callback("applicants", gson.toJson(applicants)) // LiveUserInfo
|
||||
}
|
||||
}
|
||||
launch {
|
||||
CoGuestStore.create(liveID).coGuestState.candidates.collect { candidates ->
|
||||
callback("candidates", gson.toJson(candidates)) // LiveUserInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertSeatInfoToMap(info: SeatUserInfo): Map<String, Any> {
|
||||
val map = mutableMapOf<String, Any>()
|
||||
map["userID"] = info.userID
|
||||
map["userName"] = info.userName
|
||||
map["avatarURL"] = info.avatarURL
|
||||
map["role"] = info.role
|
||||
map["liveID"] = info.liveID
|
||||
map["microphoneStatus"] = convertDeviceStatus(info.microphoneStatus)
|
||||
map["allowOpenMicrophone"] = info.allowOpenMicrophone
|
||||
map["cameraStatus"] = convertDeviceStatus(info.cameraStatus)
|
||||
map["allowOpenCamera"] = info.allowOpenCamera
|
||||
return map
|
||||
}
|
||||
|
||||
private fun convertDeviceStatus(status: DeviceStatus?): String {
|
||||
if (status == DeviceStatus.ON) {
|
||||
return "ON"
|
||||
}
|
||||
return "OFF"
|
||||
}
|
||||
|
||||
private fun convertUserRole(role: Role?): String {
|
||||
return when (role) {
|
||||
Role.OWNER -> "OWNER"
|
||||
Role.ADMIN -> "ADMIN"
|
||||
else -> "GENERAL_USER"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.CoHostStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object CoHostStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun coHostStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
CoHostStore.create(liveID).coHostState.coHostStatus.collect { coHostStatus ->
|
||||
callback("coHostStatus", gson.toJson(coHostStatus))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
CoHostStore.create(liveID).coHostState.connected.collect { connected ->
|
||||
callback("connected", gson.toJson(connected))
|
||||
}
|
||||
}
|
||||
// TODO: 底层未实现,暂时隐藏
|
||||
// launch {
|
||||
// CoHostStore.create(liveID).coHostState.candidates.collect { candidates ->
|
||||
// callback("candidates", gson.toJson(candidates))
|
||||
// }
|
||||
// }
|
||||
launch {
|
||||
CoHostStore.create(liveID).coHostState.invitees.collect { invitees ->
|
||||
callback("invitees", gson.toJson(invitees))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
CoHostStore.create(liveID).coHostState.applicant.collect { applicant ->
|
||||
callback("applicant", gson.toJson(applicant))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.device.DeviceStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object DeviceStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun deviceStoreChanged(callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.microphoneStatus.collect { status ->
|
||||
callback("microphoneStatus", gson.toJson(status.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.microphoneLastError.collect { deviceError ->
|
||||
callback("microphoneLastError", gson.toJson(deviceError.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.captureVolume.collect { volume ->
|
||||
callback("captureVolume", gson.toJson(volume))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.currentMicVolume.collect { volume ->
|
||||
callback("currentMicVolume", gson.toJson(volume))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.outputVolume.collect { volume ->
|
||||
callback("outputVolume", gson.toJson(volume))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.cameraStatus.collect { cameraStatus ->
|
||||
callback("cameraStatus", gson.toJson(cameraStatus.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.cameraLastError.collect { deviceError ->
|
||||
callback("cameraLastError", gson.toJson(deviceError.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.isFrontCamera.collect { isFrontCamera ->
|
||||
callback("isFrontCamera", gson.toJson(isFrontCamera))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.localMirrorType.collect { localMirrorType ->
|
||||
callback("localMirrorType", gson.toJson(localMirrorType))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.localVideoQuality.collect { quality ->
|
||||
callback("localVideoQuality", gson.toJson(quality))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.currentAudioRoute.collect { audioRoute ->
|
||||
callback("currentAudioRoute", gson.toJson(audioRoute.value))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.screenStatus.collect { screenStatus ->
|
||||
callback("screenStatus", gson.toJson(screenStatus.value))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
DeviceStore.shared().deviceState.networkInfo.collect { networkInfo ->
|
||||
callback("networkInfo", gson.toJson(networkInfo))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.gift.GiftStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object GiftStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun giftStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
GiftStore.create(liveID).giftState.usableGifts.collect { usableGifts ->
|
||||
callback("usableGifts", gson.toJson(usableGifts))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.LikeStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object LikeStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun likeStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LikeStore.create(liveID).likeState.totalLikeCount.collect { count ->
|
||||
callback("totalLikeCount", gson.toJson(count))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.LiveAudienceStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object LiveAudienceStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun liveAudienceStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LiveAudienceStore.create(liveID).liveAudienceState.audienceList.collect { audienceList ->
|
||||
callback("audienceList", gson.toJson(audienceList))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
LiveAudienceStore.create(liveID).liveAudienceState.audienceCount.collect { audienceCount ->
|
||||
callback("audienceCount", gson.toJson(audienceCount))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.LiveListStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object LiveListStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun liveStoreChanged(callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LiveListStore.shared().liveState.liveList.collect { liveList ->
|
||||
callback("liveList", gson.toJson(liveList))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
LiveListStore.shared().liveState.liveListCursor.collect { cursor ->
|
||||
callback("liveListCursor", gson.toJson(cursor))
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
LiveListStore.shared().liveState.currentLive.collect { liveInfo ->
|
||||
callback("currentLive", gson.toJson(liveInfo))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.LiveSeatStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import uts.sdk.modules.atomicx.kotlin.Logger
|
||||
import io.dcloud.uts.console
|
||||
|
||||
object LiveSeatStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun liveSeatStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LiveSeatStore.create(liveID).liveSeatState.seatList.collect { seatList ->
|
||||
val list = gson.toJson(seatList)
|
||||
console.info("UTS-Live: liveSeatStoreChanged, seatList: ", list)
|
||||
Logger.i("UTS-Live: " + "liveSeatStoreChanged, seatList: "+ list);
|
||||
callback("seatList", gson.toJson(seatList))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
LiveSeatStore.create(liveID).liveSeatState.canvas.collect { canvas ->
|
||||
callback("canvas", gson.toJson(canvas))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
LiveSeatStore.create(liveID).liveSeatState.speakingUsers.collect { speakingUsers ->
|
||||
callback("speakingUsers", gson.toJson(speakingUsers))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import io.trtc.tuikit.atomicxcore.api.live.LiveSummaryStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
object LiveSummaryStoreObserver {
|
||||
private val gson = Gson()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun liveSummaryStoreChanged(liveID: String, callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LiveSummaryStore.create(liveID).liveSummaryState.summaryData.collect { data ->
|
||||
callback("summaryData", gson.toJson(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package uts.sdk.modules.atomicx.observer
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import io.trtc.tuikit.atomicxcore.api.login.LoginStatus
|
||||
import io.trtc.tuikit.atomicxcore.api.login.LoginStore
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object LoginStoreObserver {
|
||||
private val gson = GsonBuilder().serializeNulls().create()
|
||||
private var bindDataJob: Job? = null
|
||||
|
||||
fun loginStoreChanged(callback: (String, String) -> Unit) {
|
||||
bindDataJob?.cancel()
|
||||
bindDataJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
launch {
|
||||
LoginStore.shared.loginState.loginUserInfo.collect { userInfo ->
|
||||
callback("loginUserInfo", gson.toJson(userInfo))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
LoginStore.shared.loginState.loginStatus.collect { loginStatus ->
|
||||
// UNLOGIN \ LOGINED
|
||||
callback("loginStatus", gson.toJson(loginStatus))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user