@tencent-rtc/mcp 1.3.8 → 1.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/package.json +1 -1
  2. package/resource/doc/chatuikit/android/integration.md +499 -203
  3. package/resource/doc/chatuikit/android/workflow.md +713 -0
  4. package/resource/doc/chatuikit/flutter/integration.md +1 -1
  5. package/resource/doc/livekit/voice/android/voice-audience-list.md +334 -0
  6. package/resource/doc/livekit/voice/android/voice-audio-effect.md +380 -0
  7. package/resource/doc/livekit/voice/android/voice-barrage.md +565 -0
  8. package/resource/doc/livekit/voice/android/voice-co-guest-interaction.md +745 -0
  9. package/resource/doc/livekit/voice/android/voice-gift.md +822 -0
  10. package/resource/doc/livekit/voice/android/voice-host-interaction.md +703 -0
  11. package/resource/doc/livekit/voice/android/voice-integration.md +940 -0
  12. package/resource/doc/livekit/voice/android/voice-room-list.md +575 -0
  13. package/resource/doc/livekit/voice/flutter/voice-co-guest-interaction.md +675 -0
  14. package/resource/doc/livekit/voice/flutter/voice-integration.md +936 -0
  15. package/resource/doc/livekit/voice/ios/voice-audience-list.md +339 -0
  16. package/resource/doc/livekit/voice/ios/voice-audio-effect.md +370 -0
  17. package/resource/doc/livekit/voice/ios/voice-barrage.md +517 -0
  18. package/resource/doc/livekit/voice/ios/voice-co-guest-interaction.md +708 -0
  19. package/resource/doc/livekit/voice/ios/voice-gift.md +783 -0
  20. package/resource/doc/livekit/voice/ios/voice-host-interaction.md +770 -0
  21. package/resource/doc/livekit/voice/ios/voice-integration.md +898 -0
  22. package/resource/doc/livekit/voice/ios/voice-room-list.md +485 -0
  23. package/resource/doc/roomkit/vue/integration.md +179 -288
  24. package/resource/doc/roomkit/vue/workflow.md +499 -253
  25. package/resource/doc/tuicallkit/android/integration.md +539 -83
  26. package/resource/doc/tuicallkit/android/workflow.md +441 -0
  27. package/tools/common/present-scenario-choice.js +16 -0
  28. package/tools/common/present-scenario-choice.js.map +1 -0
  29. package/tools/definitions/get_native_call_uikit_integration_def.js +25 -9
  30. package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
  31. package/tools/definitions/get_native_chat_uikit_integration_def.js +36 -14
  32. package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
  33. package/tools/definitions/get_native_live_uikit_integration_def.js +55 -29
  34. package/tools/definitions/get_native_live_uikit_integration_def.js.map +1 -1
  35. package/tools/definitions/get_native_live_uikit_interaction_def.js +43 -54
  36. package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -1
  37. package/tools/definitions/get_web_room_feature_detail_def.js +52 -55
  38. package/tools/definitions/get_web_room_feature_detail_def.js.map +1 -1
  39. package/tools/definitions/get_web_room_uikit_integration_def.js +41 -25
  40. package/tools/definitions/get_web_room_uikit_integration_def.js.map +1 -1
  41. package/tools/definitions/present_scenario_choice_def.js +53 -0
  42. package/tools/definitions/present_scenario_choice_def.js.map +1 -0
  43. package/tools/definitions/record_prompt_def.js +26 -21
  44. package/tools/definitions/record_prompt_def.js.map +1 -1
  45. package/tools/definitions/record_result_def.js +20 -4
  46. package/tools/definitions/record_result_def.js.map +1 -1
  47. package/tools/index.js +2 -0
  48. package/tools/index.js.map +1 -1
  49. package/tools/live/get-native-live-uikit-integration.js +110 -34
  50. package/tools/live/get-native-live-uikit-integration.js.map +1 -1
  51. package/tools/live/get_native_live_uikit_interaction.js +128 -35
  52. package/tools/live/get_native_live_uikit_interaction.js.map +1 -1
  53. package/utils/report-cls-client.js +1 -1
  54. package/utils/report-es-client.js +1 -1
@@ -0,0 +1,940 @@
1
+ This document guides developers through building a voice chat room application with host broadcasting and audience participation features using the **AtomicXCore** SDK's `LiveListStore` and `LiveSeatStore`.
2
+
3
+ ## Core Concepts
4
+ <table>
5
+ <tr>
6
+ <td rowspan="1" colSpan="1" >**Core Concept**</td>
7
+
8
+ <td rowspan="1" colSpan="1" >**Type**</td>
9
+
10
+ <td rowspan="1" colSpan="1" >**Core Responsibilities & Description**</td>
11
+ </tr>
12
+
13
+ <tr>
14
+ <td rowspan="1" colSpan="1" >`LiveListStore`</td>
15
+
16
+ <td rowspan="1" colSpan="1" >`abstract class`</td>
17
+
18
+ <td rowspan="1" colSpan="1" >- `createLive()`: Start live stream as host.<br>- `endLive()`: End live stream as host.<br>- `joinLive()`: Audience joins live room.<br>- `leaveLive()`: Leave live room.</td>
19
+ </tr>
20
+
21
+ <tr>
22
+ <td rowspan="1" colSpan="1" >`LiveInfo`</td>
23
+
24
+ <td rowspan="1" colSpan="1" >`data class`</td>
25
+
26
+ <td rowspan="1" colSpan="1" >- `liveID`: Unique room identifier.<br>- `seatLayoutTemplateID`: Layout template ID (e.g., 600 for dynamic grid).</td>
27
+ </tr>
28
+
29
+ <tr>
30
+ <td rowspan="1" colSpan="1" >`LiveSeatStore`</td>
31
+
32
+ <td rowspan="1" colSpan="1" >`abstract class`</td>
33
+
34
+ <td rowspan="1" colSpan="1" >Core seat management class. Manages all seat information and seat-related operations in the room.<br>Provides a real-time seat list data stream via liveSeatState.seatList.</td>
35
+ </tr>
36
+
37
+ <tr>
38
+ <td rowspan="1" colSpan="1" >`LiveSeatState`</td>
39
+
40
+ <td rowspan="1" colSpan="1" >`data class`</td>
41
+
42
+ <td rowspan="1" colSpan="1" >Represents the current state of all seats.<br>- `seatList`: a StateFlow containing the real-time seat list.<br>- `speakingUsers`: users currently speaking and their volume.</td>
43
+ </tr>
44
+
45
+ <tr>
46
+ <td rowspan="1" colSpan="1" >`SeatInfo`</td>
47
+
48
+ <td rowspan="1" colSpan="1" >`data class`</td>
49
+
50
+ <td rowspan="1" colSpan="1" >Data model for a single seat. The seat list (seatList) emitted by LiveSeatStore is a list of SeatInfo objects.<br>Key fields:<br>- `index`: seat position.<br>- `isLocked`: whether the seat is locked.<br>- `userInfo`: user information for the seat. If the seat is empty, this field is empty.</td>
51
+ </tr>
52
+
53
+ <tr>
54
+ <td rowspan="1" colSpan="1" >`SeatUserInfo`</td>
55
+
56
+ <td rowspan="1" colSpan="1" >`data class`</td>
57
+
58
+ <td rowspan="1" colSpan="1" >Detailed data model for the user occupying a seat. When a user successfully takes a seat, the userInfo field in SeatInfo is populated.<br>Key fields:<br>- `userID`: unique user ID.<br>- `userName`: user nickname.<br>- `avatarURL`: user avatar URL.<br>- `microphoneStatus`: microphone status (on/off).<br>- `cameraStatus`: camera status (on/off).</td>
59
+ </tr>
60
+ </table>
61
+
62
+
63
+ ## Prerequisites
64
+
65
+ ### Step 1: Activate the Service
66
+
67
+ See [Activate Service](https://write.woa.com/document/141936672617742336) to obtain either the trial or paid version of the SDK.Then, go to [the Console](https://console.trtc.io/app) for application management, and get the following:
68
+ - `SDKAppID`: Application identifier (required). Tencent Cloud uses `SDKAppId` for billing and details.
69
+
70
+ - `SDKSecretKey`: Application secret key, used to initialize the configuration file with secret information.
71
+
72
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100027182498/018c103bc9f411f09e745254007c27c5.png)
73
+
74
+
75
+ ### Step 2: Import AtomicXCore into Your Project
76
+
77
+ **Install the component**: Add the dependency `implementation 'com.tencent.atomicx:atomicxcore:latest`' to your `build.gradle` file, then perform a **Gradle****Sync**.
78
+ ``` gradle
79
+ dependencies {
80
+ implementation 'io.trtc.uikit:atomicx-core:latest.release'
81
+ api "io.trtc.uikit:rtc_room_engine:3.4.0.1306"
82
+ api "io.trtc.uikit:atomicx-core:3.4.0.1307"
83
+ api "com.tencent.liteav:LiteAVSDK_Professional:12.8.0.19279"
84
+ api "com.tencent.imsdk:imsdk-plus:8.7.7201"
85
+ // Other dependencies...
86
+ }
87
+ ```
88
+
89
+ ### Step 3: Implement Login Logic
90
+
91
+ Call `LoginStore.shared.login` in your project to complete authentication. **This is required before using any functionality of AtomicXCore**.
92
+
93
+ > **Note:**
94
+ >
95
+
96
+ > We recommend calling `LoginStore.shared.login` after your app's own user authentication is successful to ensure clear and consistent login logic.
97
+ >
98
+
99
+ ``` java
100
+ import android.os.Bundle
101
+ import androidx.appcompat.app.AppCompatActivity
102
+ import io.trtc.tuikit.atomicxcore.api.login.LoginStore
103
+ import io.trtc.tuikit.atomicxcore.api.CompletionHandler
104
+ import android.util.Log
105
+
106
+ class MainActivity : AppCompatActivity() {
107
+ override fun onCreate(savedInstanceState: Bundle?) {
108
+ super.onCreate(savedInstanceState)
109
+
110
+ LoginStore.shared.login(
111
+ this, // context
112
+ 1400000001, // Replace with your SDKAppID
113
+ "test_001", // Replace with your UserID
114
+ "xxxxxxxxxxx", // Replace with your UserSig
115
+ object : CompletionHandler {
116
+ override fun onSuccess() {
117
+ // Handle login success
118
+ Log.d("Login", "login success")
119
+ }
120
+
121
+ override fun onFailure(code: Int, desc: String) {
122
+ // Handle login failure
123
+ Log.e("Login", "login failed, code: $code, error: $desc")
124
+ }
125
+ }
126
+ )
127
+ }
128
+ }
129
+ ```
130
+
131
+ **Login API Parameter Description**
132
+ <table>
133
+ <tr>
134
+ <td rowspan="1" colSpan="1" >Parameter</td>
135
+
136
+ <td rowspan="1" colSpan="1" >Type</td>
137
+
138
+ <td rowspan="1" colSpan="1" >Description</td>
139
+ </tr>
140
+
141
+ <tr>
142
+ <td rowspan="1" colSpan="1" >`sdkAppID`</td>
143
+
144
+ <td rowspan="1" colSpan="1" >`Int`</td>
145
+
146
+ <td rowspan="1" colSpan="1" >Get this from [TRTC console > Application management](https://console.trtc.io/app).</td>
147
+ </tr>
148
+
149
+ <tr>
150
+ <td rowspan="1" colSpan="1" >`userID`</td>
151
+
152
+ <td rowspan="1" colSpan="1" >`String`</td>
153
+
154
+ <td rowspan="1" colSpan="1" >The unique ID for the current user. Must contain only English letters, numbers, hyphens, and underscores.</td>
155
+ </tr>
156
+
157
+ <tr>
158
+ <td rowspan="1" colSpan="1" >`userSig`</td>
159
+
160
+ <td rowspan="1" colSpan="1" >`String`</td>
161
+
162
+ <td rowspan="1" colSpan="1" >A ticket for Tencent Cloud authentication. Please note:<br>- **Development Environment**: You can use the local `GenerateTestUserSig.genTestSig` function to generate a UserSig or generate a temporary UserSig via the [UserSig Generation Tool](https://console.trtc.io/usersig).<br>- **Production Environment**: To prevent key leakage, you must use a server-side method to generate UserSig. For details, see [Generating UserSig on the Server](https://write.woa.com/document/89644530319802368).<br>- For more information, see [How to Calculate and Use UserSig](https://write.woa.com/document/89644530319802368).</td>
163
+ </tr>
164
+ </table>
165
+
166
+
167
+ ## Building a Basic Voice Chat Room
168
+
169
+ ### Step 1: Host Room Creation
170
+
171
+ Follow the steps below to quickly set up a voice chat room as the host.
172
+
173
+ #### **1. Initialize the Seat **`Store`
174
+
175
+ In your host `Activity`, create a `LiveSeatStore` instance. Observe changes in `liveSeatState.seatList` to get real-time mic seat data and update your UI.
176
+ ``` java
177
+ import android.os.Bundle
178
+ import android.util.Log
179
+ import androidx.appcompat.app.AppCompatActivity
180
+ import io.trtc.tuikit.atomicxcore.api.device.DeviceStore
181
+ import io.trtc.tuikit.atomicxcore.api.live.LiveListStore
182
+ import io.trtc.tuikit.atomicxcore.api.live.LiveSeatStore
183
+ import kotlinx.coroutines.CoroutineScope
184
+ import kotlinx.coroutines.Dispatchers
185
+ import kotlinx.coroutines.launch
186
+
187
+ // YourHostActivity represents your Host Activity
188
+ class YourHostActivity : AppCompatActivity() {
189
+
190
+ private lateinit var liveListStore: LiveListStore
191
+ private lateinit var liveSeatStore: LiveSeatStore
192
+ private lateinit var deviceStore: DeviceStore
193
+ private val liveID = "test_voice_room_001"
194
+
195
+ override fun onCreate(savedInstanceState: Bundle?) {
196
+ super.onCreate(savedInstanceState)
197
+ setContentView(R.layout.activity_host) // Assume you have your own layout
198
+
199
+ // 1. Initialize Stores
200
+ liveListStore = LiveListStore.shared()
201
+ liveSeatStore = LiveSeatStore.create(liveID)
202
+ deviceStore = DeviceStore.shared()
203
+
204
+ // 2. Listen for mic seat list changes
205
+ observeSeatList()
206
+ }
207
+
208
+ private fun observeSeatList() {
209
+ // Listen for seatList changes and update your mic seat UI
210
+ CoroutineScope(Dispatchers.Main).launch {
211
+ liveSeatStore.liveSeatState.seatList.collect { seatInfoList ->
212
+ // Render your mic seat UI here based on seatInfoList
213
+ // Example: updateMicSeatView(seatInfoList)
214
+ Log.d("HostActivity", "Seat list updated: ${seatInfoList.size} seats")
215
+ }
216
+ }
217
+ }
218
+ }
219
+ ```
220
+
221
+ #### **2. **Turn On Microphone
222
+
223
+ Turn On Microphone by calling the `openLocalMicrophone` method from `DeviceStore`:
224
+ ``` java
225
+ import androidx.appcompat.app.AppCompatActivity
226
+ import io.trtc.tuikit.atomicxcore.api.device.DeviceStore
227
+
228
+ class YourHostActivity : AppCompatActivity() {
229
+ // ... Other code ...
230
+
231
+ private fun openDevices() {
232
+ // 1. Turn on the microphone
233
+ DeviceStore.shared().openLocalMicrophone(completion = null)
234
+ }
235
+ }
236
+ ```
237
+
238
+ #### **3. Start Voice Chat**
239
+
240
+ Start the live voice chat by calling the `createLive` method of `LiveListStore`:
241
+ ``` java
242
+ import android.os.Bundle
243
+ import android.util.Log
244
+ import androidx.appcompat.app.AppCompatActivity
245
+ import io.trtc.tuikit.atomicxcore.api.live.LiveInfo
246
+ import io.trtc.tuikit.atomicxcore.api.live.LiveInfoCompletionHandler
247
+ import io.trtc.tuikit.atomicxcore.api.live.TakeSeatMode
248
+
249
+ class YourHostActivity : AppCompatActivity() {
250
+ // ... Other code ...
251
+
252
+ override fun onCreate(savedInstanceState: Bundle?) {
253
+ super.onCreate(savedInstanceState)
254
+ // ... Other code ...
255
+
256
+ // Start voice chat
257
+ startLive()
258
+ }
259
+
260
+ private fun startLive() {
261
+ val liveInfo = LiveInfo().apply {
262
+ // 1. Set room id
263
+ liveID = this@YourHostActivity.liveID
264
+ // 2. Set room name
265
+ liveName = "test voice room"
266
+ // 3. Configure as a voice chat room (enable mic seats)
267
+ isSeatEnabled = true
268
+ // 4. Host takes mic by default
269
+ keepOwnerOnSeat = true
270
+ // 5. Set mic seat layout template (e.g., 70 for a 10-seat template)
271
+ seatLayoutTemplateID = 70
272
+ // 6. Set mic-taking mode, e.g., apply to take mic
273
+ seatMode = TakeSeatMode.APPLY
274
+ // 7. Set maximum number of mic seats
275
+ maxSeatCount = 10
276
+ }
277
+
278
+ // 8. Call createLive to start the stream
279
+ liveListStore.createLive(liveInfo, object : LiveInfoCompletionHandler {
280
+ override fun onFailure(code: Int, desc: String) {
281
+ Log.e("Live", "Response startLive onError: $desc")
282
+ }
283
+
284
+ override fun onSuccess(liveInfo: LiveInfo) {
285
+ Log.d("Live", "Response startLive onSuccess")
286
+ // After successful creation, the Host is on the mic by default, now you can call unmuteMicrophone
287
+ liveSeatStore.unmuteMicrophone(null)
288
+ }
289
+ })
290
+ }
291
+ }
292
+ ```
293
+
294
+ **LiveInfo Parameter Description**
295
+ <table>
296
+ <tr>
297
+ <td rowspan="1" colSpan="1" >**Parameter Name**</td>
298
+
299
+ <td rowspan="1" colSpan="1" >**Type**</td>
300
+
301
+ <td rowspan="1" colSpan="1" >**Required**</td>
302
+
303
+ <td rowspan="1" colSpan="1" >**Description**</td>
304
+ </tr>
305
+
306
+ <tr>
307
+ <td rowspan="1" colSpan="1" >`liveID`</td>
308
+
309
+ <td rowspan="1" colSpan="1" >`String`</td>
310
+
311
+ <td rowspan="1" colSpan="1" >Required</td>
312
+
313
+ <td rowspan="1" colSpan="1" >Unique identifier for the live room</td>
314
+ </tr>
315
+
316
+ <tr>
317
+ <td rowspan="1" colSpan="1" >`liveName`</td>
318
+
319
+ <td rowspan="1" colSpan="1" >`String`</td>
320
+
321
+ <td rowspan="1" colSpan="1" >Optional</td>
322
+
323
+ <td rowspan="1" colSpan="1" >Title of the live room</td>
324
+ </tr>
325
+
326
+ <tr>
327
+ <td rowspan="1" colSpan="1" >`notice`</td>
328
+
329
+ <td rowspan="1" colSpan="1" >`String`</td>
330
+
331
+ <td rowspan="1" colSpan="1" >Optional</td>
332
+
333
+ <td rowspan="1" colSpan="1" >Announcement information for the live room</td>
334
+ </tr>
335
+
336
+ <tr>
337
+ <td rowspan="1" colSpan="1" >`isMessageDisable`</td>
338
+
339
+ <td rowspan="1" colSpan="1" >`Boolean`</td>
340
+
341
+ <td rowspan="1" colSpan="1" >Optional</td>
342
+
343
+ <td rowspan="1" colSpan="1" >Mute status (`true`: muted, `false`: not muted)</td>
344
+ </tr>
345
+
346
+ <tr>
347
+ <td rowspan="1" colSpan="1" >`isPublicVisible`</td>
348
+
349
+ <td rowspan="1" colSpan="1" >`Boolean`</td>
350
+
351
+ <td rowspan="1" colSpan="1" >Optional</td>
352
+
353
+ <td rowspan="1" colSpan="1" >Public visibility (`true`: visible, `false`: hidden)</td>
354
+ </tr>
355
+
356
+ <tr>
357
+ <td rowspan="1" colSpan="1" >`isSeatEnabled`</td>
358
+
359
+ <td rowspan="1" colSpan="1" >`Boolean`</td>
360
+
361
+ <td rowspan="1" colSpan="1" >Optional</td>
362
+
363
+ <td rowspan="1" colSpan="1" >Enable mic seat feature (`true`: enabled, `false`: disabled)</td>
364
+ </tr>
365
+
366
+ <tr>
367
+ <td rowspan="1" colSpan="1" >`keepOwnerOnSeat`</td>
368
+
369
+ <td rowspan="1" colSpan="1" >`Boolean`</td>
370
+
371
+ <td rowspan="1" colSpan="1" >Optional</td>
372
+
373
+ <td rowspan="1" colSpan="1" >Keep host on mic seat</td>
374
+ </tr>
375
+
376
+ <tr>
377
+ <td rowspan="1" colSpan="1" >`maxSeatCount`</td>
378
+
379
+ <td rowspan="1" colSpan="1" >`Int`</td>
380
+
381
+ <td rowspan="1" colSpan="1" >Required</td>
382
+
383
+ <td rowspan="1" colSpan="1" >Maximum number of mic seats</td>
384
+ </tr>
385
+
386
+ <tr>
387
+ <td rowspan="1" colSpan="1" >`seatMode`</td>
388
+
389
+ <td rowspan="1" colSpan="1" >[TakeSeatMode](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-take-seat-mode/index.html)</td>
390
+
391
+ <td rowspan="1" colSpan="1" >Optional</td>
392
+
393
+ <td rowspan="1" colSpan="1" >Mic seat mode (`FREE`: free to take seat, `APPLY`: apply to take seat)</td>
394
+ </tr>
395
+
396
+ <tr>
397
+ <td rowspan="1" colSpan="1" >`seatLayoutTemplateID`</td>
398
+
399
+ <td rowspan="1" colSpan="1" >`Int`</td>
400
+
401
+ <td rowspan="1" colSpan="1" >Required</td>
402
+
403
+ <td rowspan="1" colSpan="1" >Mic seat layout template ID</td>
404
+ </tr>
405
+
406
+ <tr>
407
+ <td rowspan="1" colSpan="1" >`coverURL`</td>
408
+
409
+ <td rowspan="1" colSpan="1" >`String`</td>
410
+
411
+ <td rowspan="1" colSpan="1" >Optional</td>
412
+
413
+ <td rowspan="1" colSpan="1" >Cover image URL for the live room</td>
414
+ </tr>
415
+
416
+ <tr>
417
+ <td rowspan="1" colSpan="1" >`backgroundURL`</td>
418
+
419
+ <td rowspan="1" colSpan="1" >`String`</td>
420
+
421
+ <td rowspan="1" colSpan="1" >Optional</td>
422
+
423
+ <td rowspan="1" colSpan="1" >Background image URL for the live room</td>
424
+ </tr>
425
+
426
+ <tr>
427
+ <td rowspan="1" colSpan="1" >`categoryList`</td>
428
+
429
+ <td rowspan="1" colSpan="1" >`List<Int>`</td>
430
+
431
+ <td rowspan="1" colSpan="1" >Optional</td>
432
+
433
+ <td rowspan="1" colSpan="1" >Category tag list for the live room</td>
434
+ </tr>
435
+
436
+ <tr>
437
+ <td rowspan="1" colSpan="1" >`activityStatus`</td>
438
+
439
+ <td rowspan="1" colSpan="1" >`Int`</td>
440
+
441
+ <td rowspan="1" colSpan="1" >Optional</td>
442
+
443
+ <td rowspan="1" colSpan="1" >Live activity status</td>
444
+ </tr>
445
+ </table>
446
+
447
+
448
+ #### **4. Build the Mic Seat UI**
449
+
450
+ > **Note:**
451
+ >
452
+
453
+ > For the complete business logic of mic seat UI effects, refer to the open-source [SeatGridView.kt](https://github.com/Tencent-RTC/TUILiveKit/blob/main/Android/tuilivekit/src/main/java/com/trtc/uikit/livekit/voiceroomcore/SeatGridView.kt) in the TUILiveKit project.
454
+ >
455
+
456
+
457
+ Use the `LiveSeatStore` instance to observe changes in `liveSeatState.seatList` and update your UI in real time. In your Activity (such as `YourAnchorActivity` or `YourAudienceActivity`), observe the data as follows:
458
+ ``` java
459
+ import android.os.Bundle
460
+ import android.util.Log
461
+ import androidx.appcompat.app.AppCompatActivity
462
+ import kotlinx.coroutines.CoroutineScope
463
+ import kotlinx.coroutines.Dispatchers
464
+ import kotlinx.coroutines.launch
465
+
466
+ class YourHostActivity : AppCompatActivity() {
467
+ // ... Other code ...
468
+
469
+ override fun onCreate(savedInstanceState: Bundle?) {
470
+ super.onCreate(savedInstanceState)
471
+ // ... Other code ...
472
+
473
+ // Listen for seatList changes
474
+ observeSeatList()
475
+ }
476
+
477
+ private fun observeSeatList() {
478
+ // Listen for seatList changes and update your mic seat UI
479
+ CoroutineScope(Dispatchers.Main).launch {
480
+ liveSeatStore.liveSeatState.seatList.collect { seatInfoList ->
481
+ // seatInfoList is the latest mic seat list (List<SeatInfo>), render your mic seat UI here based on seatInfoList
482
+ Log.d("HostActivity", "Seat list updated: ${seatInfoList.size} seats")
483
+ }
484
+ }
485
+ }
486
+ }
487
+ ```
488
+
489
+ #### **5. End Voice Chat**
490
+
491
+ To end the voice chat, call the `endLive` method of `LiveListStore`. The SDK will handle stopping the stream and destroying the room.
492
+ ``` java
493
+ import android.util.Log
494
+ import androidx.appcompat.app.AppCompatActivity
495
+ import com.tencent.cloud.tuikit.engine.extension.TUILiveListManager
496
+ import io.trtc.tuikit.atomicxcore.api.live.StopLiveCompletionHandler
497
+
498
+ class YourHostActivity : AppCompatActivity() {
499
+ // ... Other code ...
500
+
501
+ // End voice chat
502
+ private fun stopLive() {
503
+ liveListStore.endLive(object : StopLiveCompletionHandler {
504
+ override fun onSuccess(statisticsData: TUILiveListManager.LiveStatisticsData) {
505
+ Log.d("Live", "endLive success, duration: ${statisticsData.liveDuration}")
506
+ }
507
+
508
+ override fun onFailure(code: Int, desc: String) {
509
+ Log.e("Live", "endLive error: $desc")
510
+ }
511
+ })
512
+ }
513
+
514
+ // Ensure this is also called when the Activity is destroyed
515
+ override fun onDestroy() {
516
+ super.onDestroy()
517
+ stopLive()
518
+ Log.d("Live", "YourHostActivity onDestroy")
519
+ }
520
+ }
521
+ ```
522
+
523
+ ### Step 2: Audience Joins the Voice Chat Room
524
+
525
+ Follow these steps to allow audience members to join the voice chat room.
526
+
527
+ #### **1. Initialize the Mic Seat Store**
528
+
529
+ In your audience `Activity`, create a `LiveSeatStore` instance and observe changes in `liveSeatState.seatList` to update the mic seat UI.
530
+ ``` java
531
+ import io.trtc.tuikit.atomicxcore.api.live.LiveListStore
532
+ import io.trtc.tuikit.atomicxcore.api.live.LiveSeatStore
533
+ import android.os.Bundle
534
+ import androidx.appcompat.app.AppCompatActivity
535
+ import kotlinx.coroutines.CoroutineScope
536
+ import kotlinx.coroutines.Dispatchers
537
+ import kotlinx.coroutines.launch
538
+ import android.util.Log
539
+
540
+ // YourAudienceActivity represents your Audience Activity
541
+ class YourAudienceActivity : AppCompatActivity() {
542
+
543
+ private lateinit var liveListStore: LiveListStore
544
+ private lateinit var liveSeatStore: LiveSeatStore
545
+ private val liveID = "test_voice_room_001" // Ensure liveID matches the Host's
546
+
547
+ override fun onCreate(savedInstanceState: Bundle?) {
548
+ super.onCreate(savedInstanceState)
549
+ setContentView(R.layout.activity_audience) // Assume you have your own layout
550
+
551
+ // 1. Initialize Stores
552
+ liveListStore = LiveListStore.shared()
553
+ liveSeatStore = LiveSeatStore.create(liveID)
554
+
555
+ // 2. Listen for mic seat list changes
556
+ observeSeatList()
557
+ }
558
+
559
+ private fun observeSeatList() {
560
+ // 3. Listen for seatList changes and update your mic seat UI
561
+ CoroutineScope(Dispatchers.Main).launch {
562
+ liveSeatStore.liveSeatState.seatList.collect { seatInfoList ->
563
+ // Render your mic seat UI here based on seatInfoList
564
+ // Example: updateMicSeatView(seatInfoList)
565
+ Log.d("AudienceActivity", "Seat list updated: ${seatInfoList.size} seats")
566
+ }
567
+ }
568
+ }
569
+ }
570
+ ```
571
+
572
+ #### **2. Join Voice Chat Room**
573
+
574
+ Join the voice chat room by calling the `joinLive` method of `LiveListStore`:
575
+ ``` java
576
+ import android.os.Bundle
577
+ import androidx.appcompat.app.AppCompatActivity
578
+ import android.util.Log
579
+ import io.trtc.tuikit.atomicxcore.api.live.LiveInfo
580
+ import io.trtc.tuikit.atomicxcore.api.live.LiveInfoCompletionHandler
581
+
582
+ // YourAudienceActivity represents your Audience Activity
583
+ class YourAudienceActivity : AppCompatActivity() {
584
+
585
+ // ... Other code ...
586
+ override fun onCreate(savedInstanceState: Bundle?) {
587
+ super.onCreate(savedInstanceState)
588
+ setContentView(R.layout.activity_audience) // Assume you have your own layout
589
+ // ... Other code ...
590
+
591
+ // Enter voice chat room
592
+ joinLive()
593
+ }
594
+
595
+ private fun joinLive() {
596
+ // 1. Call joinLive to enter the voice chat room
597
+ liveListStore.joinLive(liveID, object : LiveInfoCompletionHandler {
598
+ override fun onSuccess(liveInfo: LiveInfo) {
599
+ Log.d("Live", "joinLive success")
600
+ }
601
+ override fun onFailure(code: Int, desc: String) {
602
+ Log.e("Live", "joinLive error: $desc")
603
+ }
604
+ })
605
+ }
606
+ }
607
+ ```
608
+
609
+ #### **3. Build the Mic Seat UI**
610
+
611
+ The process for building the mic seat UI as an audience member is the same as for the host. Refer to the host [Build the Mic Seat UI](https://write.woa.com/#9a917c47-816f-4930-81b1-d35ee01c519d).
612
+
613
+ #### **4. Leave the Voice Chat Room**
614
+
615
+ When an audience member leaves the voice chat room, call the `leaveLive` method of `LiveListStore`:
616
+ ``` java
617
+ import android.util.Log
618
+ import androidx.appcompat.app.AppCompatActivity
619
+ import io.trtc.tuikit.atomicxcore.api.CompletionHandler
620
+
621
+ // YourAudienceActivity represents your Audience Activity
622
+ class YourAudienceActivity : AppCompatActivity() {
623
+ // ... Other code ...
624
+
625
+ private fun leaveLive() {
626
+ liveListStore.leaveLive(object : CompletionHandler {
627
+ override fun onSuccess() {
628
+ Log.d("Live", "leaveLive success")
629
+ }
630
+
631
+ override fun onFailure(code: Int, desc: String) {
632
+ Log.e("Live", "leaveLive error: $desc")
633
+ }
634
+ })
635
+ }
636
+
637
+ // Ensure this is also called when the Activity is destroyed
638
+ override fun onDestroy() {
639
+ super.onDestroy()
640
+ leaveLive()
641
+ Log.d("Live", "YourAudienceActivity onDestroy")
642
+ }
643
+ }
644
+ ```
645
+
646
+ ### Run and Test
647
+
648
+ After completing the steps above, you will have a basic voice chat live streaming setup. For more advanced features, see the "Enrich Voice Chat Room Scenarios" section.
649
+
650
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100027182498/159d41cdc9f411f0b011525400bf7822.png)
651
+
652
+ ## Advanced Features
653
+
654
+ ### **Implementing Speaking Wave Animation for Mic Seat Users**
655
+
656
+ In voice chat rooms, it is common to show a wave animation on the avatar of users who are speaking, so everyone can see who is currently talking. `LiveSeatStore` provides a `speakingUsers` data stream for this purpose.
657
+
658
+ #### Example
659
+
660
+ #### ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100027182498/159f07ffc9f411f09e745254007c27c5.gif)
661
+
662
+ #### Implementation
663
+
664
+ > **Note:**
665
+ >
666
+
667
+ > For a complete implementation of the speaking wave animation, refer to [SeatGridView.kt](https://github.com/Tencent-RTC/TUILiveKit/blob/main/Android/tuilivekit/src/main/java/com/trtc/uikit/livekit/voiceroomcore/SeatGridView.kt) in the open-source TUILiveKit project.
668
+ >
669
+
670
+
671
+ In `YourAnchorActivity`, observe changes in `speakingUsers` and update the UI to reflect the speaking status:
672
+ ``` java
673
+ import android.os.Bundle
674
+ import android.util.Log
675
+ import androidx.appcompat.app.AppCompatActivity
676
+ import kotlinx.coroutines.CoroutineScope
677
+ import kotlinx.coroutines.Dispatchers
678
+ import kotlinx.coroutines.launch
679
+
680
+ // In YourHostActivity or YourAudienceActivity
681
+ class YourHostActivity : AppCompatActivity() {
682
+ // ... (omitting other code) ...
683
+
684
+ override fun onCreate(savedInstanceState: Bundle?) {
685
+ super.onCreate(savedInstanceState)
686
+ // ... (omitting other code) ...
687
+
688
+ // Listen for speakingUsers changes
689
+ observeSpeakingUsersState()
690
+ }
691
+
692
+ private fun observeSpeakingUsersState() {
693
+ // Listen for speakingUsers changes and update the "currently speaking" status
694
+ CoroutineScope(Dispatchers.Main).launch {
695
+ liveSeatStore.liveSeatState.speakingUsers.collect { speakingUserSet ->
696
+ // Pass the set of "currently speaking" user IDs to the UI, update UI state
697
+ Log.d("HostActivity", "Speaking users updated: ${speakingUserSet.size} users")
698
+ }
699
+ }
700
+ }
701
+ }
702
+ ```
703
+
704
+ ### Synchronizing Custom State in Live Streaming Room
705
+
706
+ In Live Streaming Room, hosts may need to synchronize custom information with all participants, such as the current room topic or background music. The `metaData` feature of `LiveListStore` supports this use case.
707
+
708
+ #### Implementation
709
+ 1. On the host side, set custom information using the `updateLiveMetaData` API. `AtomicXCore` synchronizes these changes in real time to all participants.
710
+
711
+ 2. On the audience side, subscribe to `LiveListState.currentLive` and listen for changes in `metaData`. When a relevant key is updated, parse its value and update your business logic.
712
+
713
+
714
+ #### Code Example
715
+ ``` kotlin
716
+ import io.trtc.tuikit.atomicxcore.api.LiveListStore
717
+ import io.trtc.tuikit.atomicxcore.api.CompletionHandler
718
+ import com.google.gson.Gson
719
+ import io.trtc.tuikit.atomicxcore.api.MetaDataCompletionHandler
720
+ import io.trtc.tuikit.atomicxcore.api.LiveListStore
721
+
722
+ // 1. Define a background music model (using data class)
723
+ data class MusicModel(
724
+ val musicId: String,
725
+ val musicName: String
726
+ )
727
+
728
+ // 2. Host side: Add a method to push background music in your Host business logic
729
+ fun updateBackgroundMusic(music: MusicModel) {
730
+ val gson = Gson()
731
+ val jsonString = gson.toJson(music) ?: ""
732
+
733
+ // The metaData to be updated
734
+ val metaData = hashMapOf("music_info" to jsonString)
735
+
736
+ // Update metaData
737
+ LiveListStore.shared()
738
+ .updateLiveMetaData(
739
+ metaData,
740
+ object : CompletionHandler {
741
+ override fun onSuccess() {
742
+ print("Background music ${music.musicName} pushed successfully")
743
+ }
744
+
745
+ override fun onFailure(code: Int, desc: String) {
746
+ print("Failed to push background music: $desc")
747
+ }
748
+ }
749
+ )
750
+ }
751
+
752
+ // 3. Audience side: Add a method to listen for background music changes in your Audience business logic
753
+ private fun subscribeToDataUpdates() {
754
+ CoroutineScope(Dispatchers.Main).launch {
755
+ LiveListStore.shared()
756
+ .liveState
757
+ .currentLive
758
+ .map { it.metaData }
759
+ .collect {
760
+ val musicInfo = it["music_info"]
761
+ // Refresh business state, e.g., play new background music
762
+ }
763
+ }
764
+ }
765
+ ```
766
+
767
+ ## Enrich Voice Chat Room Scenarios
768
+
769
+ After implementing the basic voice chat room, you can add more interactive features by referring to the following guides:
770
+ <table>
771
+ <tr>
772
+ <td rowspan="1" colSpan="1" >**Feature**</td>
773
+
774
+ <td rowspan="1" colSpan="1" >**Feature Description**</td>
775
+
776
+ <td rowspan="1" colSpan="1" >**Feature Stores**</td>
777
+
778
+ <td rowspan="1" colSpan="1" >**Implementation Guide**</td>
779
+ </tr>
780
+
781
+ <tr>
782
+ <td rowspan="1" colSpan="1" >**Enable Audience to Take Mic Seat**</td>
783
+
784
+ <td rowspan="1" colSpan="1" >Audience can apply to take a mic seat and interact with the host in real time.</td>
785
+
786
+ <td rowspan="1" colSpan="1" >[CoGuestStore](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-co-guest-store/index.html)</td>
787
+
788
+ <td rowspan="1" colSpan="1" >[Implementation](https://write.woa.com/document/194571595728519168)</td>
789
+ </tr>
790
+
791
+ <tr>
792
+ <td rowspan="1" colSpan="1" >**Host Cross-Room Connection & PK**</td>
793
+
794
+ <td rowspan="1" colSpan="1" >Hosts from different rooms can connect for interaction or PK.</td>
795
+
796
+ <td rowspan="1" colSpan="1" >[CoHostStore](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-co-host-store/index.html)<br>[BattleStore](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-battle-store/index.html)</td>
797
+
798
+ <td rowspan="1" colSpan="1" >[Implementation](https://write.woa.com/document/194571595874271232)</td>
799
+ </tr>
800
+
801
+ <tr>
802
+ <td rowspan="1" colSpan="1" >**Add Barrage Chat**</td>
803
+
804
+ <td rowspan="1" colSpan="1" >Members in the room can send and receive real-time text messages.</td>
805
+
806
+ <td rowspan="1" colSpan="1" >[BarrageStore](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.barrage/-barrage-store/index.html)</td>
807
+
808
+ <td rowspan="1" colSpan="1" >[Implementation](https://write.woa.com/document/195218523636584448)</td>
809
+ </tr>
810
+
811
+ <tr>
812
+ <td rowspan="1" colSpan="1" >**Build Gift System**</td>
813
+
814
+ <td rowspan="1" colSpan="1" >Audience can send virtual gifts to hosts to increase engagement and fun.</td>
815
+
816
+ <td rowspan="1" colSpan="1" >[GiftStore](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.gift/-gift-store/index.html)</td>
817
+
818
+ <td rowspan="1" colSpan="1" >[Implementation](https://write.woa.com/document/195218406705512448)</td>
819
+ </tr>
820
+ </table>
821
+
822
+
823
+ ## API Documentation
824
+ <table>
825
+ <tr>
826
+ <td rowspan="1" colSpan="1" >**Store/Component**</td>
827
+
828
+ <td rowspan="1" colSpan="1" >**Feature Description**</td>
829
+
830
+ <td rowspan="1" colSpan="1" >**API Documentation**</td>
831
+ </tr>
832
+
833
+ <tr>
834
+ <td rowspan="1" colSpan="1" >`LiveListStore`</td>
835
+
836
+ <td rowspan="1" colSpan="1" >Manages the full lifecycle of live rooms: create, join, leave, destroy rooms; query room list; modify live info (name, announcement, etc.); listen to live status (such as being kicked out, ended).</td>
837
+
838
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-live-list-store/index.html)</td>
839
+ </tr>
840
+
841
+ <tr>
842
+ <td rowspan="1" colSpan="1" >`LiveSeatStore`</td>
843
+
844
+ <td rowspan="1" colSpan="1" >Core mic seat management: manage mic seat list, user status, seat operations (take seat, leave seat, kick, lock, toggle microphone/camera, etc.), listen to mic seat events.</td>
845
+
846
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-live-seat-store/index.html)</td>
847
+ </tr>
848
+
849
+ <tr>
850
+ <td rowspan="1" colSpan="1" >`DeviceStore`</td>
851
+
852
+ <td rowspan="1" colSpan="1" >Audio/video device control: microphone (toggle/volume), camera (toggle/switch/quality), screen sharing, real-time device status monitoring.</td>
853
+
854
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.device/-device-store/index.html)</td>
855
+ </tr>
856
+
857
+ <tr>
858
+ <td rowspan="1" colSpan="1" >`CoGuestStore`</td>
859
+
860
+ <td rowspan="1" colSpan="1" >Audience co-host management: co-host application/invitation/approval/rejection, member permission control (microphone/camera), status synchronization.</td>
861
+
862
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-co-guest-store/index.html)</td>
863
+ </tr>
864
+
865
+ <tr>
866
+ <td rowspan="1" colSpan="1" >`CoHostStore`</td>
867
+
868
+ <td rowspan="1" colSpan="1" >Host cross-room connection: supports multiple layout templates (dynamic grid, etc.), initiate/accept/reject connection, manage co-host interaction.</td>
869
+
870
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-co-host-store/index.html)</td>
871
+ </tr>
872
+
873
+ <tr>
874
+ <td rowspan="1" colSpan="1" >`BattleStore`</td>
875
+
876
+ <td rowspan="1" colSpan="1" >Host PK battle: initiate PK (set duration/opponent), manage PK status (start/end), synchronize scores, listen to battle results.</td>
877
+
878
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-battle-store/index.html)</td>
879
+ </tr>
880
+
881
+ <tr>
882
+ <td rowspan="1" colSpan="1" >`GiftStore`</td>
883
+
884
+ <td rowspan="1" colSpan="1" >Gift interaction: get gift list, send/receive gifts, listen to gift events (including sender and gift details).</td>
885
+
886
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.gift/-gift-store/index.html)</td>
887
+ </tr>
888
+
889
+ <tr>
890
+ <td rowspan="1" colSpan="1" >`BarrageStore`</td>
891
+
892
+ <td rowspan="1" colSpan="1" >Bullet chat feature: send text/custom barrage, maintain barrage list, real-time barrage status monitoring.</td>
893
+
894
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.barrage/-barrage-store/index.html)</td>
895
+ </tr>
896
+
897
+ <tr>
898
+ <td rowspan="1" colSpan="1" >`LikeStore`</td>
899
+
900
+ <td rowspan="1" colSpan="1" >Like interaction: send likes, listen to like events, synchronize total like count.</td>
901
+
902
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-like-store/index.html)</td>
903
+ </tr>
904
+
905
+ <tr>
906
+ <td rowspan="1" colSpan="1" >`LiveAudienceStore`</td>
907
+
908
+ <td rowspan="1" colSpan="1" >Audience management: get real-time audience list (ID/name/avatar), count audience number, listen to audience join/leave events.</td>
909
+
910
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.live/-live-audience-store/index.html)</td>
911
+ </tr>
912
+
913
+ <tr>
914
+ <td rowspan="1" colSpan="1" >`AudioEffectStore`</td>
915
+
916
+ <td rowspan="1" colSpan="1" >Audio effects: voice changer (child/male), reverb (KTV, etc.), ear monitor adjustment, real-time effect switching.</td>
917
+
918
+ <td rowspan="1" colSpan="1" >[API Documentation](https://tencent-rtc.github.io/TUIKit_Android/-atomic-x%20-core%20-a-p-i/io.trtc.tuikit.atomicxcore.api.device/-audio-effect-store/index.html)</td>
919
+ </tr>
920
+ </table>
921
+
922
+
923
+ ## FAQs
924
+
925
+ ### Why is there no sound after the audience calls joinLive?
926
+ - **Check device permissions:** Ensure the app has system permission to use the microphone.
927
+
928
+ - **Check the host:** Confirm the host has called `DeviceStore.shared().openLocalMicrophone(null)` to enable the microphone.
929
+
930
+ - **Check the network:** Ensure the device's network connection is stable.
931
+
932
+
933
+ ### Why is the mic seat list not displayed or not updating?
934
+ - **Check store initialization:** Make sure you have created the `LiveSeatStore` instance with the same `liveID` before calling `createLive` or `joinLive` (`LiveSeatStore.create(liveID)`).
935
+
936
+ - **Check data observation:** Ensure you are observing the `liveSeatStore.liveSeatState.seatList` data stream.
937
+
938
+ - **Check API calls:** Confirm that `createLive` (host) or `joinLive` (audience) was successfully called (check the `onSuccess` callback).åå
939
+
940
+