@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,197 @@
1
+ ---
2
+ id: conference/virtual-background
3
+ name: 虚拟背景
4
+ product: conference
5
+ platform: web
6
+ tags: [virtual-background, blur, assetsPath, useVirtualBackgroundState]
7
+ platforms: [web]
8
+ related: [conference/device-control, conference/video-layout, conference/beauty-effects]
9
+ api_docs:
10
+ - title: 虚拟背景
11
+ url: https://cloud.tencent.com/document/product/647/126935
12
+ ---
13
+
14
+ # 虚拟背景
15
+
16
+ ## 功能说明
17
+
18
+ 虚拟背景负责会议中本地视频的背景增强能力,包括背景虚化、图片替换、模型资源初始化、浏览器支持性检测以及从预览到正式生效的完整链路。与基础美颜相比,它更依赖模型资源、浏览器能力和初始化流程。
19
+
20
+ ## 核心概念
21
+
22
+ ### 角色与操作
23
+
24
+ | 角色 | 关键操作 | 说明 |
25
+ |------|----------|------|
26
+ | 当前参会人 | 选择背景模式 | 可以切换虚化、图片背景或关闭虚拟背景 |
27
+ | 虚拟背景面板 | 管理模式与预览 | 承载背景模式选择、资源初始化和确认保存入口 |
28
+ | 浏览器 / 模型运行时 | 提供支持能力 | 决定当前环境是否支持虚拟背景以及模型是否可初始化 |
29
+ | 本地视频处理链 | 应用背景效果 | 将保存后的背景设置作用到本地视频流 |
30
+
31
+ ### 事件流
32
+
33
+ | 阶段 | 参与方 | 关键动作 |
34
+ |------|--------|----------|
35
+ | 支持性检测 | 浏览器 / 客户端 | 先确认当前环境是否支持虚拟背景 |
36
+ | 资源初始化 | 客户端 | 依据 `assetsPath` 等条件初始化背景模型资源 |
37
+ | 效果预览 | 当前参会人 | 选择虚化或图片背景,并在本地画面上实时预览 |
38
+ | 确认保存 | 当前参会人 | 将当前背景设置正式应用到会中视频流 |
39
+ | 降级回退 | 客户端 | 不支持或初始化失败时回退到普通视频能力 |
40
+
41
+ ### 状态与数据
42
+
43
+ | 数据 / 状态 | 说明 |
44
+ |-------------|------|
45
+ | `isSupported` | 表示当前浏览器是否支持虚拟背景能力 |
46
+ | 初始化状态 | 标识模型资源是否已成功加载并可用 |
47
+ | `assetsPath` | Web 端初始化模型资源时的重要前置条件 |
48
+ | 当前背景模式 | 关闭、虚化、图片替换等模式 |
49
+ | 预览态 / 已保存态 | 区分当前面板中试用效果与真正对外生效的设置 |
50
+
51
+ ### 状态机
52
+
53
+ ```text
54
+ unsupported
55
+
56
+ idle
57
+ → checking-support
58
+ → initializing
59
+ → previewing
60
+ → saved
61
+ → active
62
+ → cleared
63
+ ```
64
+
65
+ ## 前置条件
66
+ **通用依赖**:见 [login-auth 平台 slice](login-auth.md)。
67
+
68
+ **额外依赖**:
69
+ - 已安装 `tuikit-atomicx-vue3@latest`
70
+
71
+ **前置状态**:
72
+ - 已阅读 `conference/virtual-background`,明确当前能力的产品边界。
73
+ - 已完成 `conference/login-auth`,确保当前页面具备稳定登录态。
74
+ - 已根据业务流程接入会议上下文;需要房间状态时,优先通过 `conference/room-lifecycle` 统一承接。
75
+ - 当前能力涉及媒体采集、渲染或浏览器权限时,请在 `HTTPS` 或 `localhost` 安全上下文下调试。
76
+
77
+ ## 最佳实践
78
+
79
+ ### ✅ ALWAYS
80
+
81
+ 1. **先做支持性检测,再开放设置入口** —— 不支持的环境应直接降级,而不是让用户在无效面板里反复尝试。
82
+ 2. **把资源初始化作为显式前置步骤** —— `assetsPath`、模型资源和初始化结果应被明确管理。
83
+ 3. **区分预览效果与正式保存结果** —— 让用户确认满意后再真正应用到会中画面。
84
+ 4. **准备好不支持场景下的降级方案** —— 对不支持的浏览器应回到普通摄像头画面,而不是让视频链路中断。
85
+
86
+ ### ❌ NEVER
87
+
88
+ 1. **不要跳过初始化直接设置虚拟背景** —— 缺少模型资源时,效果很可能无法生效或表现异常。
89
+ 2. **不要默认所有浏览器都支持相同能力** —— 虚拟背景的兼容性明显强依赖浏览器和环境。
90
+ 3. **不要把虚拟背景与基础美颜混成同一份无边界的状态** —— 它们都作用于本地视频,但依赖与失败模式不同。
91
+
92
+ ## 代码示例
93
+ ### 初始化模型资源并保存虚拟背景效果
94
+
95
+ ```ts
96
+ import { onMounted } from 'vue';
97
+ import { useVirtualBackgroundState } from 'tuikit-atomicx-vue3/room';
98
+
99
+ const { isSupported, initVirtualBackground, setVirtualBackground, saveVirtualBackground } = useVirtualBackgroundState();
100
+
101
+ onMounted(async () => {
102
+ if (!isSupported()) return;
103
+ await initVirtualBackground({ assetsPath: 'https://cdn.example.com/assets' });
104
+ await setVirtualBackground({ enable: true, type: 'blur', level: 0.5 });
105
+ await saveVirtualBackground();
106
+ });
107
+ ```
108
+
109
+ ## 调用时序
110
+ ```
111
+ 完成 login-auth 并准备本地视频
112
+
113
+
114
+ 调用 isSupported() 检查浏览器能力
115
+
116
+ ├─ 不支持 → 隐藏入口或走降级文案
117
+ └─ 支持
118
+
119
+
120
+ initVirtualBackground({ assetsPath })
121
+
122
+
123
+ setVirtualBackground(...) 做预览
124
+
125
+ ├─ 用户确认 → saveVirtualBackground()
126
+ └─ 用户取消 / 关闭 → 回退或关闭背景效果
127
+ ```
128
+
129
+ ## 平台特有注意事项
130
+ ### 1. `assetsPath` 是虚拟背景能否启动的关键前置条件
131
+ 必须先成功初始化 `assetsPath` 对应的模型或资源目录,否则虚拟背景功能无法正常工作。
132
+
133
+ ### 2. 兼容性检查必须放在渲染前
134
+ 浏览器对虚拟背景的支持差异明显,建议在页面入口或打开设置面板前先调用 `isSupported()` 做能力判断。
135
+
136
+ ### 3. 虚拟背景比基础美颜更吃性能
137
+ 在低性能设备上,虚拟背景更容易带来 CPU / GPU 压力;业务应允许快速关闭,并提供清晰的降级说明。
138
+
139
+ ## 代码生成约束
140
+ ### 编译必要条件
141
+ - **通用条件**:见 [login-auth 平台 slice](login-auth.md)。
142
+ - **额外导入**:至少需要导入 `useVirtualBackgroundState`。
143
+ - **运行前提**:浏览器支持该能力、页面处于安全上下文,且 `assetsPath` 可访问。
144
+
145
+ ### 生成规则
146
+ #### MUST(生成时必须包含)
147
+
148
+ 1. **在启用虚拟背景前先做能力检查与初始化** — 否则会出现入口可见但能力不可用的假状态。
149
+ **Verify**: 检查是否存在 `isSupported()` 与 `initVirtualBackground(`。
150
+ 2. **把预览与最终保存分开处理** — 用户需要有确认生效的动作,而不是一改即永久保存。
151
+ **Verify**: 检查是否同时存在 `setVirtualBackground(` 与 `saveVirtualBackground(`。
152
+
153
+ #### MUST NOT(生成时绝不能出现)
154
+
155
+ 1. **不要跳过 `assetsPath` 初始化直接启用背景能力** — 功能无法正常启动。
156
+ **Verify**: 检查是否先调用 `initVirtualBackground({ assetsPath })`。
157
+ 2. **不要忽略不支持浏览器的降级路径** — 低兼容环境会直接报错或白屏。
158
+ **Verify**: 检查是否存在 `isSupported()` 判断和降级处理。
159
+
160
+ ### 集成检查点
161
+ - 当前 slice 常与 `conference/device-control`、`conference/beauty-effects` 联动。
162
+ - 集成方式通常是新增本地效果设置面板,不需要改动房间生命周期逻辑。
163
+ - 如果业务同时接入美颜和虚拟背景,建议在 UI 和性能策略上给出统一入口与优先级。
164
+
165
+ ## 验证矩阵
166
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
167
+ |------|--------|----------|---------|
168
+ | 1. 编译级 | 已导入 `useVirtualBackgroundState` | 检查 `import` 语句 | 虚拟背景 Hook 可解析 |
169
+ | 2. 静态规则级 | 存在能力检查、初始化、保存链路 | 搜索 `isSupported` / `initVirtualBackground` / `saveVirtualBackground` | 形成完整启用流程 |
170
+ | 3. 运行时级 | 支持浏览器可成功启用背景效果 | 在支持环境打开虚拟背景功能 | 能看到预览并保存效果 |
171
+ | 4. 业务行为级 | 不支持或低性能环境有清晰降级 | 在不支持环境或低性能设备联调 | 页面能正确隐藏入口或提示降级 |
172
+
173
+ ## 排障指南
174
+
175
+ ### 常见问题
176
+
177
+ | 问题 | 表现 | 处理建议 |
178
+ |------|------|----------|
179
+ | 面板可打开但效果不可用 | 用户能看到背景设置入口,但切换后画面无变化 | 检查浏览器支持性检测和初始化是否真正成功 |
180
+ | 初始化失败 | 选择背景时直接报错或模型资源加载失败 | 检查 `assetsPath`、资源可访问性以及初始化时机是否正确 |
181
+ | 保存后效果丢失 | 当前会议里可见,重新进入面板或再次开会后失效 | 检查预览态和已保存态是否区分维护,并确认初始化完成后再恢复设置 |
182
+
183
+ ### 排障流程
184
+
185
+ ```text
186
+ 发现 虚拟背景 相关问题
187
+ ├── 第 1 步:确认当前环境是否支持虚拟背景,不支持时应直接走降级路径
188
+ ├── 第 2 步:检查 assetsPath 和模型初始化流程是否完整且已成功完成
189
+ ├── 第 3 步:确认当前背景设置是否仍停留在预览态,还是已经正式保存到视频流
190
+ └── 第 4 步:若仍异常,再回查 device-control / video-layout / beauty-effects 的衔接是否正确
191
+ ```
192
+
193
+ ## 关联知识
194
+
195
+ - **[conference/device-control](device-control.md)** —— 摄像头是否已准备好会直接影响虚拟背景是否具备可视化预览前提。
196
+ - **[conference/video-layout](video-layout.md)** —— 背景效果最终体现为布局中的本地画面变化。
197
+ - **[conference/beauty-effects](beauty-effects.md)** —— 与虚拟背景同属本地视频前处理,但初始化要求和失败模式不同。
@@ -0,0 +1,206 @@
1
+ ---
2
+ id: conference/webinar-interaction
3
+ name: Webinar 举手、上台与弹幕互动
4
+ product: conference
5
+ platform: web
6
+ tags: [webinar, raise-hand, audience, participant, barrage, requestToOpenDevice]
7
+ platforms: [web]
8
+ related: [conference/room-lifecycle, conference/participant-management, conference/room-chat]
9
+ ---
10
+
11
+ # Webinar 举手、上台与弹幕互动
12
+
13
+ ## 功能说明
14
+
15
+ Webinar 互动负责研讨会房型中的观众举手、主持人审批、观众上台成为嘉宾、设备申请收口以及弹幕互动。它解决的是“观众如何申请发言、主持人如何处理申请、观众区如何低成本互动”,不是普通 Standard 会议的成员管理入口。
16
+
17
+ Conference Core 中,观众举手本质上是 `requestToOpenDevice({ device: DeviceType.Microphone })`;主持人侧通过 `pendingDeviceApplications` 展示待处理申请,接受时先 `promoteToParticipant()`,再 `approveOpenDeviceRequest()`。
18
+
19
+ ## 核心概念
20
+
21
+ | 能力 | 说明 |
22
+ |------|------|
23
+ | `RoomType.Webinar` | 研讨会房型,区分房主/管理员、嘉宾和观众 |
24
+ | 观众举手 | 观众申请打开麦克风,进入待审批队列 |
25
+ | `pendingDeviceApplications` | 主持人或管理员侧看到的设备申请列表 |
26
+ | 上台 | 观众被提升为嘉宾/参会人后才能参与发言或开设备 |
27
+ | 弹幕 | Webinar 低门槛互动入口,通常基于 live barrage 状态和组件 |
28
+ | 禁言联动 | 弹幕输入和普通聊天一样需要联动 `localParticipant.isMessageDisabled` |
29
+
30
+ ## 前置条件
31
+
32
+ **通用依赖**:见 [login-auth 平台 slice](login-auth.md)。
33
+
34
+ **额外依赖**:
35
+ - 已安装 `tuikit-atomicx-vue3@latest`
36
+ - Webinar 房间应使用 `RoomType.Webinar` 创建或加入。
37
+
38
+ ## 最佳实践
39
+
40
+ ### ✅ ALWAYS
41
+
42
+ 1. **只在 Webinar 房型中启用举手和弹幕入口** —— Standard 会议优先使用成员管理和会中聊天。
43
+ 2. **观众端举手用 `requestToOpenDevice({ device: DeviceType.Microphone })`** —— 不要让观众直接 `openLocalMicrophone()` 绕过审批。
44
+ 3. **主持人接受申请时先上台再批准设备** —— 推荐顺序是 `promoteToParticipant()` → `approveOpenDeviceRequest()`。
45
+ 4. **拒绝、超时、已批准都要清理观众端举手状态** —— 避免按钮一直显示“已举手”。
46
+ 5. **弹幕输入必须联动禁言状态** —— `localParticipant.isMessageDisabled` 生效时,输入框和发送链路都要禁用。
47
+ 6. **弹幕未读数只在面板关闭时累积** —— 打开面板应清零,并在切房间时重置。
48
+
49
+ ### ❌ NEVER
50
+
51
+ 1. **不要把 Webinar 观众当作普通会议成员直接开麦/开摄** —— 观众发言必须经过申请和审批。
52
+ 2. **不要只批准设备而不提升角色** —— 观众仍可能没有上台权限,导致申请看似通过但设备不可用。
53
+ 3. **不要把 Webinar 弹幕直接套用普通会议 `GROUP${roomId}` 聊天逻辑** —— Webinar 弹幕应使用 live barrage 能力。
54
+
55
+ ## 代码示例
56
+
57
+ ### 观众举手与取消举手
58
+
59
+ ```ts
60
+ import { ref, onMounted, onUnmounted } from 'vue';
61
+ import {
62
+ DeviceType,
63
+ RoomParticipantEvent,
64
+ useRoomParticipantState,
65
+ } from 'tuikit-atomicx-vue3/room';
66
+
67
+ const {
68
+ requestToOpenDevice,
69
+ cancelOpenDeviceRequest,
70
+ subscribeEvent,
71
+ unsubscribeEvent,
72
+ } = useRoomParticipantState();
73
+
74
+ const isRaised = ref(false);
75
+
76
+ export async function toggleRaiseHand() {
77
+ if (isRaised.value) {
78
+ await cancelOpenDeviceRequest({ device: DeviceType.Microphone });
79
+ isRaised.value = false;
80
+ return;
81
+ }
82
+
83
+ await requestToOpenDevice({ device: DeviceType.Microphone, timeout: 30 });
84
+ isRaised.value = true;
85
+ }
86
+
87
+ const resetRaised = () => {
88
+ isRaised.value = false;
89
+ };
90
+
91
+ onMounted(() => {
92
+ subscribeEvent(RoomParticipantEvent.onDeviceRequestApproved, resetRaised);
93
+ subscribeEvent(RoomParticipantEvent.onDeviceRequestRejected, resetRaised);
94
+ subscribeEvent(RoomParticipantEvent.onDeviceRequestTimeout, resetRaised);
95
+ });
96
+
97
+ onUnmounted(() => {
98
+ unsubscribeEvent(RoomParticipantEvent.onDeviceRequestApproved, resetRaised);
99
+ unsubscribeEvent(RoomParticipantEvent.onDeviceRequestRejected, resetRaised);
100
+ unsubscribeEvent(RoomParticipantEvent.onDeviceRequestTimeout, resetRaised);
101
+ });
102
+ ```
103
+
104
+ ### 主持人处理举手列表
105
+
106
+ ```ts
107
+ import { computed } from 'vue';
108
+ import { useRoomParticipantState, type DeviceRequestInfo } from 'tuikit-atomicx-vue3/room';
109
+
110
+ const {
111
+ pendingDeviceApplications,
112
+ promoteToParticipant,
113
+ approveOpenDeviceRequest,
114
+ rejectOpenDeviceRequest,
115
+ } = useRoomParticipantState();
116
+
117
+ const pendingCount = computed(() => pendingDeviceApplications.value.length);
118
+
119
+ export async function approveRaiseHand(invitation: DeviceRequestInfo) {
120
+ await promoteToParticipant({ userId: invitation.senderUserId });
121
+ await approveOpenDeviceRequest({
122
+ device: invitation.deviceType,
123
+ userId: invitation.senderUserId,
124
+ });
125
+ }
126
+
127
+ export async function rejectRaiseHand(invitation: DeviceRequestInfo) {
128
+ await rejectOpenDeviceRequest({
129
+ device: invitation.deviceType,
130
+ userId: invitation.senderUserId,
131
+ });
132
+ }
133
+ ```
134
+
135
+ ### Webinar 弹幕入口
136
+
137
+ ```vue
138
+ <template>
139
+ <BarrageList class="message-list" />
140
+ <BarrageInput
141
+ class="message-input"
142
+ :disabled="localParticipant?.isMessageDisabled"
143
+ />
144
+ </template>
145
+
146
+ <script setup lang="ts">
147
+ import { BarrageInput, BarrageList } from 'tuikit-atomicx-vue3/live';
148
+ import { useRoomParticipantState } from 'tuikit-atomicx-vue3/room';
149
+
150
+ const { localParticipant } = useRoomParticipantState();
151
+ </script>
152
+ ```
153
+
154
+ ## 平台特有注意事项
155
+
156
+ ### 1. 举手不是直接开麦
157
+ 观众端只发起 `requestToOpenDevice()`,真实上台和设备批准由主持人/管理员处理。不要在观众点击举手后直接调用 `openLocalMicrophone()`。
158
+
159
+ ### 2. 接受申请要处理错误码
160
+ 嘉宾人数已满或权限不足时,`promoteToParticipant()` / `approveOpenDeviceRequest()` 可能失败。遇到 `ERR_ALL_SEAT_OCCUPIED` 和 `ERR_NO_PERMISSION` 时应给出明确提示。
161
+
162
+ ### 3. 弹幕和普通会议聊天不同源
163
+ 普通会议聊天使用 `tuikit-atomicx-vue3/chat` 的 `setActiveConversation(GROUP${roomId})`;Webinar 弹幕使用 `tuikit-atomicx-vue3/live` 的 `BarrageList`、`BarrageInput`、`useBarrageState()`。
164
+
165
+ ## 代码生成约束
166
+
167
+ ### MUST
168
+
169
+ 1. **观众举手使用 `requestToOpenDevice({ device: DeviceType.Microphone })`**。
170
+ **Verify**: 检查是否存在 `requestToOpenDevice`。
171
+ 2. **主持人接受申请时先 `promoteToParticipant()` 再 `approveOpenDeviceRequest()`**。
172
+ **Verify**: 检查接受处理函数里的调用顺序。
173
+ 3. **监听 approved/rejected/timeout 事件重置举手状态**。
174
+ **Verify**: 检查 `RoomParticipantEvent.onDeviceRequest*` 监听。
175
+ 4. **Webinar 弹幕使用 live barrage 组件或状态**。
176
+ **Verify**: 检查是否从 `tuikit-atomicx-vue3/live` 导入 `BarrageInput` / `BarrageList` / `useBarrageState`。
177
+
178
+ ### MUST NOT
179
+
180
+ 1. **不要让观众举手后直接开麦**。
181
+ **Verify**: 检查观众举手函数中是否直接调用 `openLocalMicrophone()`。
182
+ 2. **不要用普通会议聊天会话替代 Webinar 弹幕**。
183
+ **Verify**: Webinar 弹幕代码中不应只出现 `setActiveConversation(GROUP${roomId})`。
184
+
185
+ ## 验证矩阵
186
+
187
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
188
+ |------|--------|----------|---------|
189
+ | 1. 编译级 | Webinar 相关 API 可解析 | 检查 `DeviceType`、`RoomParticipantEvent`、barrage 导入 | 类型可解析 |
190
+ | 2. 静态规则级 | 接受举手顺序正确 | 阅读 `approveRaiseHand()` | 先上台再批准设备 |
191
+ | 3. 运行时级 | 观众举手和取消可用 | 双账号 Webinar 联调 | 主持人侧出现待处理申请 |
192
+ | 4. 业务行为级 | 弹幕禁言联动正确 | 禁言后尝试发送 | 输入或发送被拦截 |
193
+
194
+ ## 排障指南
195
+
196
+ | 问题 | 表现 | 处理建议 |
197
+ |------|------|----------|
198
+ | 观众举手后主持人看不到 | 待处理列表为空 | 检查是否在 Webinar 房型、是否调用 `requestToOpenDevice()` |
199
+ | 主持人同意后观众仍不能发言 | 申请通过但麦克风不可用 | 检查是否先调用 `promoteToParticipant()` 再批准设备 |
200
+ | 举手按钮状态不复位 | 拒绝或超时后仍显示已举手 | 监听 approved/rejected/timeout 事件并重置本地状态 |
201
+ | 弹幕被禁言仍可输入 | UI 和真实权限不一致 | 绑定 `localParticipant.isMessageDisabled` 并拦截发送 |
202
+
203
+ ## 关联知识
204
+
205
+ - **[conference/participant-management](participant-management.md)** —— 角色治理 + 全员禁言 / 禁设备等会控规则。
206
+ - **[conference/room-chat](room-chat.md)** —— 普通会议聊天,与 Webinar 弹幕需要区分。
@@ -0,0 +1,122 @@
1
+ ---
2
+ id: live/anchor-lifecycle
3
+ name: 主播开播与结束生命周期
4
+ product: live
5
+ tags: [anchor, start, end, createLive, endLive, lifecycle]
6
+ platforms: [ios, android, web, flutter]
7
+ related: [live/anchor-room-config, live/anchor-preview, live/device-control]
8
+ ---
9
+
10
+ # 主播开播与结束生命周期
11
+
12
+ ## 功能说明
13
+
14
+ 主播的完整生命周期包含两个核心动作:
15
+
16
+ - **`createLive`**:在服务端创建直播间并开始推流,观众可加入收看。
17
+ - **`endLive`**:结束直播、销毁服务端房间、停止推流。
18
+
19
+ 除主动结束外,还需监听 `liveListEventPublisher` 处理**被动结束**场景(如被踢出、网络异常等)。生命周期管理的正确性直接影响房间资源释放和用户体验。
20
+
21
+ ## 核心概念
22
+
23
+ ### createLive
24
+
25
+ 调用 `LiveListStore` 的 `createLive` 方法,传入直播信息对象,通过成功/失败回调获取结果。
26
+
27
+ | 行为 | 说明 |
28
+ |------|------|
29
+ | 创建服务端房间 | 以 `liveID` 为唯一标识在服务端创建直播间 |
30
+ | 开始推流 | 将本地摄像头/麦克风数据推送到 CDN |
31
+ | 生成直播列表条目 | 直播间出现在观众的直播列表中 |
32
+
33
+ **前置条件**:摄像头已打开(`openLocalCamera` 成功)+ `LiveInfo` 已配置。
34
+
35
+ ### endLive
36
+
37
+ 调用 `LiveListStore` 的 `endLive` 方法,传入直播间 ID,通过成功/失败回调获取结果。
38
+
39
+ | 行为 | 说明 |
40
+ |------|------|
41
+ | 通知所有观众直播结束 | 触发观众端 `onLiveEnded` 事件 |
42
+ | 销毁服务端房间 | 房间从直播列表消失 |
43
+ | 停止推流 | 本地推流通道关闭 |
44
+
45
+ ### 被动结束事件(liveListEventPublisher)
46
+
47
+ 通过订阅 `LiveListStore` 的直播列表事件监听以下事件:
48
+
49
+ | 事件 | 触发场景 | 处理建议 |
50
+ |------|----------|----------|
51
+ | `onLiveEnded(liveID:)` | 直播被服务端强制结束 / 主播在其他设备调用 endLive | 清理 UI,提示用户直播已结束 |
52
+ | `onKickedOutOfLive(liveID:reason:)` | 主播被管理员踢出直播间 | 显示踢出原因,释放资源,返回首页 |
53
+
54
+ ### 正确的结束顺序
55
+
56
+ 直播中可能存在 PK(跨房连麦)、连线(观众上麦)、连麦等子会话,结束时必须按以下顺序操作,避免资源未释放:
57
+
58
+ ```
59
+ 1. 结束 PK(如有) → endPK()
60
+ 2. 断开连线(如有) → disconnectLink()
61
+ 3. 断开连麦(如有) → stopCoguest()
62
+ 4. 关闭摄像头/麦克风 → 通过 DeviceStore 关闭本地摄像头和麦克风
63
+ 5. 结束直播 → 通过 LiveListStore 调用 endLive,传入 liveID
64
+ 6. 销毁 LiveCoreView → 仅在 endLive 回调成功后
65
+ ```
66
+
67
+ ## 最佳实践
68
+
69
+ ### ✅ ALWAYS
70
+
71
+ 1. **严格遵守结束顺序** — 先结束所有子会话(PK → 连线 → 连麦),再关闭设备,最后调 `endLive`。乱序操作会导致远端用户状态异常或推流未真正停止。
72
+ 2. **监听 `onLiveEnded` 事件** — 直播可能因网络问题、服务端策略或管理员操作而被动结束;监听此事件以保证 UI 和资源的正确清理。
73
+ 3. **在 `endLive` 回调成功后才释放 `LiveCoreView`** — 回调前释放会导致内部推流管道异常,可能产生残留连接。
74
+ 4. **`createLive` 成功后再更新 UI 状态** — 创建是异步操作,在回调成功前不应向用户展示「正在直播」状态。
75
+
76
+ ### ❌ NEVER
77
+
78
+ 1. **`endLive` 回调前释放 `LiveCoreView`** — 视图持有底层推流资源;过早释放会导致 crash 或资源泄漏。
79
+ 2. **忽略 `onKickedOutOfLive` 事件** — 未处理此事件时,被踢出的主播仍停留在「直播中」界面,用户体验极差,且推流资源无法释放。
80
+ 3. **重复调用 `createLive`** — 同一 `liveID` 已存在直播间时再次调用会返回 `-2108`;用唯一 ID 或先调 `endLive` 销毁后再创建。
81
+ 4. **在子线程更新 UI** — `createLive` / `endLive` 的回调应在主线程处理 UI 变更;若不确定回调线程,确保切换到主线程再更新 UI。
82
+
83
+ ## 排障指南
84
+
85
+ ### 常见错误码
86
+
87
+ | 错误码 | 描述 | 处理建议 |
88
+ |--------|------|----------|
89
+ | `-2105` | 直播间 ID 非法 | `liveID` 须为 ASCII 字符且长度 ≤ 48 字节 |
90
+ | `-2107` | 直播间名称非法 | `liveName` 须为合法 UTF-8 且长度 ≤ 30 字节 |
91
+ | `-2108` | 已在其他直播间 | 先调用 `endLive` / `leaveLive` 退出当前房间再重试 |
92
+ | `-2300` | 权限不足 | 操作需要房主权限(如 endLive 只有创建者可调用) |
93
+
94
+ ### 排障流程
95
+
96
+ ```
97
+ createLive 失败
98
+ ├── 错误码 -2105 → liveID 含非法字符或超长,修正后重试
99
+ ├── 错误码 -2107 → liveName 超 30 字节,截短后重试
100
+ ├── 错误码 -2108 → 已在房间,先 endLive 退出再创建
101
+ └── 其他错误 → 检查网络连接;抓取 error.message 上报
102
+
103
+ endLive 无响应 / 超时
104
+ ├── 是否已有网络连接?→ 检查网络后重试
105
+ ├── 是否在子线程调用了 UI 操作?→ 移至主线程
106
+ └── LiveCoreView 是否被提前释放?→ 确保在回调后才销毁视图
107
+
108
+ 主播被踢出后推流未停止
109
+ └── 检查是否订阅了 onKickedOutOfLive
110
+ └── 订阅后调用正确结束顺序释放资源
111
+
112
+ 观众收不到 onLiveEnded 通知
113
+ └── 检查主播是否调用了 endLive(而非直接 kill 进程)
114
+ └── 若 App 被强杀,服务端会在超时后自动触发房间销毁
115
+ ```
116
+
117
+ ## 关联知识
118
+
119
+ - **[live/anchor-room-config](live/anchor-room-config.md)** — createLive 所需的 LiveInfo 配置
120
+ - **[live/anchor-preview](live/anchor-preview.md)** — createLive 前的摄像头预览准备
121
+ - **[live/device-control](live/device-control.md)** — 设备开关与结束顺序
122
+ - **[live/error-codes](live/error-codes.md)** — 完整错误码参考
@@ -0,0 +1,90 @@
1
+ ---
2
+ id: live/anchor-preview
3
+ name: 主播预览
4
+ product: live
5
+ tags: [anchor, preview, LiveCoreView, pushView, camera]
6
+ platforms: [ios, android, web, flutter]
7
+ related: [live/device-control, live/anchor-room-config, live/beauty, live/audio]
8
+ ---
9
+
10
+ # 主播预览
11
+
12
+ ## 功能说明
13
+
14
+ 主播预览是开播前的关键准备步骤。`LiveCoreView` 是专为直播场景设计的轻量级视图组件,通过指定推流模式(pushView)将摄像头采集的本地画面渲染到屏幕上,让主播在正式开播前确认画面效果。
15
+
16
+ 预览阶段**不会**推流到观众端,仅在本地渲染画面,直到调用 `createLive` 后才开始向外推流。
17
+
18
+ ## 核心概念
19
+
20
+ | 概念 / 方法 | 说明 |
21
+ |------------|------|
22
+ | LiveCoreView(推流模式) | 创建主播推流视图;推流模式表示该视图用于采集和预览本地画面 |
23
+ | `setLiveID` | 将视图绑定到指定直播间 ID;**必须在开启摄像头之前调用** |
24
+ | DeviceStore `openLocalCamera` | 打开本地摄像头并将预览帧渲染到已绑定的 LiveCoreView;可指定前置/后置 |
25
+ | DeviceStore `openLocalMicrophone` | 打开本地麦克风,采集音频(预览阶段可选,开播前必须打开)|
26
+
27
+ ### 预览 vs 推流
28
+
29
+ ```
30
+ [预览阶段] LiveCoreView(推流模式) + setLiveID + openLocalCamera
31
+ ↓ 仅本地渲染,不推流
32
+ [开播阶段] LiveListStore.createLive(liveInfo) 之后
33
+ ↓ 本地画面开始向观众推流
34
+ ```
35
+
36
+ ## 最佳实践
37
+
38
+ ### ✅ ALWAYS
39
+
40
+ 1. **创建 LiveCoreView 后必须立即调用 `setLiveID`** — 视图内部通过 liveID 关联底层推流通道;若跳过此步骤,摄像头画面无法渲染(出现黑屏)。
41
+ 2. **先打开设备,再依赖预览** — 调用 `openLocalCamera` 的成功回调确认后,再进行 UI 更新(如移除加载遮罩)。
42
+ 3. **提前申请系统权限** — 进入预览页面前通过系统权限检查 API 确认摄像头/麦克风权限(各平台方式不同 → 见平台文件),避免在 `openLocalCamera` 回调中才发现权限被拒导致用户体验差。
43
+ 4. **将 LiveCoreView 正确加入视图层级** — 将 LiveCoreView 添加到视图层级后设置好布局,否则视图不可见。
44
+
45
+ ### ❌ NEVER
46
+
47
+ 1. **忘记调用 `setLiveID`** — 这是最常见的黑屏原因;`LiveCoreView` 没有 liveID 绑定时摄像头数据无处渲染。
48
+ 2. **预览阶段调用 `createLive`** — `createLive` 会立即向服务端创建房间并开始推流,应在用户确认开播后才调用,不可在预览配置页面调用。
49
+ 3. **在 `openLocalCamera` completion 之前就调用 `createLive`** — 设备未就绪时开播会导致推流无画面。
50
+ 4. **跳过设备关闭直接销毁 LiveCoreView** — 退出预览页面时须先关闭摄像头与麦克风,再移除视图,否则可能出现资源泄漏。
51
+
52
+ ## 排障指南
53
+
54
+ ### 常见错误码
55
+
56
+ | 错误码 | 描述 | 处理建议 |
57
+ |--------|------|----------|
58
+ | `-1101` | 摄像头缺少系统授权 | 引导用户在「设置 > 隐私 > 摄像头」中开启权限 |
59
+ | `-1105` | 麦克风缺少系统授权 | 引导用户在「设置 > 隐私 > 麦克风」中开启权限 |
60
+ | `-1100` | 打开摄像头失败 | 重启 App 重试;持续失败则上报错误日志 |
61
+ | `-1102` | 摄像头被其他进程占用 | 提示用户关闭 FaceTime / 系统相机等应用 |
62
+
63
+ ### 排障流程
64
+
65
+ ```
66
+ 预览黑屏
67
+ ├── setLiveID 是否已调用?
68
+ │ └─ 否 → 在将 LiveCoreView 添加到视图层级之后、openLocalCamera 之前调用 setLiveID
69
+ ├── openLocalCamera 是否成功(成功回调)?
70
+ │ ├─ 失败(-1101) → 摄像头权限被拒,引导用户去系统设置
71
+ │ ├─ 失败(-1102) → 摄像头被占用,提示关闭其他应用
72
+ │ └─ 失败(-1100) → 硬件失败,重试或上报
73
+ ├── LiveCoreView 是否已添加到视图层级并设置正确布局?
74
+ │ └─ 否 → 检查视图层级,确认视图可见
75
+ └── 模拟器/无摄像头设备?
76
+ └─ 是 → 部分平台模拟器不支持摄像头,切换真机测试
77
+
78
+ 预览有画面但没声音
79
+ ├── openLocalMicrophone 是否已调用?
80
+ ├── 麦克风权限是否已授予(-1105)?
81
+ └── 是否被其他音频应用占用(-1106)?
82
+ ```
83
+
84
+ ## 关联知识
85
+
86
+ - **[live/device-control](live/device-control.md)** — DeviceStore 设备管理完整 API
87
+ - **[live/anchor-room-config](live/anchor-room-config.md)** — 直播间配置(setLiveID 所需的 liveID 来源)
88
+ - **[live/anchor-lifecycle](live/anchor-lifecycle.md)** — 从预览到 createLive 开播的完整生命周期
89
+ - **[live/beauty](live/beauty.md)** — 预览阶段启用美颜效果
90
+ - **[live/audio](live/audio.md)** — 音频采集与配置