Skip to content

Commit a84ed9a

Browse files
jiahaoliangMinTate
authored andcommitted
【Android】Call 4.1 release
1 parent 7d42a8d commit a84ed9a

18 files changed

Lines changed: 380 additions & 8 deletions

File tree

call/tuicallkit-kt/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/TUICallKitImpl.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.tencent.qcloud.tuikit.tuicallkit
22

33
import android.content.Context
44
import android.content.Intent
5+
import android.os.Handler
6+
import android.os.Looper
57
import com.tencent.cloud.tuikit.engine.call.TUICallDefine
68
import com.tencent.cloud.tuikit.engine.common.TUICommonDefine
79
import com.tencent.cloud.tuikit.engine.common.TUICommonDefine.Callback
@@ -43,6 +45,7 @@ import kotlinx.coroutines.supervisorScope
4345

4446
class TUICallKitImpl private constructor(context: Context) : TUICallKit() {
4547
private val context = context.applicationContext ?: context
48+
private val mainHandler = Handler(Looper.getMainLooper())
4649
private var subscribeSelfStateJob: Job? = null
4750
private val callStatusObserver = object : CallListener() {
4851
override fun onCallStarted(callId: String, mediaType: CallMediaType) {
@@ -58,7 +61,9 @@ class TUICallKitImpl private constructor(context: Context) : TUICallKit() {
5861
}
5962

6063
if (reason == CallEndReason.LineBusy) {
61-
AtomicToast.show(context, context.getString(R.string.callkit_toast_other_party_busy), Style.INFO)
64+
mainHandler.post {
65+
AtomicToast.show(context, context.getString(R.string.callkit_toast_other_party_busy), Style.INFO)
66+
}
6267
}
6368
}
6469

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.tencent.qcloud.tuikit.tuicallkit.beauty
2+
3+
import android.content.Context
4+
import android.os.Bundle
5+
import android.util.Log
6+
import com.tencent.qcloud.tuicore.interfaces.TUIServiceCallback
7+
import com.tencent.qcloud.tuikit.tuicallkit.beauty.tebeauty.BeautyPanelDialog
8+
import com.tencent.qcloud.tuikit.tuicallkit.beauty.tebeauty.TEBeautyManager
9+
import java.lang.ref.WeakReference
10+
11+
object BeautyIntegration {
12+
private var dialogWeakRef = WeakReference<BeautyPanelDialog?>(null)
13+
14+
fun isSupportTEBeauty(): Boolean = TEBeautyManager.isSupportTEBeauty()
15+
16+
fun setupVideoProcessor() {
17+
TEBeautyManager.setCustomVideoProcess()
18+
}
19+
20+
@JvmStatic
21+
fun showBeautyDialog(context: Context) {
22+
if (TEBeautyManager.isSupportTEBeauty()) {
23+
TEBeautyManager.checkBeautyResource(context, object : TUIServiceCallback() {
24+
override fun onServiceCallback(code: Int, message: String?, bundle: Bundle?) {
25+
if (code == 0) {
26+
realShowBeautyDialog(context)
27+
} else {
28+
Log.e("BeautyIntegration", "check beauty resource failed:$code,message:$message")
29+
}
30+
}
31+
})
32+
} else {
33+
Log.e("BeautyIntegration", "check isSupportTEBeauty is false")
34+
}
35+
}
36+
37+
@JvmStatic
38+
fun resetBeauty() {
39+
TEBeautyManager.clearBeautyParams()
40+
}
41+
42+
private fun realShowBeautyDialog(context: Context) {
43+
val dialog = BeautyPanelDialog(context)
44+
dialogWeakRef = WeakReference(dialog)
45+
dialog.setOnDismissListener {
46+
TEBeautyManager.exportParam()
47+
}
48+
dialog.show()
49+
}
50+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.tencent.qcloud.tuikit.tuicallkit.beauty.tebeauty
2+
3+
import android.content.Context
4+
import android.os.Bundle
5+
import android.view.View
6+
import io.trtc.tuikit.atomicx.widget.basicwidget.popover.AtomicPopover
7+
8+
class BeautyPanelDialog(
9+
private val context: Context
10+
) : AtomicPopover(context) {
11+
12+
init {
13+
setShowMask(false)
14+
}
15+
16+
override fun onCreate(savedInstanceState: Bundle?) {
17+
super.onCreate(savedInstanceState)
18+
val beautyView: View = TEBeautyView(context)
19+
setContent(beautyView)
20+
}
21+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.tencent.qcloud.tuikit.tuicallkit.beauty.tebeauty
2+
3+
import android.content.Context
4+
import android.os.Bundle
5+
import android.os.Handler
6+
import android.os.Looper
7+
import android.view.View
8+
import com.tencent.cloud.tuikit.engine.call.TUICallEngine
9+
import com.tencent.qcloud.tuicore.TUICore
10+
import com.tencent.qcloud.tuicore.interfaces.TUIServiceCallback
11+
import com.tencent.trtc.TRTCCloudDef
12+
import com.tencent.trtc.TRTCCloudListener.TRTCVideoFrameListener
13+
import com.tencent.cloud.tuikit.engine.common.ContextProvider
14+
import java.lang.ref.WeakReference
15+
16+
object TEBeautyManager {
17+
private const val TE_BEAUTY_EXTENSION = "TEBeautyExtension"
18+
19+
private var listenerRef: WeakReference<OnBeautyViewListener>? = null
20+
private var lastParamList: String? = null
21+
private val mainHandler = Handler(Looper.getMainLooper())
22+
23+
private var isResourceLoaded = false
24+
25+
private val trtcVideoFrameListener = object : TRTCVideoFrameListener {
26+
override fun onGLContextCreated() {
27+
if (isResourceLoaded) {
28+
mainHandler.post {
29+
ContextProvider.getApplicationContext()?.apply { initBeautyKit(this, false) }
30+
}
31+
}
32+
}
33+
34+
override fun onProcessVideoFrame(
35+
srcFrame: TRTCCloudDef.TRTCVideoFrame,
36+
dstFrame: TRTCCloudDef.TRTCVideoFrame
37+
): Int {
38+
val params = mapOf(
39+
"srcTextureId" to srcFrame.texture.textureId,
40+
"frameWidth" to srcFrame.width,
41+
"frameHeight" to srcFrame.height
42+
)
43+
dstFrame.texture.textureId = TUICore.callService(TE_BEAUTY_EXTENSION, "processVideoFrame", params) as Int
44+
return 0
45+
}
46+
47+
override fun onGLContextDestory() {
48+
val lastParam = exportParam()
49+
destroyBeautyKit()
50+
mainHandler.post {
51+
lastParamList = lastParam
52+
listenerRef?.get()?.onDestroyBeautyView()
53+
}
54+
}
55+
}
56+
57+
fun isSupportTEBeauty(): Boolean = TUICore.getService(TE_BEAUTY_EXTENSION) != null
58+
59+
fun setCustomVideoProcess() {
60+
if (isSupportTEBeauty()) {
61+
TUICallEngine.createInstance(ContextProvider.getApplicationContext()).trtcCloudInstance.setLocalVideoProcessListener(
62+
TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D,
63+
TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE,
64+
trtcVideoFrameListener
65+
)
66+
}
67+
}
68+
69+
fun clearBeautyParams() {
70+
lastParamList = null
71+
}
72+
73+
fun setListener(listener: OnBeautyViewListener?) {
74+
listenerRef = WeakReference(listener)
75+
}
76+
77+
fun init(context: Context) {
78+
createBeautyKit(context)
79+
}
80+
81+
private fun createBeautyKit(context: Context) {
82+
checkBeautyResource(context, object : TUIServiceCallback() {
83+
override fun onServiceCallback(errorCode: Int, errorMessage: String?, bundle: Bundle?) {
84+
if (errorCode == 0) {
85+
initBeautyKit(context, true)
86+
}
87+
}
88+
})
89+
}
90+
91+
private fun initBeautyKit(context: Context, createPanel: Boolean) {
92+
val params = mapOf(
93+
"context" to context,
94+
"lastParamList" to lastParamList
95+
)
96+
TUICore.callService(TE_BEAUTY_EXTENSION, "initBeautyKit", params, object : TUIServiceCallback() {
97+
override fun onServiceCallback(errorCode: Int, errorMessage: String?, bundle: Bundle?) {
98+
if (errorCode != 0) {
99+
return
100+
}
101+
if (createPanel) {
102+
mainHandler.post {
103+
val beautyPanel = createTEBeautyPanel(context)
104+
beautyPanel?.let {
105+
listenerRef?.get()?.onCreateBeautyView(it)
106+
}
107+
}
108+
}
109+
}
110+
})
111+
}
112+
113+
fun checkBeautyResource(context: Context, callback: TUIServiceCallback? = null) {
114+
115+
val params = mapOf("context" to context)
116+
TUICore.callService(TE_BEAUTY_EXTENSION, "checkResource", params, object : TUIServiceCallback() {
117+
override fun onServiceCallback(errorCode: Int, errorMessage: String?, bundle: Bundle?) {
118+
isResourceLoaded = true
119+
callback?.onServiceCallback(errorCode, errorMessage, bundle)
120+
}
121+
})
122+
}
123+
124+
fun exportParam(): String {
125+
lastParamList = TUICore.callService(TE_BEAUTY_EXTENSION, "exportParam", null)?.toString() ?: "null"
126+
return lastParamList ?: ""
127+
}
128+
129+
private fun destroyBeautyKit() {
130+
TUICore.callService(TE_BEAUTY_EXTENSION, "destroyBeautyKit", null)
131+
}
132+
133+
private fun createTEBeautyPanel(context: Context): View? {
134+
val param = mapOf(
135+
"context" to context,
136+
"lastParamList" to lastParamList
137+
)
138+
return TUICore.getExtensionList("TEBeautyExtension", param)
139+
.firstNotNullOfOrNull { extensionInfo ->
140+
(extensionInfo.data["beautyPanel"] as? View)
141+
}
142+
}
143+
144+
interface OnBeautyViewListener {
145+
fun onCreateBeautyView(view: View)
146+
fun onDestroyBeautyView()
147+
}
148+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.tencent.qcloud.tuikit.tuicallkit.beauty.tebeauty
2+
3+
import android.content.Context
4+
import android.view.View
5+
import android.view.ViewGroup
6+
import android.widget.FrameLayout
7+
8+
class TEBeautyView(context: Context) : FrameLayout(context) {
9+
10+
override fun onAttachedToWindow() {
11+
super.onAttachedToWindow()
12+
init()
13+
}
14+
15+
override fun onDetachedFromWindow() {
16+
super.onDetachedFromWindow()
17+
unInit()
18+
}
19+
20+
private fun init() {
21+
TEBeautyManager.setListener(beautyListener)
22+
TEBeautyManager.init(context)
23+
}
24+
25+
private fun unInit() {
26+
TEBeautyManager.setListener(null)
27+
}
28+
29+
private val beautyListener = object : TEBeautyManager.OnBeautyViewListener {
30+
override fun onCreateBeautyView(view: View) {
31+
view.let {
32+
removeAllViews()
33+
(it.parent as? ViewGroup)?.removeView(view)
34+
addView(it)
35+
}
36+
}
37+
38+
override fun onDestroyBeautyView() {
39+
removeAllViews()
40+
}
41+
}
42+
}

call/tuicallkit-kt/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/manager/CallManager.kt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.tencent.qcloud.tuikit.tuicallkit.manager
22

33
import android.content.Context
4+
import android.util.Log
45
import com.tencent.cloud.tuikit.engine.call.TUICallDefine
56
import com.tencent.cloud.tuikit.engine.call.TUICallEngine
67
import com.tencent.cloud.tuikit.engine.common.TUICommonDefine
78
import com.tencent.imsdk.BaseConstants
9+
import com.tencent.imsdk.v2.V2TIMManager
10+
import com.tencent.imsdk.v2.V2TIMValueCallback
811
import com.tencent.liteav.TXLiteAVCode
912
import com.tencent.qcloud.tuicore.TUIConfig
1013
import com.tencent.qcloud.tuicore.util.ErrorMessageConverter
@@ -136,7 +139,7 @@ class CallManager private constructor(context: Context) {
136139
}
137140

138141
override fun onFailure(code: Int, desc: String) {
139-
Logger.e(TAG, "reject failed, errorCode: $code, errMsg: $desc")
142+
Logger.e(TAG, "hangup failed, errorCode: $code, errMsg: $desc")
140143
completion?.onFailure(code, desc)
141144
}
142145
})
@@ -277,7 +280,14 @@ class CallManager private constructor(context: Context) {
277280
sourceLanguage = SourceLanguage.CHINESE_ENGLISH,
278281
translationLanguages = mutableListOf(TranslationLanguage.ENGLISH)
279282
)
280-
AITranscriberStore.shared.startRealtimeTranscriber(transcriberConfig, null)
283+
AITranscriberStore.shared.startRealtimeTranscriber(transcriberConfig, object : CompletionHandler {
284+
override fun onSuccess() {
285+
observerTranscriber()
286+
}
287+
288+
override fun onFailure(code: Int, desc: String) {
289+
}
290+
})
281291
closeVAD()
282292
}
283293

@@ -314,6 +324,20 @@ class CallManager private constructor(context: Context) {
314324
TRTCCloud.sharedInstance(context).callExperimentalAPI(closeObj.toString())
315325
}
316326

327+
private fun observerTranscriber() {
328+
val param = JSONObject().apply {
329+
put("UIComponentType", 1402)
330+
}.toString()
331+
V2TIMManager.getInstance()
332+
.callExperimentalAPI("reportTUIFeatureUsage", param, object : V2TIMValueCallback<Any> {
333+
override fun onSuccess(t: Any?) {
334+
}
335+
override fun onError(code: Int, desc: String?) {
336+
Log.e(TAG, "reportFeatureUsage failed: $code $desc")
337+
}
338+
})
339+
}
340+
317341
private fun convertErrorMsg(errorCode: Int, errMsg: String): String {
318342
if (errorCode == BaseConstants.ERR_SVR_MSG_IN_PEER_BLACKLIST) {
319343
return context.getString(R.string.callkit_error_in_peer_blacklist)
@@ -338,6 +362,7 @@ class CallManager private constructor(context: Context) {
338362
// todo: 待补充 6017 、-3301 对应错误码后删除
339363
map[BaseConstants.ERR_INVALID_PARAMETERS] = context.getString(R.string.callkit_toast_error_call_user_not_exist)
340364
map[TXLiteAVCode.ERR_TRTC_ENTER_ROOM_FAILED] = context.getString(R.string.callkit_toast_error_call_failed)
365+
map[ERR_SVR_GROUP_HAS_ACTIVE_CALL] = context.getString(R.string.callkit_toast_error_group_call_has_active_call)
341366
return map
342367
}
343368

@@ -390,6 +415,7 @@ class CallManager private constructor(context: Context) {
390415

391416
companion object {
392417
private const val TAG = "CallManager"
418+
private const val ERR_SVR_GROUP_HAS_ACTIVE_CALL = 101012
393419
val instance: CallManager = CallManager(TUIConfig.getAppContext())
394420
private const val BLUR_LEVEL_HIGH = 3
395421
private const val BLUR_LEVEL_CLOSE = 0

call/tuicallkit-kt/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/state/GlobalState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class GlobalState private constructor() {
1313
var enableFloatWindow: Boolean = true
1414
var enableIncomingBanner: Boolean = false
1515
var enableVirtualBackground: Boolean = false
16-
var enableAITranscriber: Boolean = false
16+
var enableAITranscriber: Boolean = true
1717
var orientation = Constants.Orientation.Portrait
1818
var enableForceUseV2API = false
1919
var disableControlButtonSet: MutableSet<Constants.ControlButton> = CopyOnWriteArraySet()

0 commit comments

Comments
 (0)