@tencentcloud/sdk-mcp 1.3.4 → 1.3.6

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 (126) hide show
  1. package/index.js +4 -4
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/resource/doc/chatuikit/android/features/theme.md +363 -0
  5. package/resource/doc/chatuikit/{android/client_api_android.md → faq/android_sdk/client-api.md} +0 -1
  6. package/resource/doc/chatuikit/faq/{native_sdk/faq.md → common/product.md} +8 -0
  7. package/resource/doc/chatuikit/faq/flutter_sdk/faq.md +54 -0
  8. package/resource/doc/chatuikit/faq/web_sdk/faq.md +1 -1
  9. package/resource/doc/chatuikit/flutter/features/theme.md +379 -0
  10. package/resource/doc/chatuikit/flutter/workflow.md +816 -0
  11. package/resource/doc/chatuikit/iOS/features/theme.md +416 -0
  12. package/resource/doc/chatuikit/iOS/workflow.md +0 -0
  13. package/resource/doc/chatuikit/react/components/chat-setting.md +124 -0
  14. package/resource/doc/chatuikit/react/components/contact-list.md +1331 -0
  15. package/resource/doc/chatuikit/react/components/search.md +885 -0
  16. package/resource/doc/chatuikit/vue/components/chat-setting.md +88 -0
  17. package/resource/doc/chatuikit/vue/components/contact-list.md +679 -0
  18. package/resource/doc/chatuikit/vue/components/search.md +1384 -0
  19. package/resource/doc/livekit/live/android/workflow.md +137 -4
  20. package/resource/doc/livekit/live/flutter/live-audience-list.md +337 -0
  21. package/resource/doc/livekit/live/flutter/live-audio-effect.md +739 -0
  22. package/resource/doc/livekit/live/flutter/live-barrage.md +578 -0
  23. package/resource/doc/livekit/live/flutter/live-base-beauty.md +484 -0
  24. package/resource/doc/livekit/live/flutter/live-co-guest-interaction.md +606 -0
  25. package/resource/doc/livekit/live/flutter/live-gift.md +812 -0
  26. package/resource/doc/livekit/live/flutter/live-host-interaction.md +1113 -0
  27. package/resource/doc/livekit/live/flutter/live-integration.md +1029 -0
  28. package/resource/doc/livekit/live/flutter/live-live-list.md +861 -0
  29. package/resource/doc/livekit/live/ios/live-audience-list.md +335 -0
  30. package/resource/doc/livekit/live/ios/live-audio-effect.md +373 -0
  31. package/resource/doc/livekit/live/ios/live-barrage.md +529 -0
  32. package/resource/doc/livekit/live/ios/live-base-beauty.md +237 -0
  33. package/resource/doc/livekit/live/ios/live-co-guest-interaction.md +483 -0
  34. package/resource/doc/livekit/live/ios/live-gift.md +785 -0
  35. package/resource/doc/livekit/live/ios/live-host-interaction.md +743 -0
  36. package/resource/doc/livekit/live/ios/live-integration.md +822 -0
  37. package/resource/doc/livekit/live/ios/live-live-list.md +535 -0
  38. package/resource/doc/livekit/live/ios/workflow.md +352 -0
  39. package/resource/doc/rtcengine/faq/web/web.md +2 -2
  40. package/resource/doc/rtcengine/web/how_to_integrated_web_sdk.md +2 -2
  41. package/resource/doc/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md +84 -0
  42. package/resource/doc/rtcengine/web/plugin/21-advanced-auto-play-policy.md +86 -0
  43. package/resource/doc/rtcengine/web/plugin/22-advanced-audio-mixer.md +220 -0
  44. package/resource/doc/rtcengine/web/plugin/23-advanced-support-detection.md +217 -0
  45. package/resource/doc/rtcengine/web/plugin/24-advanced-network-quality.md +137 -0
  46. package/resource/doc/rtcengine/web/plugin/25-advanced-device-change.md +97 -0
  47. package/resource/doc/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md +453 -0
  48. package/resource/doc/rtcengine/web/plugin/27-advanced-small-stream.md +180 -0
  49. package/resource/doc/rtcengine/web/plugin/28-advanced-beauty.md +349 -0
  50. package/resource/doc/rtcengine/web/plugin/29-advanced-water-mark.md +149 -0
  51. package/resource/doc/rtcengine/web/plugin/30-advanced-cross-room-link.md +96 -0
  52. package/resource/doc/rtcengine/web/plugin/31-advanced-plugins-overview.md +405 -0
  53. package/resource/doc/rtcengine/web/plugin/34-advanced-proxy.md +244 -0
  54. package/resource/doc/rtcengine/web/plugin/35-advanced-ai-denoiser.md +84 -0
  55. package/resource/doc/rtcengine/web/plugin/36-advanced-virtual-background.md +202 -0
  56. package/resource/doc/rtcengine/web/plugin/37-advanced-voice-changer.md +98 -0
  57. package/resource/doc/rtcengine/web/plugin/38-advanced-basic-beauty.md +95 -0
  58. package/resource/doc/rtcengine/web/plugin/39-advanced-video-decoder.md +33 -0
  59. package/resource/doc/rtcengine/web/plugin/40-advanced-video-mixer.md +380 -0
  60. package/resource/doc/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md +91 -0
  61. package/resource/doc/rtcengine/web/plugin/42-advanced-realtime-transcriber.md +314 -0
  62. package/resource/doc/rtcengine/web/plugin/43-advanced-face-detection.md +180 -0
  63. package/resource/doc/tuicallkit/android/workflow.md +0 -0
  64. package/resource/doc/tuicallkit/flutter/integration.md +510 -0
  65. package/resource/doc/tuicallkit/flutter/workflow.md +331 -0
  66. package/tools/call/get-native-call-integration.js +27 -11
  67. package/tools/call/get-native-call-integration.js.map +1 -1
  68. package/tools/chat/get-native-chat-feature-detail.js +30 -0
  69. package/tools/chat/get-native-chat-feature-detail.js.map +1 -0
  70. package/tools/chat/get-native-chat-integration.js +30 -12
  71. package/tools/chat/get-native-chat-integration.js.map +1 -1
  72. package/tools/common/get-faq.js +2 -4
  73. package/tools/common/get-faq.js.map +1 -1
  74. package/tools/definitions/get_native_call_uikit_integration_def.js +16 -6
  75. package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
  76. package/tools/definitions/get_native_chat_feature_detail_def.js +32 -0
  77. package/tools/definitions/get_native_chat_feature_detail_def.js.map +1 -0
  78. package/tools/definitions/get_native_chat_uikit_integration_def.js +18 -6
  79. package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
  80. package/tools/definitions/{get_native_live_extra_features_def.js → get_native_live_uikit_extra_features_def.js} +3 -3
  81. package/tools/definitions/get_native_live_uikit_extra_features_def.js.map +1 -0
  82. package/tools/definitions/{get_native_live_interaction_def.js → get_native_live_uikit_interaction_def.js} +3 -3
  83. package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -0
  84. package/tools/definitions/get_web_chat_uikit_component_detail_def.js +46 -7
  85. package/tools/definitions/get_web_chat_uikit_component_detail_def.js.map +1 -1
  86. package/tools/index.js +6 -4
  87. package/tools/index.js.map +1 -1
  88. package/tools/live/{get_native_live_extra_features.js → get_native_live_uikit_extra_features.js} +4 -4
  89. package/tools/live/get_native_live_uikit_extra_features.js.map +1 -0
  90. package/tools/live/{get_native_live_interaction.js → get_native_live_uikit_interaction.js} +4 -4
  91. package/tools/live/get_native_live_uikit_interaction.js.map +1 -0
  92. package/tools/rtcengine/get-trtc-web-sdk-faq.js +1 -1
  93. package/tools/rtcengine/get-trtc-web-sdk-plugin.js +45 -0
  94. package/tools/rtcengine/get-trtc-web-sdk-plugin.js.map +1 -0
  95. package/utils/handle-component-name.js +0 -16
  96. package/utils/handle-component-name.js.map +1 -1
  97. package/utils/report-cls-client.js +1 -1
  98. package/utils/report-es-client.js +1 -1
  99. package/resource/doc/chatuikit/android/integrate_tuichat_only_android.md +0 -382
  100. package/resource/doc/chatuikit/android/ui_api_android.md +0 -418
  101. package/resource/doc/chatuikit/iOS/integrate_tuichat_only_iOS.md +0 -993
  102. package/resource/doc/chatuikit/iOS/ui_api_iOS.md +0 -526
  103. package/resource/doc/tuicallkit/flutter/how_to_integrated_flutter_callkit.md +0 -226
  104. package/resource/doc/tuicallkit/flutter/how_to_run_flutter_callkit_demo.md +0 -101
  105. package/resource/doc/tuicallkit/iOS/how_to_run_iOS_callkit_demo.md +0 -98
  106. package/tools/definitions/get_native_live_extra_features_def.js.map +0 -1
  107. package/tools/definitions/get_native_live_interaction_def.js.map +0 -1
  108. package/tools/live/get_native_live_extra_features.js.map +0 -1
  109. package/tools/live/get_native_live_interaction.js.map +0 -1
  110. /package/resource/doc/chatuikit/android/{integrate_tuikit_android.md → integration.md} +0 -0
  111. /package/resource/doc/{tuicallkit/android/.gitkeep → chatuikit/android/workflow.md} +0 -0
  112. /package/resource/doc/chatuikit/{flutter/client_api_Flutter.md → faq/flutter_sdk/client-api.md} +0 -0
  113. /package/resource/doc/chatuikit/{iOS/client_api_iOS.md → faq/ios_sdk/client-api.md} +0 -0
  114. /package/resource/doc/chatuikit/flutter/{integrate_tuikit_Flutter.md → integration.md} +0 -0
  115. /package/resource/doc/chatuikit/iOS/{integrate_tuikit_iOS.md → integration.md} +0 -0
  116. /package/resource/doc/chatuikit/react/components/{chatheader.md → chat-header.md} +0 -0
  117. /package/resource/doc/chatuikit/vue/components/{chatheader.md → chat-header.md} +0 -0
  118. /package/resource/doc/tuicallkit/android/{how_to_integrated_android_callkit.md → integration.md} +0 -0
  119. /package/resource/doc/tuicallkit/{android/api_TUICallObserver.md → faq/android_sdk/call-observer-api.md} +0 -0
  120. /package/resource/doc/tuicallkit/{android/api_TUICallKit.md → faq/android_sdk/callkit-api.md} +0 -0
  121. /package/resource/doc/tuicallkit/{flutter/api_TUICallDefine.md → faq/flutter_sdk/call-define-api.md} +0 -0
  122. /package/resource/doc/tuicallkit/{flutter/api_TUICallObserver.md → faq/flutter_sdk/call-observer-api.md} +0 -0
  123. /package/resource/doc/tuicallkit/{flutter/api_TUICallKit.md → faq/flutter_sdk/callkit-api.md} +0 -0
  124. /package/resource/doc/tuicallkit/{iOS/api_TUICallObserver.md → faq/ios_sdk/call-observer-api.md} +0 -0
  125. /package/resource/doc/tuicallkit/{iOS/api_TUICallKit.md → faq/ios_sdk/callkit-api.md} +0 -0
  126. /package/resource/doc/tuicallkit/iOS/{how_to_integrated_iOS_callkit.md → integration.md} +0 -0
@@ -0,0 +1,739 @@
1
+ 本篇文档旨在指导您如何使用 `AtomicXCore` 框架中的 `AudioEffectStore` 和 `DeviceStore` 模块,为您的直播应用快速集成音效控制功能,包括麦克风音量、耳返监听,并添加多种趣味变声效果和混响效果。
2
+
3
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100032457995/683e0548df0e11f08304525400454e06.png)
4
+
5
+
6
+ ## 核心功能
7
+
8
+ 通过组合 `AudioEffectStore` 和 `DeviceStore`,您将能实现以下核心功能:
9
+ - **人声音量调节**:控制本地音频上行的采集音量大小,即观众听到主播声音的大小。
10
+
11
+ - **耳返功能**:允许主播或连麦用户通过耳机实时听到自己的声音,用于监听和矫正发音。
12
+
13
+ - **变声效果**:提供多种趣味变声选项,例如萝莉、大叔、熊孩子等。
14
+
15
+ - **混响效果**:模拟不同环境的声场效果,例如 KTV、金属声、低沉、洪亮等。
16
+
17
+
18
+ ## 概念说明
19
+ <table>
20
+ <tr>
21
+ <td rowspan="1" colSpan="1" >**核心概念**</td>
22
+
23
+ <td rowspan="1" colSpan="1" >**类型**</td>
24
+
25
+ <td rowspan="1" colSpan="1" >**核心职责与描述**</td>
26
+ </tr>
27
+
28
+ <tr>
29
+ <td rowspan="1" colSpan="1" >[AudioEffectState](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioEffectState-class.html)</td>
30
+
31
+ <td rowspan="1" colSpan="1" >`class`</td>
32
+
33
+ <td rowspan="1" colSpan="1" >代表音效模块的当前状态,通常用于UI渲染。包括变声状态、混响状态、耳返开启状态、耳返音量。所有属性均为 `ValueListenable` 类型,支持订阅监听。</td>
34
+ </tr>
35
+
36
+ <tr>
37
+ <td rowspan="1" colSpan="1" >[AudioEffectStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioEffectStore-class.html)</td>
38
+
39
+ <td rowspan="1" colSpan="1" >`class`</td>
40
+
41
+ <td rowspan="1" colSpan="1" >代表音效模块**单例数据管理类**。通过它您可以调用修改音效接口,当您调用接口后,相应的 `audioEffectState` 属性会自动更新,可以通过订阅这个 state 响应式数据来接收和监听状态更新。</td>
42
+ </tr>
43
+
44
+ <tr>
45
+ <td rowspan="1" colSpan="1" >[DeviceState](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_device_store/DeviceState-class.html)</td>
46
+
47
+ <td rowspan="1" colSpan="1" >`class`</td>
48
+
49
+ <td rowspan="1" colSpan="1" >代表设备模块的当前状态,通常用于UI渲染。核心属性包括摄像头、麦克风的设备状态、采集音量等。所有属性均为 `ValueListenable` 类型,支持订阅监听。</td>
50
+ </tr>
51
+
52
+ <tr>
53
+ <td rowspan="1" colSpan="1" >[DeviceStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_device_store/DeviceStore-class.html)</td>
54
+
55
+ <td rowspan="1" colSpan="1" >`class`</td>
56
+
57
+ <td rowspan="1" colSpan="1" >代表设备模块**单例数据管理类**。通过它您可以调用操作摄像头、麦克风接口,当您调用接口后,相应的 `state` 属性会自动更新,可以通过订阅这个 state 响应式数据来接收和监听状态更新。</td>
58
+ </tr>
59
+ </table>
60
+
61
+
62
+ ## 实现步骤
63
+
64
+ ### 步骤1:组件集成
65
+
66
+ 请参考 [开始直播](https://write.woa.com/document/191126413785100288) 集成 **AtomicXCore**,完成接入。
67
+
68
+ ### 步骤2:获取 Store 实例
69
+
70
+ `AudioEffectStore` 和 `DeviceStore` 是单例对象,您可以直接通过 `shared` 属性在项目的任何位置获取实例。您也可以参考 TUILiveKit 开源 UI demo 项目中的 [audio_effect_panel_widget.dart](https://github.com/Tencent-RTC/TUIKit_Flutter/blob/main/live/livekit/lib/component/audio_effect/audio_effect_panel_widget.dart) 文件来了解完整的实现逻辑。
71
+ ``` java
72
+ import 'package:flutter/material.dart';
73
+ import 'package:atomic_x_core/atomicxcore.dart';
74
+
75
+ class _AudioEffectPanelWidgetState {
76
+ final _audioEffectStore = AudioEffectStore.shared;
77
+ final _deviceStore = DeviceStore.shared;
78
+ }
79
+ ```
80
+
81
+ ### 步骤3:实现耳返功能
82
+
83
+ 耳返功能允许用户实时监听自己的麦克风声音,可以通过调用本节介绍的接口管理耳返功能。
84
+
85
+ > **注意:**
86
+ >
87
+
88
+ > 耳返功能通常需要连接耳机才能正常工作。
89
+ >
90
+
91
+
92
+ #### 实现方式
93
+ 1. **开关耳返**:您可以使用 `Switch` 控件实现开关耳返功能。
94
+
95
+ 2. **设置耳返音量值**:您可以使用 `Slider` 控件实现左右拖动滑块来调节音量的功能,并将 `Slider` 的值映射成音量值,调用 `setVoiceEarMonitorVolume(volume)`。请注意,该接口接收的参数范围是 `[0, 150]`,所以您需要将 UI 控件的值(例如 Slider 的 `0.0 - 1.0`)映射到 `0 - 150` 的范围。
96
+
97
+ 3. **监听状态更新 UI**:您可以订阅实时的耳返状态值更新 UI。
98
+
99
+
100
+ #### 代码示例
101
+ ``` java
102
+ import 'package:flutter/material.dart';
103
+ import 'package:atomic_x_core/atomicxcore.dart';
104
+
105
+ /// 耳返控制组件
106
+ class EarMonitorWidget extends StatelessWidget {
107
+ const EarMonitorWidget({super.key});
108
+
109
+ @override
110
+ Widget build(BuildContext context) {
111
+ final audioEffectStore = AudioEffectStore.shared;
112
+
113
+ return Column(
114
+ crossAxisAlignment: CrossAxisAlignment.start,
115
+ children: [
116
+ // 1. 开关耳返
117
+ ValueListenableBuilder<bool>(
118
+ valueListenable: audioEffectStore.audioEffectState.isEarMonitorOpened,
119
+ builder: (context, isOpened, child) {
120
+ return SwitchListTile(
121
+ title: const Text('耳返'),
122
+ subtitle: const Text('需要插入耳机'),
123
+ value: isOpened,
124
+ onChanged: (value) {
125
+ audioEffectStore.setVoiceEarMonitorEnable(value);
126
+ },
127
+ );
128
+ },
129
+ ),
130
+ // 2. 调节耳返音量
131
+ ValueListenableBuilder<int>(
132
+ valueListenable: audioEffectStore.audioEffectState.earMonitorVolume,
133
+ builder: (context, volume, child) {
134
+ return ListTile(
135
+ title: const Text('耳返音量'),
136
+ subtitle: Slider(
137
+ value: volume.toDouble(),
138
+ min: 0,
139
+ max: 150,
140
+ divisions: 150,
141
+ onChanged: (value) {
142
+ audioEffectStore.setVoiceEarMonitorVolume(value.toInt());
143
+ },
144
+ ),
145
+ trailing: Text('$volume'),
146
+ );
147
+ },
148
+ ),
149
+ ],
150
+ );
151
+ }
152
+ }
153
+ ```
154
+
155
+ #### setVoiceEarMonitorEnable 接口参数
156
+ <table>
157
+ <tr>
158
+ <td rowspan="1" colSpan="1" >**参数名**</td>
159
+
160
+ <td rowspan="1" colSpan="1" >**类型**</td>
161
+
162
+ <td rowspan="1" colSpan="1" >**描述**</td>
163
+ </tr>
164
+
165
+ <tr>
166
+ <td rowspan="1" colSpan="1" >`enable`</td>
167
+
168
+ <td rowspan="1" colSpan="1" >`bool`</td>
169
+
170
+ <td rowspan="1" colSpan="1" >是否开启耳返。<br>- true:开启<br>- false:关闭</td>
171
+ </tr>
172
+ </table>
173
+
174
+
175
+ #### setVoiceEarMonitorVolume 接口参数
176
+ <table>
177
+ <tr>
178
+ <td rowspan="1" colSpan="1" >**参数名**</td>
179
+
180
+ <td rowspan="1" colSpan="1" >**类型**</td>
181
+
182
+ <td rowspan="1" colSpan="1" >**描述**</td>
183
+ </tr>
184
+
185
+ <tr>
186
+ <td rowspan="1" colSpan="1" >`volume`</td>
187
+
188
+ <td rowspan="1" colSpan="1" >`int`</td>
189
+
190
+ <td rowspan="1" colSpan="1" >耳返音量大小。<br>- 取值范围:[0, 150]<br>- 默认值:100</td>
191
+ </tr>
192
+ </table>
193
+
194
+
195
+ ### 步骤4:实现人声音量调节
196
+
197
+ 当主播希望调节自己的上行采集音量大小时,调用 `DeviceStore` 的 `setCaptureVolume(volume)` 方法传入音量值即可。
198
+
199
+ #### 实现方式
200
+ 1. **设置采集音量值**:您可以使用 `Slider` 控件实现左右拖动滑块来调节音量的功能,并将 `Slider` 的值映射成音量值后调用 `setCaptureVolume(volume)`。请注意,该接口接收的参数范围是 `[0, 150]`,所以您需要将 UI 控件的值(例如 Slider 的 `0.0 - 1.0`)映射到 `0 - 150` 的范围。
201
+
202
+ 2. **监听状态更新 UI**:您可以订阅实时的音量状态值更新 UI。
203
+
204
+
205
+ #### 代码示例
206
+ ``` java
207
+ import 'package:flutter/material.dart';
208
+ import 'package:atomic_x_core/atomicxcore.dart';
209
+
210
+ /// 人声音量控制组件
211
+ class CaptureVolumeWidget extends StatelessWidget {
212
+ const CaptureVolumeWidget({super.key});
213
+
214
+ @override
215
+ Widget build(BuildContext context) {
216
+ final deviceStore = DeviceStore.shared;
217
+
218
+ return ValueListenableBuilder<int>(
219
+ valueListenable: deviceStore.state.captureVolume,
220
+ builder: (context, volume, child) {
221
+ return ListTile(
222
+ title: const Text('人声音量'),
223
+ subtitle: Slider(
224
+ value: volume.toDouble(),
225
+ min: 0,
226
+ max: 150,
227
+ divisions: 150,
228
+ onChanged: (value) {
229
+ deviceStore.setCaptureVolume(value.toInt());
230
+ },
231
+ ),
232
+ trailing: Text('$volume'),
233
+ );
234
+ },
235
+ );
236
+ }
237
+ }
238
+ ```
239
+
240
+ #### setCaptureVolume 接口参数
241
+ <table>
242
+ <tr>
243
+ <td rowspan="1" colSpan="1" >**参数名**</td>
244
+
245
+ <td rowspan="1" colSpan="1" >**类型**</td>
246
+
247
+ <td rowspan="1" colSpan="1" >**描述**</td>
248
+ </tr>
249
+
250
+ <tr>
251
+ <td rowspan="1" colSpan="1" >`volume`</td>
252
+
253
+ <td rowspan="1" colSpan="1" >`int`</td>
254
+
255
+ <td rowspan="1" colSpan="1" >采集音量大小。<br>- 取值范围:[0, 150]<br>- 默认值:100</td>
256
+ </tr>
257
+ </table>
258
+
259
+
260
+ ### 步骤5:实现变声效果
261
+
262
+ 当主播希望改变自己的声音时,您可以调用 `setAudioChangerType(type)` 方法,传入相应的 Type 枚举值即可切换效果。
263
+
264
+ #### 代码示例
265
+ ``` java
266
+ import 'package:flutter/material.dart';
267
+ import 'package:atomic_x_core/atomicxcore.dart';
268
+
269
+ /// 变声效果选择组件
270
+ class VoiceChangerWidget extends StatelessWidget {
271
+ const VoiceChangerWidget({super.key});
272
+
273
+ @override
274
+ Widget build(BuildContext context) {
275
+ final audioEffectStore = AudioEffectStore.shared;
276
+
277
+ return Column(
278
+ crossAxisAlignment: CrossAxisAlignment.start,
279
+ children: [
280
+ const Padding(
281
+ padding: EdgeInsets.all(16),
282
+ child: Text('变声效果', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
283
+ ),
284
+ ValueListenableBuilder<AudioChangerType>(
285
+ valueListenable: audioEffectStore.audioEffectState.audioChangerType,
286
+ builder: (context, changerType, child) {
287
+ return Padding(
288
+ padding: const EdgeInsets.symmetric(horizontal: 16),
289
+ child: Wrap(
290
+ spacing: 8,
291
+ runSpacing: 8,
292
+ children: AudioChangerType.values.map((type) {
293
+ return ChoiceChip(
294
+ label: Text(_getChangerTypeName(type)),
295
+ selected: changerType == type,
296
+ onSelected: (selected) {
297
+ if (selected) {
298
+ audioEffectStore.setAudioChangerType(type);
299
+ }
300
+ },
301
+ );
302
+ }).toList(),
303
+ ),
304
+ );
305
+ },
306
+ ),
307
+ ],
308
+ );
309
+ }
310
+
311
+ String _getChangerTypeName(AudioChangerType type) {
312
+ switch (type) {
313
+ case AudioChangerType.none:
314
+ return '关闭';
315
+ case AudioChangerType.child:
316
+ return '熊孩子';
317
+ case AudioChangerType.girl:
318
+ return '萝莉';
319
+ case AudioChangerType.uncle:
320
+ return '大叔';
321
+ case AudioChangerType.ethereal:
322
+ return '空灵';
323
+ }
324
+ }
325
+ }
326
+ ```
327
+
328
+ #### setAudioChangerType 接口参数
329
+ <table>
330
+ <tr>
331
+ <td rowspan="1" colSpan="1" >**参数名**</td>
332
+
333
+ <td rowspan="1" colSpan="1" >**类型**</td>
334
+
335
+ <td rowspan="1" colSpan="1" >**描述**</td>
336
+ </tr>
337
+
338
+ <tr>
339
+ <td rowspan="1" colSpan="1" >`type`</td>
340
+
341
+ <td rowspan="1" colSpan="1" >[AudioChangerType](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioChangerType.html)</td>
342
+
343
+ <td rowspan="1" colSpan="1" >变声效果枚举。</td>
344
+ </tr>
345
+ </table>
346
+
347
+
348
+ ### 步骤6:实现混响效果
349
+
350
+ 当主播希望给自己的声音添加混响效果时,您可以调用 `setAudioReverbType(type)` 方法,传入相应的 Type 枚举值即可切换效果。
351
+
352
+ #### 代码示例
353
+ ``` java
354
+ import 'package:flutter/material.dart';
355
+ import 'package:atomic_x_core/atomicxcore.dart';
356
+
357
+ /// 混响效果选择组件
358
+ class ReverbWidget extends StatelessWidget {
359
+ const ReverbWidget({super.key});
360
+
361
+ @override
362
+ Widget build(BuildContext context) {
363
+ final audioEffectStore = AudioEffectStore.shared;
364
+
365
+ return Column(
366
+ crossAxisAlignment: CrossAxisAlignment.start,
367
+ children: [
368
+ const Padding(
369
+ padding: EdgeInsets.all(16),
370
+ child: Text('混响效果', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
371
+ ),
372
+ ValueListenableBuilder<AudioReverbType>(
373
+ valueListenable: audioEffectStore.audioEffectState.audioReverbType,
374
+ builder: (context, reverbType, child) {
375
+ return Padding(
376
+ padding: const EdgeInsets.symmetric(horizontal: 16),
377
+ child: Wrap(
378
+ spacing: 8,
379
+ runSpacing: 8,
380
+ children: AudioReverbType.values.map((type) {
381
+ return ChoiceChip(
382
+ label: Text(_getReverbTypeName(type)),
383
+ selected: reverbType == type,
384
+ onSelected: (selected) {
385
+ if (selected) {
386
+ audioEffectStore.setAudioReverbType(type);
387
+ }
388
+ },
389
+ );
390
+ }).toList(),
391
+ ),
392
+ );
393
+ },
394
+ ),
395
+ ],
396
+ );
397
+ }
398
+
399
+ String _getReverbTypeName(AudioReverbType type) {
400
+ switch (type) {
401
+ case AudioReverbType.none:
402
+ return '关闭';
403
+ case AudioReverbType.ktv:
404
+ return 'KTV';
405
+ case AudioReverbType.room:
406
+ return '小房间';
407
+ case AudioReverbType.hall:
408
+ return '大会堂';
409
+ case AudioReverbType.deep:
410
+ return '低沉';
411
+ case AudioReverbType.loud:
412
+ return '洪亮';
413
+ case AudioReverbType.metallic:
414
+ return '金属声';
415
+ case AudioReverbType.magnetic:
416
+ return '磁性';
417
+ case AudioReverbType.recordingStudio:
418
+ return '录音棚';
419
+ }
420
+ }
421
+ }
422
+ ```
423
+
424
+ #### setAudioReverbType 接口参数
425
+ <table>
426
+ <tr>
427
+ <td rowspan="1" colSpan="1" >**参数名**</td>
428
+
429
+ <td rowspan="1" colSpan="1" >**类型**</td>
430
+
431
+ <td rowspan="1" colSpan="1" >**描述**</td>
432
+ </tr>
433
+
434
+ <tr>
435
+ <td rowspan="1" colSpan="1" >`type`</td>
436
+
437
+ <td rowspan="1" colSpan="1" >[AudioReverbType](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioReverbType.html)</td>
438
+
439
+ <td rowspan="1" colSpan="1" >混响效果枚举。</td>
440
+ </tr>
441
+ </table>
442
+
443
+
444
+ ### 步骤7:重置音效设置
445
+
446
+ > **重要:**
447
+ >
448
+
449
+ > AudioEffectStore 和 DeviceStore 是单例,即音效和设备设置会全局生效,如果您不希望当前直播间的设置影响到之后创建的其他直播间,就需要在当前直播间结束的时候重置音效和设备设置。
450
+ >
451
+
452
+
453
+ 以下两种情况您可能需要重置音效设置:
454
+ 1. **当前直播间结束时**,调用 `store` 的 `reset()` 方法实现音效重置。
455
+
456
+ 2. **需要重置所有设备和音效设置时**,调用 `store` 的 `reset()` 方法实现音效重置。
457
+
458
+ ``` java
459
+ import 'package:flutter/material.dart';
460
+ import 'package:atomic_x_core/atomicxcore.dart';
461
+
462
+ /// 音效重置组件
463
+ class AudioEffectResetWidget extends StatelessWidget {
464
+ const AudioEffectResetWidget({super.key});
465
+
466
+ void _resetAudioEffect() {
467
+ AudioEffectStore.shared.reset();
468
+ DeviceStore.shared.reset();
469
+ }
470
+
471
+ @override
472
+ Widget build(BuildContext context) {
473
+ return ElevatedButton(
474
+ onPressed: _resetAudioEffect,
475
+ child: const Text('重置音效设置'),
476
+ );
477
+ }
478
+ }
479
+ ```
480
+
481
+ ## 完整示例
482
+ ``` java
483
+ import 'package:flutter/material.dart';
484
+ import 'package:atomic_x_core/atomicxcore.dart';
485
+
486
+ /// 音效设置页面
487
+ class AudioEffectPage extends StatelessWidget {
488
+ const AudioEffectPage({super.key});
489
+
490
+ @override
491
+ Widget build(BuildContext context) {
492
+ final audioEffectStore = AudioEffectStore.shared;
493
+ final deviceStore = DeviceStore.shared;
494
+
495
+ return Scaffold(
496
+ appBar: AppBar(title: const Text('音效设置')),
497
+ body: ListView(
498
+ children: [
499
+ // 人声音量
500
+ const Padding(
501
+ padding: EdgeInsets.all(16),
502
+ child: Text('人声音量', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
503
+ ),
504
+ ValueListenableBuilder<int>(
505
+ valueListenable: deviceStore.state.captureVolume,
506
+ builder: (context, volume, child) {
507
+ return ListTile(
508
+ title: const Text('采集音量'),
509
+ subtitle: Slider(
510
+ value: volume.toDouble(),
511
+ min: 0,
512
+ max: 150,
513
+ divisions: 150,
514
+ onChanged: (value) {
515
+ deviceStore.setCaptureVolume(value.toInt());
516
+ },
517
+ ),
518
+ trailing: Text('$volume'),
519
+ );
520
+ },
521
+ ),
522
+ const Divider(),
523
+
524
+ // 耳返设置
525
+ const Padding(
526
+ padding: EdgeInsets.all(16),
527
+ child: Text('耳返', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
528
+ ),
529
+ ValueListenableBuilder<bool>(
530
+ valueListenable: audioEffectStore.audioEffectState.isEarMonitorOpened,
531
+ builder: (context, isOpened, child) {
532
+ return SwitchListTile(
533
+ title: const Text('开启耳返'),
534
+ subtitle: const Text('需要插入耳机'),
535
+ value: isOpened,
536
+ onChanged: (value) {
537
+ audioEffectStore.setVoiceEarMonitorEnable(value);
538
+ },
539
+ );
540
+ },
541
+ ),
542
+ ValueListenableBuilder<int>(
543
+ valueListenable: audioEffectStore.audioEffectState.earMonitorVolume,
544
+ builder: (context, volume, child) {
545
+ return ListTile(
546
+ title: const Text('耳返音量'),
547
+ subtitle: Slider(
548
+ value: volume.toDouble(),
549
+ min: 0,
550
+ max: 150,
551
+ divisions: 150,
552
+ onChanged: (value) {
553
+ audioEffectStore.setVoiceEarMonitorVolume(value.toInt());
554
+ },
555
+ ),
556
+ trailing: Text('$volume'),
557
+ );
558
+ },
559
+ ),
560
+ const Divider(),
561
+
562
+ // 变声设置
563
+ const Padding(
564
+ padding: EdgeInsets.all(16),
565
+ child: Text('变声', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
566
+ ),
567
+ ValueListenableBuilder<AudioChangerType>(
568
+ valueListenable: audioEffectStore.audioEffectState.audioChangerType,
569
+ builder: (context, changerType, child) {
570
+ return Padding(
571
+ padding: const EdgeInsets.symmetric(horizontal: 16),
572
+ child: Wrap(
573
+ spacing: 8,
574
+ runSpacing: 8,
575
+ children: AudioChangerType.values.map((type) {
576
+ return ChoiceChip(
577
+ label: Text(_getChangerTypeName(type)),
578
+ selected: changerType == type,
579
+ onSelected: (selected) {
580
+ if (selected) {
581
+ audioEffectStore.setAudioChangerType(type);
582
+ }
583
+ },
584
+ );
585
+ }).toList(),
586
+ ),
587
+ );
588
+ },
589
+ ),
590
+ const SizedBox(height: 16),
591
+ const Divider(),
592
+
593
+ // 混响设置
594
+ const Padding(
595
+ padding: EdgeInsets.all(16),
596
+ child: Text('混响', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
597
+ ),
598
+ ValueListenableBuilder<AudioReverbType>(
599
+ valueListenable: audioEffectStore.audioEffectState.audioReverbType,
600
+ builder: (context, reverbType, child) {
601
+ return Padding(
602
+ padding: const EdgeInsets.symmetric(horizontal: 16),
603
+ child: Wrap(
604
+ spacing: 8,
605
+ runSpacing: 8,
606
+ children: AudioReverbType.values.map((type) {
607
+ return ChoiceChip(
608
+ label: Text(_getReverbTypeName(type)),
609
+ selected: reverbType == type,
610
+ onSelected: (selected) {
611
+ if (selected) {
612
+ audioEffectStore.setAudioReverbType(type);
613
+ }
614
+ },
615
+ );
616
+ }).toList(),
617
+ ),
618
+ );
619
+ },
620
+ ),
621
+ const SizedBox(height: 24),
622
+
623
+ // 重置按钮
624
+ Padding(
625
+ padding: const EdgeInsets.all(16),
626
+ child: ElevatedButton(
627
+ onPressed: () {
628
+ audioEffectStore.reset();
629
+ deviceStore.reset();
630
+ },
631
+ child: const Text('重置音效设置'),
632
+ ),
633
+ ),
634
+ ],
635
+ ),
636
+ );
637
+ }
638
+
639
+ String _getChangerTypeName(AudioChangerType type) {
640
+ switch (type) {
641
+ case AudioChangerType.none:
642
+ return '关闭';
643
+ case AudioChangerType.child:
644
+ return '熊孩子';
645
+ case AudioChangerType.girl:
646
+ return '萝莉';
647
+ case AudioChangerType.uncle:
648
+ return '大叔';
649
+ case AudioChangerType.ethereal:
650
+ return '空灵';
651
+ }
652
+ }
653
+
654
+ String _getReverbTypeName(AudioReverbType type) {
655
+ switch (type) {
656
+ case AudioReverbType.none:
657
+ return '关闭';
658
+ case AudioReverbType.ktv:
659
+ return 'KTV';
660
+ case AudioReverbType.room:
661
+ return '小房间';
662
+ case AudioReverbType.hall:
663
+ return '大会堂';
664
+ case AudioReverbType.deep:
665
+ return '低沉';
666
+ case AudioReverbType.loud:
667
+ return '洪亮';
668
+ case AudioReverbType.metallic:
669
+ return '金属声';
670
+ case AudioReverbType.magnetic:
671
+ return '磁性';
672
+ case AudioReverbType.recordingStudio:
673
+ return '录音棚';
674
+ }
675
+ }
676
+ }
677
+ ```
678
+
679
+ ## API 文档
680
+
681
+ 关于 [AudioEffectStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioEffectStore-class.html) 和 [DeviceStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_device_store/DeviceStore-class.html) 及其相关类的所有公开接口、属性的详细信息,请参阅 [AtomicXCore](https://tencent-rtc.github.io/TUIKit_Flutter/index.html) 框架的官方 API 文档。
682
+ <table>
683
+ <tr>
684
+ <td rowspan="1" colSpan="1" >**Store/Component**</td>
685
+
686
+ <td rowspan="1" colSpan="1" >**功能描述**</td>
687
+
688
+ <td rowspan="1" colSpan="1" >**API 文档**</td>
689
+ </tr>
690
+
691
+ <tr>
692
+ <td rowspan="1" colSpan="1" >**AudioEffectStore**</td>
693
+
694
+ <td rowspan="1" colSpan="1" >音效管理:进行音效设置,并获取实时音效状态。</td>
695
+
696
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_audio_effect_store/AudioEffectStore-class.html)</td>
697
+ </tr>
698
+
699
+ <tr>
700
+ <td rowspan="1" colSpan="1" >**DeviceStore**</td>
701
+
702
+ <td rowspan="1" colSpan="1" >设备管理:进行摄像头、麦克风操作,并获取实时设备状态。</td>
703
+
704
+ <td rowspan="1" colSpan="1" >[API 文档](https://tencent-rtc.github.io/TUIKit_Flutter/api_device_device_store/DeviceStore-class.html)</td>
705
+ </tr>
706
+ </table>
707
+
708
+
709
+ ## 常见问题
710
+
711
+ ### 音效和设备接口的调用时机是否有要求?
712
+
713
+ 没有限制。`AudioEffectStore` 和 `DeviceStore` 的设置是全局生效的,您可以在进入直播间之前或之后随时调用相关接口(例如设置变声、混响或耳返),设置会立即生效并被保留。
714
+
715
+ ### "人声音量" 和"耳返音量" 有什么区别?
716
+
717
+ 这是一个非常重要且易混淆的概念,区别如下:
718
+ - **人声音量 (CaptureVolume):**通过 `DeviceStore.shared.setCaptureVolume()` 设置。它决定了观众能听到主播的声音大小。
719
+
720
+ - **耳返音量 (EarMonitorVolume):**通过 `AudioEffectStore.shared.setVoiceEarMonitorVolume()` 设置。它只决定了主播在耳机里听到的监听声音大小,**不会**影响观众。
721
+
722
+
723
+ ### 新创建的直播间为什么直接就有音效、或者出现音量很大、很小等问题?
724
+
725
+ `AudioEffectStore` 和 `DeviceStore` 是单例,这意味着音效和设备设置是全局生效的,出现这种情况很可能是因为您之前设置过音效但是没有重置,需要在合适的地方调用 `reset()` 方法重置。
726
+
727
+ ### 为什么我开启了"耳返",但是听不到自己的声音?
728
+
729
+ 请您按照以下步骤检查:
730
+ 1. **是否插入耳机**:耳返功能绝大多数情况下依赖耳机才能生效,请确保已连接有线或蓝牙耳机。
731
+
732
+ 2. **音量是否为0**:检查“耳返音量"是否被设置为 0。
733
+
734
+ 3. **麦克风是否开启**:确认 `DeviceStore` 中的麦克风是开启状态(即已调用 `openLocalMicrophone()`)。
735
+
736
+
737
+ ### 变声效果和混响效果可以同时生效吗?
738
+
739
+ 可以。`AudioChangerType` 和 `AudioReverbType` 是可以叠加生效的。例如,您可以同时设置 `AudioChangerType.girl` 变声和 `AudioReverbType.ktv` 混响。