@tencentcloud/sdk-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 (70) hide show
  1. package/package.json +1 -1
  2. package/resource/doc/chatuikit/android/integration.md +466 -484
  3. package/resource/doc/chatuikit/android/workflow.md +713 -0
  4. package/resource/doc/livekit/live/flutter/live-integration.md +208 -167
  5. package/resource/doc/livekit/voice/android/voice-audience-list.md +335 -0
  6. package/resource/doc/livekit/voice/android/voice-audio-effect.md +384 -0
  7. package/resource/doc/livekit/voice/android/voice-barrage.md +569 -0
  8. package/resource/doc/livekit/voice/android/voice-co-guest-interaction.md +748 -0
  9. package/resource/doc/livekit/voice/android/voice-gift.md +833 -0
  10. package/resource/doc/livekit/voice/android/voice-host-interaction.md +728 -0
  11. package/resource/doc/livekit/voice/android/voice-integration.md +886 -0
  12. package/resource/doc/livekit/voice/android/voice-room-list.md +493 -0
  13. package/resource/doc/livekit/voice/android/workflow.md +333 -0
  14. package/resource/doc/livekit/voice/flutter/voice-audience-list.md +337 -0
  15. package/resource/doc/livekit/voice/flutter/voice-audio-effect.md +739 -0
  16. package/resource/doc/livekit/voice/flutter/voice-barrage.md +578 -0
  17. package/resource/doc/livekit/voice/flutter/voice-co-guest-interaction.md +673 -0
  18. package/resource/doc/livekit/voice/flutter/voice-gift.md +812 -0
  19. package/resource/doc/livekit/voice/flutter/voice-integration.md +925 -0
  20. package/resource/doc/livekit/voice/flutter/voice-room-list.md +842 -0
  21. package/resource/doc/livekit/voice/flutter/workflow.md +359 -0
  22. package/resource/doc/livekit/voice/ios/voice-audience-list.md +335 -0
  23. package/resource/doc/livekit/voice/ios/voice-audio-effect.md +373 -0
  24. package/resource/doc/livekit/voice/ios/voice-barrage.md +529 -0
  25. package/resource/doc/livekit/voice/ios/voice-co-guest-interaction.md +701 -0
  26. package/resource/doc/livekit/voice/ios/voice-gift.md +785 -0
  27. package/resource/doc/livekit/voice/ios/voice-host-interaction.md +820 -0
  28. package/resource/doc/livekit/voice/ios/voice-integration.md +853 -0
  29. package/resource/doc/livekit/voice/ios/voice-room-list.md +467 -0
  30. package/resource/doc/livekit/voice/ios/workflow.md +358 -0
  31. package/resource/doc/livekit/voice/uni-app/voice-audience-list.md +264 -0
  32. package/resource/doc/livekit/voice/uni-app/voice-audio-effect.md +332 -0
  33. package/resource/doc/livekit/voice/uni-app/voice-barrage.md +482 -0
  34. package/resource/doc/livekit/voice/uni-app/voice-co-guest-interaction.md +944 -0
  35. package/resource/doc/livekit/voice/uni-app/voice-gift.md +716 -0
  36. package/resource/doc/livekit/voice/uni-app/voice-integration.md +613 -0
  37. package/resource/doc/livekit/voice/uni-app/voice-room-list.md +562 -0
  38. package/resource/doc/livekit/voice/uni-app/workflow.md +369 -0
  39. package/resource/doc/roomkit/vue/integration.md +119 -224
  40. package/resource/doc/roomkit/vue/workflow.md +472 -226
  41. package/resource/doc/tuicallkit/android/integration.md +675 -90
  42. package/resource/doc/tuicallkit/android/workflow.md +432 -0
  43. package/tools/common/present-scenario-choice.js +16 -0
  44. package/tools/common/present-scenario-choice.js.map +1 -0
  45. package/tools/definitions/get_native_call_uikit_integration_def.js +18 -2
  46. package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
  47. package/tools/definitions/get_native_chat_uikit_integration_def.js +29 -7
  48. package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
  49. package/tools/definitions/get_native_live_uikit_integration_def.js +65 -40
  50. package/tools/definitions/get_native_live_uikit_integration_def.js.map +1 -1
  51. package/tools/definitions/get_native_live_uikit_interaction_def.js +42 -94
  52. package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -1
  53. package/tools/definitions/get_web_room_feature_detail_def.js +29 -32
  54. package/tools/definitions/get_web_room_feature_detail_def.js.map +1 -1
  55. package/tools/definitions/get_web_room_uikit_integration_def.js +25 -9
  56. package/tools/definitions/get_web_room_uikit_integration_def.js.map +1 -1
  57. package/tools/definitions/present_scenario_choice_def.js +53 -0
  58. package/tools/definitions/present_scenario_choice_def.js.map +1 -0
  59. package/tools/definitions/record_prompt_def.js +6 -1
  60. package/tools/definitions/record_prompt_def.js.map +1 -1
  61. package/tools/definitions/record_result_def.js +20 -4
  62. package/tools/definitions/record_result_def.js.map +1 -1
  63. package/tools/index.js +2 -0
  64. package/tools/index.js.map +1 -1
  65. package/tools/live/get-native-live-uikit-integration.js +110 -34
  66. package/tools/live/get-native-live-uikit-integration.js.map +1 -1
  67. package/tools/live/get_native_live_uikit_interaction.js +128 -35
  68. package/tools/live/get_native_live_uikit_interaction.js.map +1 -1
  69. package/utils/report-cls-client.js +1 -1
  70. package/utils/report-es-client.js +1 -1
@@ -0,0 +1,925 @@
1
+ 本文档将帮助开发者使用 `AtomicXCore SDK` 的 `LiveListStore` 和 `LiveSeatStore` 快速构建一个包含主播开播和观众进房功能的语聊房 `App`。
2
+
3
+ ## 核心概念
4
+
5
+ 在开始集成之前,请先通过下表了解一下 `LiveSeatStore` 相关的几个核心概念:
6
+ <table>
7
+ <tr>
8
+ <td rowspan="1" colSpan="1" >**核心概念**</td>
9
+
10
+ <td rowspan="1" colSpan="1" >**类型**</td>
11
+
12
+ <td rowspan="1" colSpan="1" >**核心职责与描述**</td>
13
+ </tr>
14
+
15
+ <tr>
16
+ <td rowspan="1" colSpan="1" >[LiveSeatStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_seat_store/LiveSeatStore-class.html)</td>
17
+
18
+ <td rowspan="1" colSpan="1" >`class`</td>
19
+
20
+ <td rowspan="1" colSpan="1" >麦位管理核心,负责管理房间内的所有麦位信息和麦位相关操作。<br>通过 `liveSeatState.seatList` 暴露实时的麦位列表数据流。</td>
21
+ </tr>
22
+
23
+ <tr>
24
+ <td rowspan="1" colSpan="1" >[LiveSeatState](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_seat_store/LiveSeatState-class.html)</td>
25
+
26
+ <td rowspan="1" colSpan="1" >`class`</td>
27
+
28
+ <td rowspan="1" colSpan="1" >代表麦位的当前状态。<br>- `seatList` 是一个 `ValueListenable<List<SeatInfo>>` 类型,存储了麦位列表的实时状态;<br>- `speakingUsers` 则代表当前正在说话的人和对应的音量。</td>
29
+ </tr>
30
+
31
+ <tr>
32
+ <td rowspan="1" colSpan="1" >[SeatInfo](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_seat_store/SeatInfo-class.html)</td>
33
+
34
+ <td rowspan="1" colSpan="1" >`class`</td>
35
+
36
+ <td rowspan="1" colSpan="1" >单个麦位的数据模型。`LiveSeatStore` 所推送的麦位列表(`seatList`)就是由多个 `SeatInfo` 对象组成的。关键字段:<br>- `index`(麦位的索引)。<br>- `isLocked`(麦位是否被锁定)。<br>- `userInfo`(麦位上的用户信息,如果麦位为空,此字段也为空对象)。</td>
37
+ </tr>
38
+
39
+ <tr>
40
+ <td rowspan="1" colSpan="1" >[SeatUserInfo](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_seat_store/SeatUserInfo-class.html)</td>
41
+
42
+ <td rowspan="1" colSpan="1" >`class`</td>
43
+
44
+ <td rowspan="1" colSpan="1" >麦上用户的详细数据模型。当一个用户成功上麦后,`SeatInfo` 中的 `userInfo` 字段就会被填充为此用户。关键字段:<br>- `userID`(用户的唯一 ID)<br>- `userName`(用户的昵称)<br>- `avatarURL`(用户的头像 URL)<br>- `microphoneStatus`(麦克风状态)<br>- `cameraStatus`(摄像头状态)。</td>
45
+ </tr>
46
+ </table>
47
+
48
+
49
+ ## 准备工作
50
+
51
+ ### 步骤1:开通服务
52
+
53
+ 请参见 [开通服务](https://write.woa.com/document/141302177829593088),获取体验版或付费版 `SDK`。
54
+
55
+ ### 步骤2:在当前项目中导入 AtomicXCore
56
+ 1. **安装组件**:请在您的 `pubspec.yaml` 文件中添加 `atomic_x_core` 依赖,然后执行 `flutter pub get`。
57
+
58
+ ``` yaml
59
+ dependencies:
60
+ atomic_x_core: ^3.6.0
61
+ ```
62
+ 2. **配置工程权限:**Android 和 iOS 工程都需要配置权限。
63
+
64
+
65
+
66
+
67
+ 【Android】
68
+
69
+ 在 `android/app/src/main/AndroidManifest.xml` 文件中添加麦克风的使用权限说明。
70
+ ``` xml
71
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
72
+ ```
73
+
74
+ 【iOS】
75
+
76
+ 在应用 `ios` 目录的 **Podfile** 和 `ios/Runner` 目录的 `Info.plist` 文件中添加麦克风的使用权限说明。
77
+
78
+ **Podfile**
79
+ ``` ruby
80
+ post_install do |installer|
81
+ installer.pods_project.targets.each do |target|
82
+ flutter_additional_ios_build_settings(target)
83
+ target.build_configurations.each do |config|
84
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
85
+ '$(inherited)',
86
+ 'PERMISSION_MICROPHONE=1',
87
+ ]
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
93
+ **Info.plist**
94
+ ``` xml
95
+ <key>NSMicrophoneUsageDescription</key>
96
+ <string>TUILiveKit需要访问您的麦克风权限,开启后录制的视频才会有声音</string>
97
+ ```
98
+
99
+
100
+ ### 步骤3:实现登录逻辑
101
+
102
+ 在项目中调用 `LoginStore.shared.login` 完成登录,**这是使用 **`AtomicXCore`** 所有功能的关键前提**。
103
+
104
+ > **重要:**
105
+ >
106
+
107
+ > 推荐在您 App 自身的用户账户登录成功后,再调用 LoginStore.shared.login,以确保登录业务逻辑的清晰和一致。
108
+ >
109
+
110
+ ``` java
111
+ import 'package:flutter/material.dart';
112
+ import 'package:atomic_x_core/atomicxcore.dart';
113
+
114
+ // main.dart
115
+ void main() async {
116
+ WidgetsFlutterBinding.ensureInitialized();
117
+
118
+ // 登录
119
+ final result = await LoginStore.shared.login(
120
+ sdkAppID: 1400000001, // 替换为您的 sdkAppID
121
+ userID: "test_001", // 替换为您的 userID
122
+ userSig: "xxxxxxxxxxx", // 替换为您的 userSig
123
+ );
124
+
125
+ if (result.isSuccess) {
126
+ debugPrint("login success");
127
+ } else {
128
+ debugPrint("login failed code: ${result.code}, message: ${result.message}");
129
+ }
130
+
131
+ runApp(const MyApp());
132
+ }
133
+ ```
134
+
135
+ **登录接口参数说明:**
136
+ <table>
137
+ <tr>
138
+ <td rowspan="1" colSpan="1" >**参数**</td>
139
+
140
+ <td rowspan="1" colSpan="1" >**类型**</td>
141
+
142
+ <td rowspan="1" colSpan="1" >**说明**</td>
143
+ </tr>
144
+
145
+ <tr>
146
+ <td rowspan="1" colSpan="1" >`sdkAppID`</td>
147
+
148
+ <td rowspan="1" colSpan="1" >`int`</td>
149
+
150
+ <td rowspan="1" colSpan="1" >从 [控制台](https://console.cloud.tencent.com/trtc) 获取,通常是以 `140` 或 `160` 开头的 10 位整数。</td>
151
+ </tr>
152
+
153
+ <tr>
154
+ <td rowspan="1" colSpan="1" >`userID`</td>
155
+
156
+ <td rowspan="1" colSpan="1" >`String`</td>
157
+
158
+ <td rowspan="1" colSpan="1" >当前用户的唯一 ID,仅包含英文字母、数字、连字符和下划线。为避免多端登录冲突,**请勿使用**`1`、`123`**等简单 ID**。</td>
159
+ </tr>
160
+
161
+ <tr>
162
+ <td rowspan="1" colSpan="1" >`userSig`</td>
163
+
164
+ <td rowspan="1" colSpan="1" >`String`</td>
165
+
166
+ <td rowspan="1" colSpan="1" >用于腾讯云鉴权的票据。请注意:<br>- 开发环境:您可以采用本地 `GenerateTestUserSig.genTestSig` 函数生成 userSig 或者通过 [UserSig 辅助工具](https://console.cloud.tencent.com/im/tool-usersig) 生成临时的 UserSig。<br>- 生产环境:为了防止密钥泄露,请务必采用服务端生成 UserSig 的方式。详细信息请参考 [服务端生成 UserSig](https://cloud.tencent.com/document/product/647/17275)。<br>更多信息请参见 [如何计算及使用 UserSig](https://cloud.tencent.com/document/product/647/17275)。</td>
167
+ </tr>
168
+ </table>
169
+
170
+
171
+ ## 构建基础语聊房应用
172
+
173
+ ### 步骤1:实现房主创建语聊房
174
+
175
+ 房主开播流程如下,您只需执行以下几步操作,即可快速搭建一个语聊房。
176
+
177
+ #### 1. 初始化麦位 Store
178
+
179
+ 在您的房主页面中,创建一个 `LiveSeatStore` 实例。您需要监听 `liveSeatStore.liveSeatState` 的变化,以实时获取麦位数据来渲染您的 `UI`。
180
+ ``` java
181
+ import 'package:flutter/material.dart';
182
+ import 'package:atomic_x_core/atomicxcore.dart';
183
+
184
+ // YourAnchorPage 代表您的房主页面
185
+ class YourAnchorPage extends StatefulWidget {
186
+ const YourAnchorPage({super.key});
187
+
188
+ @override
189
+ State<YourAnchorPage> createState() => _YourAnchorPageState();
190
+ }
191
+
192
+ class _YourAnchorPageState extends State<YourAnchorPage> {
193
+ final _liveListStore = LiveListStore.shared;
194
+ final _deviceStore = DeviceStore.shared;
195
+
196
+ // 使用 liveID 初始化 LiveSeatStore
197
+ final String _liveID = "test_voice_room_001";
198
+ late final LiveSeatStore _liveSeatStore;
199
+ late final VoidCallback _seatListListener = _onSeatListChanged;
200
+
201
+ @override
202
+ void initState() {
203
+ super.initState();
204
+ _liveSeatStore = LiveSeatStore.create(_liveID);
205
+
206
+ // 监听麦位列表变化
207
+ _observeSeatList();
208
+ }
209
+
210
+ void _observeSeatList() {
211
+ // 监听 liveSeatState.seatList 的变化,并更新您的麦位 UI
212
+ _liveSeatStore.liveSeatState.seatList.addListener(_seatListListener);
213
+ }
214
+
215
+ void _onSeatListChanged() {
216
+ // 在这里根据 seatInfoList 渲染您的麦位 UI
217
+ final seatInfoList = _liveSeatStore.liveSeatState.seatList.value;
218
+ debugPrint("Seat list updated: ${seatInfoList.length} seats");
219
+ setState(() {});
220
+ }
221
+
222
+ @override
223
+ void dispose() {
224
+ _liveSeatStore.liveSeatState.seatList.removeListener(_seatListListener);
225
+ super.dispose();
226
+ }
227
+
228
+ @override
229
+ Widget build(BuildContext context) {
230
+ // 假设您有自己的布局
231
+ return Container();
232
+ }
233
+ }
234
+ ```
235
+
236
+ #### 2. 打开麦克风
237
+
238
+ 通过调用 `DeviceStore` 的 `openLocalMicrophone` 接口打开麦克风,示例代码如下:
239
+ ``` java
240
+ class _YourAnchorPageState extends State<YourAnchorPage> {
241
+ // ... 其他代码 ...
242
+
243
+ void _openDevices() {
244
+ // 打开麦克风
245
+ DeviceStore.shared.openLocalMicrophone();
246
+ }
247
+ }
248
+ ```
249
+
250
+ #### 3. 开始语聊
251
+
252
+ 通过调用 `LiveListStore` 的 `createLive` 接口开始语聊房直播,完整示例代码如下:
253
+ ``` java
254
+ class _YourAnchorPageState extends State<YourAnchorPage> {
255
+ // ... 其他代码 ...
256
+ final String _liveID = "test_voice_room_001";
257
+
258
+ @override
259
+ void initState() {
260
+ super.initState();
261
+ // ... 其他代码 ...
262
+
263
+ // 开始语聊
264
+ _startLive();
265
+ }
266
+
267
+ Future<void> _startLive() async {
268
+ // 1. 准备 LiveInfo 对象
269
+ final liveInfo = LiveInfo(
270
+ // 2. 设置房间 id
271
+ liveID: _liveID,
272
+ // 3. 设置房间名称
273
+ liveName: "test 语聊房",
274
+ // 4. 配置为语聊房(启用麦位)
275
+ isSeatEnabled: true,
276
+ // 5. 房主默认上麦
277
+ keepOwnerOnSeat: true,
278
+ // 6. 设置麦位布局模板(例如 70 为 10 麦位模板)
279
+ // 重要:请根据产品规范传入正确的 ID
280
+ seatLayoutTemplateID: 70,
281
+ // 7. 设置上麦模式,例如申请上麦
282
+ seatMode: TakeSeatMode.apply,
283
+ // 8. 设置最大麦位数
284
+ maxSeatCount: 10,
285
+ );
286
+
287
+ // 9. 调用 createLive 开始直播
288
+ final result = await _liveListStore.createLive(liveInfo);
289
+
290
+ if (result.isSuccess) {
291
+ debugPrint("Response startLive onSuccess");
292
+ // 房主创建成功后,默认会上麦,此时您可以调用 unmuteMicrophone
293
+ _liveSeatStore.unmuteMicrophone();
294
+ } else {
295
+ debugPrint("Response startLive onError: ${result.message}");
296
+ }
297
+ }
298
+ }
299
+ ```
300
+
301
+ **LiveInfo 参数说明:**
302
+ <table>
303
+ <tr>
304
+ <td rowspan="1" colSpan="1" >**参数名**</td>
305
+
306
+ <td rowspan="1" colSpan="1" >**类型**</td>
307
+
308
+ <td rowspan="1" colSpan="1" >**属性**</td>
309
+
310
+ <td rowspan="1" colSpan="1" >**描述**</td>
311
+ </tr>
312
+
313
+ <tr>
314
+ <td rowspan="1" colSpan="1" >`liveID`</td>
315
+
316
+ <td rowspan="1" colSpan="1" >`String`</td>
317
+
318
+ <td rowspan="1" colSpan="1" >必填</td>
319
+
320
+ <td rowspan="1" colSpan="1" >直播间的唯一标识符</td>
321
+ </tr>
322
+
323
+ <tr>
324
+ <td rowspan="1" colSpan="1" >`liveName`</td>
325
+
326
+ <td rowspan="1" colSpan="1" >`String`</td>
327
+
328
+ <td rowspan="1" colSpan="1" >选填</td>
329
+
330
+ <td rowspan="1" colSpan="1" >直播间的标题</td>
331
+ </tr>
332
+
333
+ <tr>
334
+ <td rowspan="1" colSpan="1" >`notice`</td>
335
+
336
+ <td rowspan="1" colSpan="1" >`String`</td>
337
+
338
+ <td rowspan="1" colSpan="1" >选填</td>
339
+
340
+ <td rowspan="1" colSpan="1" >直播间的公告信息</td>
341
+ </tr>
342
+
343
+ <tr>
344
+ <td rowspan="1" colSpan="1" >`isMessageDisable`</td>
345
+
346
+ <td rowspan="1" colSpan="1" >`bool`</td>
347
+
348
+ <td rowspan="1" colSpan="1" >选填</td>
349
+
350
+ <td rowspan="1" colSpan="1" >是否禁言(`true`:是,`false`:否)</td>
351
+ </tr>
352
+
353
+ <tr>
354
+ <td rowspan="1" colSpan="1" >`isPublicVisible`</td>
355
+
356
+ <td rowspan="1" colSpan="1" >`bool`</td>
357
+
358
+ <td rowspan="1" colSpan="1" >选填</td>
359
+
360
+ <td rowspan="1" colSpan="1" >是否公开可见(`true`:是,`false`:否)</td>
361
+ </tr>
362
+
363
+ <tr>
364
+ <td rowspan="1" colSpan="1" >`isSeatEnabled`</td>
365
+
366
+ <td rowspan="1" colSpan="1" >`bool`</td>
367
+
368
+ <td rowspan="1" colSpan="1" >选填</td>
369
+
370
+ <td rowspan="1" colSpan="1" >是否启用麦位功能(`true`:是,`false`:否)</td>
371
+ </tr>
372
+
373
+ <tr>
374
+ <td rowspan="1" colSpan="1" >`keepOwnerOnSeat`</td>
375
+
376
+ <td rowspan="1" colSpan="1" >`bool`</td>
377
+
378
+ <td rowspan="1" colSpan="1" >选填</td>
379
+
380
+ <td rowspan="1" colSpan="1" >是否保持房主在麦位上</td>
381
+ </tr>
382
+
383
+ <tr>
384
+ <td rowspan="1" colSpan="1" >`maxSeatCount`</td>
385
+
386
+ <td rowspan="1" colSpan="1" >`int`</td>
387
+
388
+ <td rowspan="1" colSpan="1" >选填</td>
389
+
390
+ <td rowspan="1" colSpan="1" >最大麦位数量</td>
391
+ </tr>
392
+
393
+ <tr>
394
+ <td rowspan="1" colSpan="1" >`seatMode`</td>
395
+
396
+ <td rowspan="1" colSpan="1" >`TakeSeatMode`</td>
397
+
398
+ <td rowspan="1" colSpan="1" >选填</td>
399
+
400
+ <td rowspan="1" colSpan="1" >上麦模式(`free`:自由上麦,`apply`:申请上麦)</td>
401
+ </tr>
402
+
403
+ <tr>
404
+ <td rowspan="1" colSpan="1" >`seatLayoutTemplateID`</td>
405
+
406
+ <td rowspan="1" colSpan="1" >`int`</td>
407
+
408
+ <td rowspan="1" colSpan="1" >必填</td>
409
+
410
+ <td rowspan="1" colSpan="1" >麦位布局模板 `ID`</td>
411
+ </tr>
412
+
413
+ <tr>
414
+ <td rowspan="1" colSpan="1" >`coverURL`</td>
415
+
416
+ <td rowspan="1" colSpan="1" >`String`</td>
417
+
418
+ <td rowspan="1" colSpan="1" >选填</td>
419
+
420
+ <td rowspan="1" colSpan="1" >直播间的封面图片地址</td>
421
+ </tr>
422
+
423
+ <tr>
424
+ <td rowspan="1" colSpan="1" >`backgroundURL`</td>
425
+
426
+ <td rowspan="1" colSpan="1" >`String`</td>
427
+
428
+ <td rowspan="1" colSpan="1" >选填</td>
429
+
430
+ <td rowspan="1" colSpan="1" >直播间的背景图片地址</td>
431
+ </tr>
432
+
433
+ <tr>
434
+ <td rowspan="1" colSpan="1" >`categoryList`</td>
435
+
436
+ <td rowspan="1" colSpan="1" >`List<int>`</td>
437
+
438
+ <td rowspan="1" colSpan="1" >选填</td>
439
+
440
+ <td rowspan="1" colSpan="1" >直播间的分类标签列表</td>
441
+ </tr>
442
+
443
+ <tr>
444
+ <td rowspan="1" colSpan="1" >`activityStatus`</td>
445
+
446
+ <td rowspan="1" colSpan="1" >`int`</td>
447
+
448
+ <td rowspan="1" colSpan="1" >选填</td>
449
+
450
+ <td rowspan="1" colSpan="1" >直播活动状态</td>
451
+ </tr>
452
+
453
+ <tr>
454
+ <td rowspan="1" colSpan="1" >`isGiftEnabled`</td>
455
+
456
+ <td rowspan="1" colSpan="1" >`bool`</td>
457
+
458
+ <td rowspan="1" colSpan="1" >选填</td>
459
+
460
+ <td rowspan="1" colSpan="1" >是否启用礼物功能(`true`:是,`false`:否)</td>
461
+ </tr>
462
+ </table>
463
+
464
+
465
+ #### 4. 构建麦位 UI 界面
466
+
467
+ > **提示:**
468
+ >
469
+
470
+ > 麦位 `UI` 效果的业务代码,可参考 `TUILiveKit` 开源项目中的 [seat_grid_widget.dart](https://github.com/Tencent-RTC/TUIKit_Flutter/blob/main/live/livekit/lib/seat_grid_widget/seat_grid_widget.dart) 文件来了解完整的实现逻辑。
471
+ >
472
+
473
+
474
+ 通过 `LiveSeatStore` 实例,监听 `liveSeatState.seatList` 的变化,以实时获取麦位数据来渲染您的 UI。您可以在页面中(例如 `YourAnchorPage` 或 `YourAudiencePage`)通过以下方式监听数据:
475
+ ``` java
476
+ class _YourAnchorPageState extends State<YourAnchorPage> {
477
+ // ... 其他代码 ...
478
+ late final LiveSeatStore _liveSeatStore;
479
+ late final VoidCallback _seatListListener = _onSeatListChanged;
480
+
481
+ @override
482
+ void initState() {
483
+ super.initState();
484
+ _liveSeatStore = LiveSeatStore.create("your_live_id");
485
+ // ... 其他代码 ...
486
+
487
+ // 监听 seatList 变化
488
+ _observeSeatList();
489
+ }
490
+
491
+ void _observeSeatList() {
492
+ // 监听 liveSeatState.seatList 变化,并更新您的麦位 UI
493
+ _liveSeatStore.liveSeatState.seatList.addListener(_seatListListener);
494
+ }
495
+
496
+ void _onSeatListChanged() {
497
+ // seatInfoList 即为最新的麦位列表 (List<SeatInfo>)
498
+ final seatInfoList = _liveSeatStore.liveSeatState.seatList.value;
499
+ // 在这里根据 seatInfoList 渲染您的麦位 UI
500
+ debugPrint("Seat list updated: ${seatInfoList.length} seats");
501
+ setState(() {});
502
+ }
503
+
504
+ @override
505
+ void dispose() {
506
+ _liveSeatStore.liveSeatState.seatList.removeListener(_seatListListener);
507
+ super.dispose();
508
+ }
509
+
510
+ @override
511
+ Widget build(BuildContext context) {
512
+ return ValueListenableBuilder<List<SeatInfo>>(
513
+ valueListenable: _liveSeatStore.liveSeatState.seatList,
514
+ builder: (context, seatList, child) {
515
+ return GridView.builder(
516
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
517
+ crossAxisCount: 4,
518
+ ),
519
+ itemCount: seatList.length,
520
+ itemBuilder: (context, index) {
521
+ final seat = seatList[index];
522
+ return _buildSeatItem(seat);
523
+ },
524
+ );
525
+ },
526
+ );
527
+ }
528
+
529
+ Widget _buildSeatItem(SeatInfo seat) {
530
+ // 构建单个麦位 UI
531
+ return Container();
532
+ }
533
+ }
534
+ ```
535
+
536
+ #### 5. 结束语聊
537
+
538
+ 语聊结束后,房主可以调用 `LiveListStore` 的 `endLive` 接口结束语聊,`SDK` 会处理停止推流和销毁房间的逻辑。
539
+ ``` java
540
+ class _YourAnchorPageState extends State<YourAnchorPage> {
541
+ // ... 其他代码 ...
542
+
543
+ // 结束语聊
544
+ Future<void> _stopLive() async {
545
+ final result = await _liveListStore.endLive();
546
+
547
+ if (result.isSuccess) {
548
+ debugPrint("endLive success");
549
+ } else {
550
+ debugPrint("endLive error: ${result.message}");
551
+ }
552
+ }
553
+ }
554
+ ```
555
+
556
+ ### 步骤2:实现观众进入语聊房
557
+
558
+ 观众进房流程如下,通过简单几步操作,即可实现观众进入语聊房。
559
+
560
+ #### 1. 初始化麦位 Store
561
+
562
+ 在您的观众页面中,创建 `LiveSeatStore` 实例,并监听 `liveSeatState.seatList` 的变化,以渲染麦位 `UI`。
563
+ ``` java
564
+ import 'package:flutter/material.dart';
565
+ import 'package:atomic_x_core/atomicxcore.dart';
566
+
567
+ // YourAudiencePage 代表您的观众页面
568
+ class YourAudiencePage extends StatefulWidget {
569
+ const YourAudiencePage({super.key});
570
+
571
+ @override
572
+ State<YourAudiencePage> createState() => _YourAudiencePageState();
573
+ }
574
+
575
+ class _YourAudiencePageState extends State<YourAudiencePage> {
576
+ final _liveListStore = LiveListStore.shared;
577
+
578
+ // 确保 liveID 与房主一致
579
+ final String _liveID = "test_voice_room_001";
580
+ late final LiveSeatStore _liveSeatStore;
581
+ late final VoidCallback _seatListListener = _onSeatListChanged;
582
+
583
+ @override
584
+ void initState() {
585
+ super.initState();
586
+ _liveSeatStore = LiveSeatStore.create(_liveID);
587
+
588
+ // 监听麦位列表变化
589
+ _observeSeatList();
590
+ }
591
+
592
+ void _observeSeatList() {
593
+ // 监听 liveSeatState.seatList 变化,并更新您的麦位 UI
594
+ _liveSeatStore.liveSeatState.seatList.addListener(_seatListListener);
595
+ }
596
+
597
+ void _onSeatListChanged() {
598
+ // 在这里根据 seatInfoList 渲染您的麦位 UI
599
+ final seatInfoList = _liveSeatStore.liveSeatState.seatList.value;
600
+ debugPrint("AudiencePage Seat list updated: ${seatInfoList.length} seats");
601
+ setState(() {});
602
+ }
603
+
604
+ @override
605
+ void dispose() {
606
+ _liveSeatStore.liveSeatState.seatList.removeListener(_seatListListener);
607
+ super.dispose();
608
+ }
609
+
610
+ @override
611
+ Widget build(BuildContext context) {
612
+ // 假设您有自己的布局
613
+ return Container();
614
+ }
615
+ }
616
+ ```
617
+
618
+ #### 2. 进入语聊房
619
+
620
+ 通过调用 `LiveListStore` 的 `joinLive` 接口加入语聊房,完整示例代码如下:
621
+ ``` java
622
+ class _YourAudiencePageState extends State<YourAudiencePage> {
623
+ // ... 其他代码 ...
624
+
625
+ @override
626
+ void initState() {
627
+ super.initState();
628
+ // ... 其他代码 ...
629
+
630
+ // 进入语聊房
631
+ _joinLive();
632
+ }
633
+
634
+ Future<void> _joinLive() async {
635
+ // 调用 joinLive 进入语聊房
636
+ final result = await _liveListStore.joinLive(_liveID);
637
+
638
+ if (result.isSuccess) {
639
+ debugPrint("joinLive success");
640
+ } else {
641
+ debugPrint("joinLive error: ${result.message}");
642
+ }
643
+ }
644
+ }
645
+ ```
646
+
647
+ #### 3. 构建麦位 UI 界面
648
+
649
+ 观众构建麦位 UI 界面的流程与主播完全一致,请参考[构建麦位 UI 界面](https://write.woa.com/#4.-.E6.9E.84.E5.BB.BA.E9.BA.A6.E4.BD.8D-ui-.E7.95.8C.E9.9D.A2)。
650
+
651
+ #### 4. 退出语聊房
652
+
653
+ 观众退出语聊房时,需要调用 `LiveListStore` 的 `leaveLive` 接口来退出。
654
+ ``` java
655
+ class _YourAudiencePageState extends State<YourAudiencePage> {
656
+ // ... 其他代码 ...
657
+
658
+ Future<void> _leaveLive() async {
659
+ final result = await _liveListStore.leaveLive();
660
+
661
+ if (result.isSuccess) {
662
+ debugPrint("leaveLive success");
663
+ } else {
664
+ debugPrint("leaveLive error: ${result.message}");
665
+ }
666
+ }
667
+ }
668
+ ```
669
+
670
+ ### 运行效果
671
+
672
+ 完成上述步骤后,即可完成一个最基础的语聊直播场景。您可以参考 [丰富语聊房场景](https://write.woa.com/#.E4.B8.B0.E5.AF.8C.E8.AF.AD.E8.81.8A.E6.88.BF.E5.9C.BA.E6.99.AF) 来完善语聊场景。
673
+
674
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100032457995/9b1930a4df3011f0a38652540044a08e.png)
675
+
676
+
677
+ ## 功能进阶
678
+
679
+ ### 实现麦上用户说话音浪
680
+
681
+ 在语聊房场景中,一个常见的需求是当麦上用户说话时,在其头像上显示一个波浪动画,以提示全房间用户"谁在说话",`LiveSeatStore` 提供了 `speakingUsers` 数据流,专门用于实现此功能。
682
+
683
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100032457995/af03283cdf3011f0a4f35254007c27c5.png)
684
+
685
+
686
+ #### 实现方式
687
+
688
+ > **提示:**
689
+ >
690
+
691
+ > 麦上用户说话时展示波浪动画效果,可参考 `TUILiveKit` 开源项目中的 [seat_grid_widget.dart](https://github.com/Tencent-RTC/TUIKit_Flutter/blob/main/live/livekit/lib/seat_grid_widget/seat_grid_widget.dart) 文件来了解完整的实现逻辑。
692
+ >
693
+
694
+
695
+ 在 `YourAnchorPage` 或 `YourAudiencePage` 中监听 `speakingUsers` 变化,并更新"正在说话"状态,代码示例如下:
696
+ ``` java
697
+ class _YourAnchorPageState extends State<YourAnchorPage> {
698
+ late final VoidCallback _speakingUsersListener = _onSpeakingUsersChanged;
699
+ // ... 其他代码 ...
700
+
701
+ @override
702
+ void initState() {
703
+ super.initState();
704
+ // ... 其他代码 ...
705
+
706
+ // 监听 speakingUsers 变化
707
+ _observeSpeakingUsersState();
708
+ }
709
+
710
+ void _observeSpeakingUsersState() {
711
+ // 监听 liveSeatState.speakingUsers 变化,并更新"正在说话"状态
712
+ _liveSeatStore.liveSeatState.speakingUsers.addListener(_speakingUsersListener);
713
+ }
714
+
715
+ void _onSpeakingUsersChanged() {
716
+ // 将 "正在说话" 的用户 ID 集合传递给 UI,更新 UI 状态
717
+ final speakingUserMap = _liveSeatStore.liveSeatState.speakingUsers.value;
718
+ debugPrint("Speaking users updated: ${speakingUserMap.length} users");
719
+ setState(() {});
720
+ }
721
+
722
+ @override
723
+ void dispose() {
724
+ _liveSeatStore.liveSeatState.speakingUsers.removeListener(_speakingUsersListener);
725
+ super.dispose();
726
+ }
727
+
728
+ @override
729
+ Widget build(BuildContext context) {
730
+ return ValueListenableBuilder<Map<String, int>>(
731
+ valueListenable: _liveSeatStore.liveSeatState.speakingUsers,
732
+ builder: (context, speakingUsers, child) {
733
+ // speakingUsers 是一个 Map,key 是 userID,value 是音量
734
+ return YourSpeakingIndicatorWidget(speakingUsers: speakingUsers);
735
+ },
736
+ );
737
+ }
738
+ }
739
+
740
+ // 示例:正在说话指示器组件
741
+ class YourSpeakingIndicatorWidget extends StatelessWidget {
742
+ final Map<String, int> speakingUsers;
743
+
744
+ const YourSpeakingIndicatorWidget({
745
+ super.key,
746
+ required this.speakingUsers,
747
+ });
748
+
749
+ @override
750
+ Widget build(BuildContext context) {
751
+ return Container();
752
+ }
753
+ }
754
+ ```
755
+
756
+ ## 丰富语聊房场景
757
+
758
+ 当您完成了基础的语聊房功能后,您可以参考以下功能指南来为语聊房添加丰富的互动玩法。
759
+ <table>
760
+ <tr>
761
+ <td rowspan="1" colSpan="1" >**功能**</td>
762
+
763
+ <td rowspan="1" colSpan="1" >**功能介绍**</td>
764
+
765
+ <td rowspan="1" colSpan="1" >**功能 Stores**</td>
766
+
767
+ <td rowspan="1" colSpan="1" >**实现指南**</td>
768
+ </tr>
769
+
770
+ <tr>
771
+ <td rowspan="1" colSpan="1" >**实现听众上麦**</td>
772
+
773
+ <td rowspan="1" colSpan="1" >听众申请上麦,与房主进行实时语音互动。</td>
774
+
775
+ <td rowspan="1" colSpan="1" >[CoGuestStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_co_guest_store/CoGuestStore-class.html)</td>
776
+
777
+ <td rowspan="1" colSpan="1" >[观众上麦](https://write.woa.com/document/197477898206908416)</td>
778
+ </tr>
779
+
780
+ <tr>
781
+ <td rowspan="1" colSpan="1" >**添加弹幕聊天功能**</td>
782
+
783
+ <td rowspan="1" colSpan="1" >房间内成员可以发送和接收实时文字消息。</td>
784
+
785
+ <td rowspan="1" colSpan="1" >[BarrageStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_barrage_barrage_store/BarrageStore-class.html)</td>
786
+
787
+ <td rowspan="1" colSpan="1" >[实现弹幕功能](https://write.woa.com/document/200285441364750336)</td>
788
+ </tr>
789
+
790
+ <tr>
791
+ <td rowspan="1" colSpan="1" >**构建礼物赠送系统**</td>
792
+
793
+ <td rowspan="1" colSpan="1" >观众可以向主播赠送虚拟礼物,增加互动和趣味性。</td>
794
+
795
+ <td rowspan="1" colSpan="1" >[GiftStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftStore-class.html)</td>
796
+
797
+ <td rowspan="1" colSpan="1" >[实现礼物功能](https://write.woa.com/document/200285576402239488)</td>
798
+ </tr>
799
+ </table>
800
+
801
+
802
+ ## API 文档
803
+ <table>
804
+ <tr>
805
+ <td rowspan="1" colSpan="1" >**Store/Component**</td>
806
+
807
+ <td rowspan="1" colSpan="1" >**功能描述**</td>
808
+
809
+ <td rowspan="1" colSpan="1" >**API 文档**</td>
810
+ </tr>
811
+
812
+ <tr>
813
+ <td rowspan="1" colSpan="1" >**LiveListStore**</td>
814
+
815
+ <td rowspan="1" colSpan="1" >直播间全生命周期管理:创建 / 加入 / 离开 / 销毁房间,查询房间列表,修改直播信息(名称、公告等),监听直播状态(如被踢出、结束)。</td>
816
+
817
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_list_store/LiveListStore-class.html)</td>
818
+ </tr>
819
+
820
+ <tr>
821
+ <td rowspan="1" colSpan="1" >**LiveSeatStore**</td>
822
+
823
+ <td rowspan="1" colSpan="1" >麦位管理核心:管理麦位列表、麦上用户状态、麦位相关操作(上麦、下麦、踢人、锁麦、开关麦克风/摄像头等),监听麦位事件。</td>
824
+
825
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_seat_store/LiveSeatStore-class.html)</td>
826
+ </tr>
827
+
828
+ <tr>
829
+ <td rowspan="1" colSpan="1" >**DeviceStore**</td>
830
+
831
+ <td rowspan="1" colSpan="1" >音视频设备控制:麦克风(开关 / 音量)、摄像头(开关 / 切换 / 画质)、屏幕共享,设备状态实时监听。</td>
832
+
833
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_device_store/DeviceStore-class.html)</td>
834
+ </tr>
835
+
836
+ <tr>
837
+ <td rowspan="1" colSpan="1" >**CoGuestStore**</td>
838
+
839
+ <td rowspan="1" colSpan="1" >观众连麦管理:连麦申请 / 邀请 / 同意 / 拒绝,连麦成员权限控制(麦克风 / 摄像头),状态同步。</td>
840
+
841
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_co_guest_store/CoGuestStore-class.html)</td>
842
+ </tr>
843
+
844
+ <tr>
845
+ <td rowspan="1" colSpan="1" >**CoHostStore**</td>
846
+
847
+ <td rowspan="1" colSpan="1" >主播跨房连线:支持多布局模板(动态网格等),发起 / 接受 / 拒绝连线,连麦主播互动管理。</td>
848
+
849
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_co_host_store/CoHostStore-class.html)</td>
850
+ </tr>
851
+
852
+ <tr>
853
+ <td rowspan="1" colSpan="1" >**BattleStore**</td>
854
+
855
+ <td rowspan="1" colSpan="1" >主播 PK 对战:发起 PK(配置时长 / 对手),管理 PK 状态(开始 / 结束),同步分数,监听对战结果。</td>
856
+
857
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_battle_store/BattleStore-class.html)</td>
858
+ </tr>
859
+
860
+ <tr>
861
+ <td rowspan="1" colSpan="1" >**GiftStore**</td>
862
+
863
+ <td rowspan="1" colSpan="1" >礼物互动:获取礼物列表,发送 / 接收礼物,监听礼物事件(含发送者、礼物详情)。</td>
864
+
865
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftStore-class.html)</td>
866
+ </tr>
867
+
868
+ <tr>
869
+ <td rowspan="1" colSpan="1" >**BarrageStore**</td>
870
+
871
+ <td rowspan="1" colSpan="1" >弹幕功能:发送文本 / 自定义弹幕,维护弹幕列表,实时监听弹幕状态。</td>
872
+
873
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_barrage_barrage_store/BarrageStore-class.html)</td>
874
+ </tr>
875
+
876
+ <tr>
877
+ <td rowspan="1" colSpan="1" >**LikeStore**</td>
878
+
879
+ <td rowspan="1" colSpan="1" >点赞互动:发送点赞,监听点赞事件,同步总点赞数。</td>
880
+
881
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_like_store/LikeStore-class.html)</td>
882
+ </tr>
883
+
884
+ <tr>
885
+ <td rowspan="1" colSpan="1" >**LiveAudienceStore**</td>
886
+
887
+ <td rowspan="1" colSpan="1" >观众管理:获取实时观众列表(ID / 名称 / 头像),统计观众数量,监听观众进出事件。</td>
888
+
889
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_live_live_audience_store/LiveAudienceStore-class.html)</td>
890
+ </tr>
891
+
892
+ <tr>
893
+ <td rowspan="1" colSpan="1" >**AudioEffectStore**</td>
894
+
895
+ <td rowspan="1" colSpan="1" >音频特效:变声(童声 / 男声)、混响(KTV 等)、耳返调节,实时切换特效。</td>
896
+
897
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioEffectStore-class.html)</td>
898
+ </tr>
899
+
900
+ <tr>
901
+ <td rowspan="1" colSpan="1" >**BaseBeautyStore**</td>
902
+
903
+ <td rowspan="1" colSpan="1" >基础美颜:调节磨皮 / 美白 / 红润(0-100 级),重置美颜状态,同步效果参数。</td>
904
+
905
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_base_beauty_store/BaseBeautyStore-class.html)</td>
906
+ </tr>
907
+ </table>
908
+
909
+
910
+ ## 常见问题
911
+
912
+ ### 听众进房后无声音
913
+ - **检查设备权限**:请确保 `App` 已在 `Info.plist`(iOS)或 `AndroidManifest.xml`(Android)中声明并获得了麦克风的系统使用权限。
914
+
915
+ - **检查房主端**:房主端是否正常调用 `DeviceStore.shared.openLocalMicrophone()` 打开了麦克风。
916
+
917
+ - **检查网络**:请检查设备网络连接是否正常。
918
+
919
+
920
+ ### 麦位列表未显示或更新
921
+ - **检查 Store 初始化**:请确保您在 `createLive` 或 `joinLive` 之前,已经使用相同的 `liveID` 正确创建了 `LiveSeatStore` 实例(`LiveSeatStore.create(liveID)`)。
922
+
923
+ - **检查数据监听**:请检查您是否正确使用了 `addListener` 来监听 `liveSeatStore.liveSeatState.seatList`,并确保在 `dispose` 中调用 `removeListener` 移除监听。
924
+
925
+ - **检查接口调用**:请确保 `createLive`(房主)或 `joinLive`(听众)接口已成功调用(在回调结果的 `isSuccess` 为 `true` 时确认)。