@tencent-rtc/trtc-agent-skills 0.1.0

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 (205) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/README.zh.md +173 -0
  4. package/bin/cli.js +434 -0
  5. package/knowledge-base/index.yaml +454 -0
  6. package/knowledge-base/platform-slice-template.md +233 -0
  7. package/knowledge-base/scenario-spec.md +350 -0
  8. package/knowledge-base/scenarios/conference/base/general-conference.md +365 -0
  9. package/knowledge-base/scenarios/conference/base/webinar-conference.md +130 -0
  10. package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +145 -0
  11. package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +113 -0
  12. package/knowledge-base/scenarios/live/entertainment-live-room.md +118 -0
  13. package/knowledge-base/slice-spec.md +546 -0
  14. package/knowledge-base/slices/conference/web/ai-tools.md +225 -0
  15. package/knowledge-base/slices/conference/web/beauty-effects.md +188 -0
  16. package/knowledge-base/slices/conference/web/device-control.md +338 -0
  17. package/knowledge-base/slices/conference/web/login-auth.md +261 -0
  18. package/knowledge-base/slices/conference/web/network-quality.md +190 -0
  19. package/knowledge-base/slices/conference/web/official-roomkit-api.md +298 -0
  20. package/knowledge-base/slices/conference/web/official-roomkit-login-ui.md +246 -0
  21. package/knowledge-base/slices/conference/web/participant-list.md +238 -0
  22. package/knowledge-base/slices/conference/web/participant-management.md +718 -0
  23. package/knowledge-base/slices/conference/web/prejoin-check.md +293 -0
  24. package/knowledge-base/slices/conference/web/room-call.md +213 -0
  25. package/knowledge-base/slices/conference/web/room-chat.md +426 -0
  26. package/knowledge-base/slices/conference/web/room-lifecycle.md +534 -0
  27. package/knowledge-base/slices/conference/web/room-schedule.md +281 -0
  28. package/knowledge-base/slices/conference/web/screen-share.md +211 -0
  29. package/knowledge-base/slices/conference/web/video-layout.md +675 -0
  30. package/knowledge-base/slices/conference/web/virtual-background.md +197 -0
  31. package/knowledge-base/slices/conference/web/webinar-interaction.md +206 -0
  32. package/knowledge-base/slices/live/anchor-lifecycle.md +122 -0
  33. package/knowledge-base/slices/live/anchor-preview.md +90 -0
  34. package/knowledge-base/slices/live/anchor-room-config.md +104 -0
  35. package/knowledge-base/slices/live/audience-list.md +86 -0
  36. package/knowledge-base/slices/live/audience-manage.md +92 -0
  37. package/knowledge-base/slices/live/audience-watch.md +85 -0
  38. package/knowledge-base/slices/live/audio.md +116 -0
  39. package/knowledge-base/slices/live/barrage.md +88 -0
  40. package/knowledge-base/slices/live/beauty.md +99 -0
  41. package/knowledge-base/slices/live/coguest-apply.md +105 -0
  42. package/knowledge-base/slices/live/device-control.md +91 -0
  43. package/knowledge-base/slices/live/error-codes.md +167 -0
  44. package/knowledge-base/slices/live/gift.md +84 -0
  45. package/knowledge-base/slices/live/ios/.gitkeep +0 -0
  46. package/knowledge-base/slices/live/ios/anchor-lifecycle.md +313 -0
  47. package/knowledge-base/slices/live/ios/anchor-preview.md +228 -0
  48. package/knowledge-base/slices/live/ios/anchor-room-config.md +257 -0
  49. package/knowledge-base/slices/live/ios/audience-list.md +353 -0
  50. package/knowledge-base/slices/live/ios/audience-manage.md +381 -0
  51. package/knowledge-base/slices/live/ios/audience-watch.md +286 -0
  52. package/knowledge-base/slices/live/ios/audio.md +373 -0
  53. package/knowledge-base/slices/live/ios/barrage.md +285 -0
  54. package/knowledge-base/slices/live/ios/beauty.md +323 -0
  55. package/knowledge-base/slices/live/ios/coguest-apply.md +506 -0
  56. package/knowledge-base/slices/live/ios/device-control.md +286 -0
  57. package/knowledge-base/slices/live/ios/error-codes.md +270 -0
  58. package/knowledge-base/slices/live/ios/gift.md +315 -0
  59. package/knowledge-base/slices/live/ios/live-list.md +269 -0
  60. package/knowledge-base/slices/live/ios/login-auth.md +247 -0
  61. package/knowledge-base/slices/live/live-list.md +82 -0
  62. package/knowledge-base/slices/live/login-auth.md +78 -0
  63. package/package.json +34 -0
  64. package/skills/trtc/SKILL.md +326 -0
  65. package/skills/trtc/room-builder/SKILL.md +138 -0
  66. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +108 -0
  67. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/backend-contract.zh-CN.md +162 -0
  68. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/integration.zh-CN.md +154 -0
  69. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/theme.zh-CN.md +78 -0
  70. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/index.html +12 -0
  71. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/package.json +28 -0
  72. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/postcss.config.js +5 -0
  73. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/App.vue +25 -0
  74. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/ConsultationManagePanel.vue +838 -0
  75. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LanguageSwitch.vue +102 -0
  76. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LoadingSpinner.vue +6 -0
  77. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalAlert.vue +34 -0
  78. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalBusinessPanel.vue +148 -0
  79. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalButton.vue +49 -0
  80. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalConfirmDialog.vue +68 -0
  81. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalDataPanel.vue +196 -0
  82. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalRecordPanel.vue +270 -0
  83. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/PrescriptionPanel.vue +363 -0
  84. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/basic-info-config.ts +29 -0
  85. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
  86. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
  87. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/runtime-config.ts +12 -0
  88. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/env.d.ts +32 -0
  89. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +123 -0
  90. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +230 -0
  91. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +135 -0
  92. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +113 -0
  93. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +132 -0
  94. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +50 -0
  95. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/types.ts +77 -0
  96. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationChat.ts +97 -0
  97. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationDevices.ts +48 -0
  98. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationParticipants.ts +121 -0
  99. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationPermissions.ts +25 -0
  100. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/utils.ts +70 -0
  101. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/en-US/index.ts +553 -0
  102. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/index.ts +25 -0
  103. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/medicalTranslate.ts +85 -0
  104. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/state.ts +49 -0
  105. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/zh-CN/index.ts +463 -0
  106. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/main.ts +12 -0
  107. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/appointments.ts +96 -0
  108. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/users.ts +79 -0
  109. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/router/index.ts +63 -0
  110. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/index.ts +25 -0
  111. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/appointmentService.ts +77 -0
  112. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/authService.ts +38 -0
  113. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/launchContext.ts +31 -0
  114. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/userService.ts +35 -0
  115. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/appointmentService.ts +43 -0
  116. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/authService.ts +33 -0
  117. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/userService.ts +43 -0
  118. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/types.ts +135 -0
  119. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/shared/icons.ts +53 -0
  120. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/index.css +106 -0
  121. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/tailwind.css +3 -0
  122. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/theme.css +209 -0
  123. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/auth.ts +50 -0
  124. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/format.ts +24 -0
  125. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/navigation.ts +12 -0
  126. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/session.ts +28 -0
  127. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorConsultationView.vue +777 -0
  128. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorDashboardView.vue +678 -0
  129. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/LoginView.vue +441 -0
  130. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationFinishedView.vue +185 -0
  131. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationView.vue +1003 -0
  132. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientSelectDoctorView.vue +317 -0
  133. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientWaitingView.vue +454 -0
  134. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.json +21 -0
  135. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.node.json +8 -0
  136. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/vite.config.ts +17 -0
  137. package/skills/trtc/room-builder/templates/scenarios/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md +6 -0
  138. package/skills/trtc/room-builder/tools/render_ai_instructions.py +226 -0
  139. package/skills/trtc-apply/SKILL.md +97 -0
  140. package/skills/trtc-apply/guardrails/apply_lib/__init__.py +0 -0
  141. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/__init__.cpython-313.pyc +0 -0
  142. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/rule_parser.cpython-313.pyc +0 -0
  143. package/skills/trtc-apply/guardrails/apply_lib/rule_parser.py +268 -0
  144. package/skills/trtc-docs/SKILL.md +207 -0
  145. package/skills/trtc-onboarding/SKILL.md +839 -0
  146. package/skills/trtc-onboarding/reference/path-a1-demo.md +103 -0
  147. package/skills/trtc-onboarding/reference/path-a2-integrate.md +693 -0
  148. package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +115 -0
  149. package/skills/trtc-onboarding/reference/path-c-expand.md +43 -0
  150. package/skills/trtc-onboarding/reference/reporting-protocol.md +174 -0
  151. package/skills/trtc-onboarding/reference/supported-matrix.md +100 -0
  152. package/skills/trtc-onboarding/reference/usersig-handling.md +140 -0
  153. package/skills/trtc-search/SKILL.md +221 -0
  154. package/skills/trtc-topic/SKILL.md +638 -0
  155. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_read.cpython-313.pyc +0 -0
  156. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_write.cpython-313.pyc +0 -0
  157. package/skills/trtc-topic/guardrails/__pycache__/stop_require_apply_evidence.cpython-313.pyc +0 -0
  158. package/skills/trtc-topic/guardrails/gate_slice_read.py +133 -0
  159. package/skills/trtc-topic/guardrails/gate_slice_write.py +169 -0
  160. package/skills/trtc-topic/guardrails/stop_require_apply_evidence.py +97 -0
  161. package/skills/trtc-topic/references/execution-units.yaml +58 -0
  162. package/skills/trtc-topic/runtime/README.md +50 -0
  163. package/skills/trtc-topic/runtime/RUNTIME.md +128 -0
  164. package/skills/trtc-topic/runtime/lib/__init__.py +0 -0
  165. package/skills/trtc-topic/runtime/lib/platforms.py +194 -0
  166. package/skills/trtc-topic/runtime/package-lock.json +1211 -0
  167. package/skills/trtc-topic/runtime/package.json +13 -0
  168. package/skills/trtc-topic/runtime/telemetry-bridge.mjs +339 -0
  169. package/skills/trtc-topic/runtime/telemetry_collector.py +293 -0
  170. package/skills/trtc-topic/scripts/STATE-MACHINE-GUIDE.md +186 -0
  171. package/skills/trtc-topic/scripts/__pycache__/apply.cpython-313.pyc +0 -0
  172. package/skills/trtc-topic/scripts/apply.py +581 -0
  173. package/skills/trtc-topic/scripts/finalize_session.py +113 -0
  174. package/skills/trtc-topic/scripts/init_slice_queue.py +96 -0
  175. package/skills/trtc-topic/scripts/lib/__pycache__/state_machine.cpython-313.pyc +0 -0
  176. package/skills/trtc-topic/scripts/lib/state_machine.py +328 -0
  177. package/skills/trtc-topic/scripts/next_slice.py +137 -0
  178. package/skills/trtc-topic/tests/README.md +70 -0
  179. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
  180. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  181. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.2.pyc +0 -0
  182. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  183. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.2.pyc +0 -0
  184. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.3.pyc +0 -0
  185. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.2.pyc +0 -0
  186. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.3.pyc +0 -0
  187. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.2.pyc +0 -0
  188. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.3.pyc +0 -0
  189. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.2.pyc +0 -0
  190. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.3.pyc +0 -0
  191. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.2.pyc +0 -0
  192. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.3.pyc +0 -0
  193. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.2.pyc +0 -0
  194. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.3.pyc +0 -0
  195. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.2.pyc +0 -0
  196. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.3.pyc +0 -0
  197. package/skills/trtc-topic/tests/conftest.py +72 -0
  198. package/skills/trtc-topic/tests/test_apply_cli.py +480 -0
  199. package/skills/trtc-topic/tests/test_end_to_end.py +305 -0
  200. package/skills/trtc-topic/tests/test_finalize_session.py +51 -0
  201. package/skills/trtc-topic/tests/test_gates.py +316 -0
  202. package/skills/trtc-topic/tests/test_session_resolver.py +260 -0
  203. package/skills/trtc-topic/tests/test_state_machine.py +414 -0
  204. package/skills/trtc-topic/tests/test_stop_require_apply.py +99 -0
  205. package/skills/trtc-topic/tests/test_topic_skill_invariants.py +130 -0
@@ -0,0 +1,323 @@
1
+ ---
2
+ id: live/beauty
3
+ platform: ios
4
+ ---
5
+
6
+ # 美颜 — iOS 实现
7
+
8
+ ## 前置条件
9
+
10
+ **依赖安装(Podfile)**
11
+ ```ruby
12
+ pod 'AtomicXCore', '~> 4.0'
13
+ ```
14
+
15
+ **前置状态**:
16
+ - `DeviceStore.shared.openLocalCamera` 已成功回调(摄像头已打开)
17
+ - AtomicXCore 授权包含基础美颜功能
18
+
19
+ ## API 调用
20
+
21
+ ```swift
22
+ // 获取单例
23
+ let beautyStore = BaseBeautyStore.shared
24
+
25
+ // 设置磨皮强度(0–9,类型为 Float)
26
+ beautyStore.setSmoothLevel(smoothLevel: Float)
27
+
28
+ // 设置美白强度(0–9,类型为 Float)
29
+ beautyStore.setWhitenessLevel(whitenessLevel: Float)
30
+
31
+ // 设置红润强度(0–9,类型为 Float)
32
+ beautyStore.setRuddyLevel(ruddyLevel: Float)
33
+
34
+ // 重置所有美颜参数
35
+ beautyStore.reset()
36
+
37
+ // 订阅状态变化
38
+ beautyStore.state // StatePublisher<BaseBeautyState>
39
+ // BaseBeautyState.smoothLevel: Float
40
+ // BaseBeautyState.whitenessLevel: Float
41
+ // BaseBeautyState.ruddyLevel: Float
42
+ ```
43
+
44
+ > ⚠️ **参数类型为 `Float`,不是 `Int`**。范围 0–9,0 表示关闭,9 为最强。
45
+
46
+ | 参数 | 类型 | 范围 | 说明 |
47
+ |------|------|------|------|
48
+ | `smoothLevel` | `Float` | 0–9 | 磨皮强度,0 = 关闭 |
49
+ | `whitenessLevel` | `Float` | 0–9 | 美白强度,0 = 关闭 |
50
+ | `ruddyLevel` | `Float` | 0–9 | 红润强度,0 = 关闭 |
51
+
52
+ **UI 值映射**:UI 滑块通常范围 `0.0–1.0`,调用 SDK 前需乘以 9:
53
+ ```
54
+ SDK Float 参数 = UISlider.value(0.0–1.0)× 9.0
55
+ ```
56
+
57
+ ## 代码示例
58
+
59
+ ### 完整美颜集成
60
+
61
+ ```swift
62
+ import AtomicXCore
63
+ import Combine
64
+
65
+ final class BeautyPanelViewModel {
66
+
67
+ // MARK: - 属性
68
+
69
+ private let beautyStore = BaseBeautyStore.shared
70
+ private var cancellables = Set<AnyCancellable>()
71
+
72
+ /// UI 滑块值(0.0-1.0),通过映射驱动 SDK
73
+ @Published var smoothSlider: Float = 0.0
74
+ @Published var whitenessSlider: Float = 0.0
75
+ @Published var ruddySlider: Float = 0.0
76
+
77
+ // MARK: - 初始化
78
+
79
+ init() {
80
+ // 步骤1: 订阅 SDK 状态,同步到 UI 滑块
81
+ subscribeBeautyState()
82
+
83
+ // 步骤2: 订阅 UI 滑块变化,映射后调用 SDK
84
+ bindSliderToSDK()
85
+ }
86
+
87
+ // MARK: - 状态订阅(SDK → UI)
88
+
89
+ private func subscribeBeautyState() {
90
+ // BaseBeautyState 的属性均为 Float
91
+ beautyStore.state
92
+ .receive(on: DispatchQueue.main)
93
+ .sink { [weak self] state in
94
+ // 将 SDK 参数(Float,0-9)转换为 UI 滑块值(0.0-1.0)
95
+ self?.smoothSlider = state.smoothLevel / 9.0
96
+ self?.whitenessSlider = state.whitenessLevel / 9.0
97
+ self?.ruddySlider = state.ruddyLevel / 9.0
98
+ }
99
+ .store(in: &cancellables)
100
+ }
101
+
102
+ // MARK: - UI 绑定(UI → SDK)
103
+
104
+ private func bindSliderToSDK() {
105
+ // 磨皮滑块变化 → 调用 SDK
106
+ $smoothSlider
107
+ .dropFirst() // 跳过初始值,避免重复设置
108
+ .sink { [weak self] value in
109
+ self?.setSmoothLevel(sliderValue: value)
110
+ }
111
+ .store(in: &cancellables)
112
+
113
+ // 美白滑块变化 → 调用 SDK
114
+ $whitenessSlider
115
+ .dropFirst()
116
+ .sink { [weak self] value in
117
+ self?.setWhitenessLevel(sliderValue: value)
118
+ }
119
+ .store(in: &cancellables)
120
+
121
+ // 红润滑块变化 → 调用 SDK
122
+ $ruddySlider
123
+ .dropFirst()
124
+ .sink { [weak self] value in
125
+ self?.setRuddyLevel(sliderValue: value)
126
+ }
127
+ .store(in: &cancellables)
128
+ }
129
+
130
+ // MARK: - 美颜参数设置(含 UI→SDK 值映射)
131
+
132
+ /// 设置磨皮(UI 滑块值 0.0-1.0 → SDK Float 0-9)
133
+ func setSmoothLevel(sliderValue: Float) {
134
+ // 步骤3: UI 值 ×9 转换为 SDK Float 参数
135
+ let sdkValue = clamp(sliderValue * 9.0)
136
+ beautyStore.setSmoothLevel(smoothLevel: sdkValue)
137
+ }
138
+
139
+ /// 设置美白(UI 滑块值 0.0-1.0 → SDK Float 0-9)
140
+ func setWhitenessLevel(sliderValue: Float) {
141
+ let sdkValue = clamp(sliderValue * 9.0)
142
+ beautyStore.setWhitenessLevel(whitenessLevel: sdkValue)
143
+ }
144
+
145
+ /// 设置红润(UI 滑块值 0.0-1.0 → SDK Float 0-9)
146
+ func setRuddyLevel(sliderValue: Float) {
147
+ let sdkValue = clamp(sliderValue * 9.0)
148
+ beautyStore.setRuddyLevel(ruddyLevel: sdkValue)
149
+ }
150
+
151
+ /// 重置所有美颜参数(步骤4)
152
+ func resetBeauty() {
153
+ beautyStore.reset()
154
+ // $state 订阅会自动将滑块归零,无需手动设置
155
+ }
156
+
157
+ // MARK: - 工具方法
158
+
159
+ /// 参数截断,防止超出 0–9 范围
160
+ private func clamp(_ value: Float) -> Float {
161
+ return min(max(value, 0.0), 9.0)
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### UI 滑块绑定(UIKit)
167
+
168
+ ```swift
169
+ import UIKit
170
+ import Combine
171
+
172
+ final class BeautyPanelViewController: UIViewController {
173
+
174
+ // MARK: - UI 元素
175
+
176
+ @IBOutlet weak var smoothSlider: UISlider! // 磨皮
177
+ @IBOutlet weak var whitenessSlider: UISlider! // 美白
178
+ @IBOutlet weak var ruddySlider: UISlider! // 红润
179
+ @IBOutlet weak var resetButton: UIButton!
180
+
181
+ private let viewModel = BeautyPanelViewModel()
182
+ private var cancellables = Set<AnyCancellable>()
183
+
184
+ // MARK: - 生命周期
185
+
186
+ override func viewDidLoad() {
187
+ super.viewDidLoad()
188
+ setupSliders()
189
+ bindViewModel()
190
+ }
191
+
192
+ private func setupSliders() {
193
+ [smoothSlider, whitenessSlider, ruddySlider].forEach {
194
+ $0?.minimumValue = 0.0
195
+ $0?.maximumValue = 1.0
196
+ }
197
+ }
198
+
199
+ // MARK: - ViewModel 绑定
200
+
201
+ private func bindViewModel() {
202
+ // ViewModel → UI:SDK 状态变化驱动滑块位置
203
+ viewModel.$smoothSlider
204
+ .receive(on: DispatchQueue.main)
205
+ .assign(to: \.value, on: smoothSlider)
206
+ .store(in: &cancellables)
207
+
208
+ viewModel.$whitenessSlider
209
+ .receive(on: DispatchQueue.main)
210
+ .assign(to: \.value, on: whitenessSlider)
211
+ .store(in: &cancellables)
212
+
213
+ viewModel.$ruddySlider
214
+ .receive(on: DispatchQueue.main)
215
+ .assign(to: \.value, on: ruddySlider)
216
+ .store(in: &cancellables)
217
+ }
218
+
219
+ // MARK: - 用户交互
220
+
221
+ @IBAction func smoothSliderChanged(_ sender: UISlider) {
222
+ viewModel.smoothSlider = sender.value
223
+ }
224
+
225
+ @IBAction func whitenessSliderChanged(_ sender: UISlider) {
226
+ viewModel.whitenessSlider = sender.value
227
+ }
228
+
229
+ @IBAction func ruddySliderChanged(_ sender: UISlider) {
230
+ viewModel.ruddySlider = sender.value
231
+ }
232
+
233
+ @IBAction func resetTapped(_ sender: UIButton) {
234
+ viewModel.resetBeauty()
235
+ // 滑块会通过 $state 订阅自动归零
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### 连麦观众场景复用
241
+
242
+ ```swift
243
+ // 连麦观众打开摄像头后,直接复用同一单例
244
+ func onCoGuestCameraOpened() {
245
+ // DeviceStore.openLocalCamera 成功后即可设置美颜
246
+ // BaseBeautyStore.shared 持有上次的 Float 参数,无需重新配置
247
+ let currentState = BaseBeautyStore.shared.state
248
+ print("[Beauty] 当前磨皮: \(currentState.smoothLevel), 美白: \(currentState.whitenessLevel)")
249
+
250
+ // 若需要重置(连麦场景可能不需要美颜)
251
+ // BaseBeautyStore.shared.reset()
252
+ }
253
+ ```
254
+
255
+ ## 调用时序
256
+
257
+ ```
258
+ 摄像头打开成功(openLocalCamera .success)
259
+
260
+
261
+ BaseBeautyStore.shared // 获取单例(无需初始化)
262
+
263
+
264
+ 订阅 state // 建立状态监听,驱动 UI 同步
265
+
266
+ ├─ 用户调整磨皮滑块
267
+ │ │
268
+ │ ▼
269
+ │ UISlider.value × 9.0 → setSmoothLevel(smoothLevel: Float)
270
+ │ │
271
+ │ └─ state 更新 → UI 滑块位置同步确认
272
+
273
+ ├─ 用户调整美白滑块
274
+ │ │
275
+ │ └─ setWhitenessLevel(whitenessLevel: Float)
276
+
277
+ ├─ 用户调整红润滑块
278
+ │ │
279
+ │ └─ setRuddyLevel(ruddyLevel: Float)
280
+
281
+ ├─ 用户点击重置
282
+ │ │
283
+ │ ▼
284
+ │ reset()
285
+ │ │
286
+ │ └─ state 更新(所有 Float 值归 0)→ UI 滑块自动归零
287
+
288
+ └─ 关闭摄像头 / 退出直播间
289
+
290
+
291
+ cancellables.removeAll() // 清理订阅
292
+ ```
293
+
294
+ ## 平台特有注意事项
295
+
296
+ ### 1. 参数类型为 Float
297
+ `setSmoothLevel`、`setWhitenessLevel`、`setRuddyLevel` 的参数和 `BaseBeautyState` 的所有属性均为 `Float`,不是 `Int`。不要对参数做 `Int()` 截断,否则会丢失精度(如 4.5 会变成 4)。
298
+
299
+ ### 2. 真机测试
300
+ iOS 模拟器不支持摄像头采集,美颜效果**必须在真机上验证**。模拟器上调用美颜接口不会报错,但无法看到实际效果。
301
+
302
+ ### 3. 滑块防抖
303
+ 用户拖动滑块时会高频触发 `valueChanged`,建议对 SDK 调用做 100ms 防抖,避免过高的调用频率影响性能:
304
+
305
+ ```swift
306
+ private var beautyDebounceTimer: Timer?
307
+
308
+ func setSmoothLevelDebounced(sliderValue: Float) {
309
+ beautyDebounceTimer?.invalidate()
310
+ beautyDebounceTimer = Timer.scheduledTimer(
311
+ withTimeInterval: 0.1,
312
+ repeats: false
313
+ ) { [weak self] _ in
314
+ self?.viewModel.setSmoothLevel(sliderValue: sliderValue)
315
+ }
316
+ }
317
+ ```
318
+
319
+ ### 4. App 进入后台
320
+ iOS 后台时摄像头采集暂停,美颜效果自动停止作用。App 重新进入前台且摄像头恢复采集后,美颜参数会自动继续生效(单例保留了上次的 Float 参数设置),无需重新调用。
321
+
322
+ ### 5. 与滤镜功能的关系
323
+ `BaseBeautyStore` 仅提供基础美颜(磨皮/美白/红润)。如需高级美颜(瘦脸、大眼等)或滤镜功能,需要接入腾讯特效 SDK(XMagic),配置不同的授权。