@tencent-rtc/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 (122) 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 -2
  6. package/resource/doc/chatuikit/faq/common/product.md +8 -0
  7. package/resource/doc/chatuikit/faq/flutter_sdk/faq.md +53 -0
  8. package/resource/doc/chatuikit/{iOS/client_api_iOS.md → faq/ios_sdk/client-api.md} +0 -2
  9. package/resource/doc/chatuikit/flutter/features/theme.md +379 -0
  10. package/resource/doc/chatuikit/flutter/integration.md +413 -0
  11. package/resource/doc/chatuikit/flutter/workflow.md +941 -0
  12. package/resource/doc/chatuikit/iOS/features/theme.md +416 -0
  13. package/resource/doc/chatuikit/react/components/chat-setting.md +86 -0
  14. package/resource/doc/chatuikit/react/components/contact-list.md +1093 -0
  15. package/resource/doc/chatuikit/react/components/search.md +745 -0
  16. package/resource/doc/chatuikit/vue/components/chat-setting.md +64 -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 -6
  20. package/resource/doc/livekit/live/ios/live-audience-list.md +339 -0
  21. package/resource/doc/livekit/live/ios/live-audio-effect.md +370 -0
  22. package/resource/doc/livekit/live/ios/live-barrage.md +517 -0
  23. package/resource/doc/livekit/live/ios/live-base-beauty.md +247 -0
  24. package/resource/doc/livekit/live/ios/live-co-guest-interaction.md +518 -0
  25. package/resource/doc/livekit/live/ios/live-gift.md +783 -0
  26. package/resource/doc/livekit/live/ios/live-host-interaction.md +815 -0
  27. package/resource/doc/livekit/live/ios/live-integration.md +931 -0
  28. package/resource/doc/livekit/live/ios/live-live-list.md +485 -0
  29. package/resource/doc/livekit/live/ios/workflow.md +454 -0
  30. package/resource/doc/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md +87 -0
  31. package/resource/doc/rtcengine/web/plugin/21-advanced-auto-play-policy.md +87 -0
  32. package/resource/doc/rtcengine/web/plugin/22-advanced-audio-mixer.md +175 -0
  33. package/resource/doc/rtcengine/web/plugin/23-advanced-support-detection.md +221 -0
  34. package/resource/doc/rtcengine/web/plugin/24-advanced-network-quality.md +140 -0
  35. package/resource/doc/rtcengine/web/plugin/25-advanced-device-change.md +99 -0
  36. package/resource/doc/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md +451 -0
  37. package/resource/doc/rtcengine/web/plugin/27-advanced-small-stream.md +151 -0
  38. package/resource/doc/rtcengine/web/plugin/28-advanced-beauty.md +322 -0
  39. package/resource/doc/rtcengine/web/plugin/29-advanced-water-mark.md +149 -0
  40. package/resource/doc/rtcengine/web/plugin/30-advanced-cross-room-link.md +96 -0
  41. package/resource/doc/rtcengine/web/plugin/31-advanced-plugins-overview.md +330 -0
  42. package/resource/doc/rtcengine/web/plugin/34-advanced-proxy.md +248 -0
  43. package/resource/doc/rtcengine/web/plugin/35-advanced-ai-denoiser.md +81 -0
  44. package/resource/doc/rtcengine/web/plugin/36-advanced-virtual-background.md +242 -0
  45. package/resource/doc/rtcengine/web/plugin/37-advanced-voice-changer.md +99 -0
  46. package/resource/doc/rtcengine/web/plugin/39-advanced-video-decoder.md +33 -0
  47. package/resource/doc/rtcengine/web/plugin/40-advanced-video-mixer.md +379 -0
  48. package/resource/doc/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md +91 -0
  49. package/resource/doc/rtcengine/web/plugin/42-advanced-realtime-transcriber.md +315 -0
  50. package/resource/doc/rtcengine/web/plugin/43-advanced-face-detection.md +180 -0
  51. package/resource/doc/tuicallkit/android/workflow.md +0 -0
  52. package/resource/doc/tuicallkit/flutter/workflow.md +331 -0
  53. package/tools/call/get-native-call-integration.js +27 -11
  54. package/tools/call/get-native-call-integration.js.map +1 -1
  55. package/tools/chat/get-native-chat-feature-detail.js +30 -0
  56. package/tools/chat/get-native-chat-feature-detail.js.map +1 -0
  57. package/tools/chat/get-native-chat-integration.js +30 -12
  58. package/tools/chat/get-native-chat-integration.js.map +1 -1
  59. package/tools/common/get-faq.js +2 -4
  60. package/tools/common/get-faq.js.map +1 -1
  61. package/tools/definitions/get_native_call_uikit_integration_def.js +17 -7
  62. package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
  63. package/tools/definitions/get_native_chat_feature_detail_def.js +32 -0
  64. package/tools/definitions/get_native_chat_feature_detail_def.js.map +1 -0
  65. package/tools/definitions/get_native_chat_uikit_integration_def.js +19 -7
  66. package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
  67. package/tools/definitions/{get_native_live_extra_features_def.js → get_native_live_uikit_extra_features_def.js} +3 -3
  68. package/tools/definitions/get_native_live_uikit_extra_features_def.js.map +1 -0
  69. package/tools/definitions/{get_native_live_interaction_def.js → get_native_live_uikit_interaction_def.js} +3 -3
  70. package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -0
  71. package/tools/definitions/get_web_chat_uikit_component_detail_def.js +49 -10
  72. package/tools/definitions/get_web_chat_uikit_component_detail_def.js.map +1 -1
  73. package/tools/index.js +6 -4
  74. package/tools/index.js.map +1 -1
  75. package/tools/live/{get_native_live_extra_features.js → get_native_live_uikit_extra_features.js} +4 -4
  76. package/tools/live/get_native_live_uikit_extra_features.js.map +1 -0
  77. package/tools/live/{get_native_live_interaction.js → get_native_live_uikit_interaction.js} +4 -4
  78. package/tools/live/get_native_live_uikit_interaction.js.map +1 -0
  79. package/tools/rtcengine/get-rtcengine-web-sdk-integration.js.map +1 -1
  80. package/tools/rtcengine/get-trtc-sdk-faq.js +32 -0
  81. package/tools/rtcengine/get-trtc-sdk-faq.js.map +1 -0
  82. package/tools/rtcengine/get-trtc-web-sdk-faq.js +1 -1
  83. package/tools/rtcengine/get-trtc-web-sdk-integration.js.map +1 -1
  84. package/tools/rtcengine/get-trtc-web-sdk-plugin.js +45 -0
  85. package/tools/rtcengine/get-trtc-web-sdk-plugin.js.map +1 -0
  86. package/utils/handle-component-name.js +0 -16
  87. package/utils/handle-component-name.js.map +1 -1
  88. package/utils/report-cls-client.js +1 -1
  89. package/utils/report-es-client.js +1 -1
  90. package/resource/doc/chatuikit/android/generate_UserSig.md +0 -306
  91. package/resource/doc/chatuikit/android/integrarte_only_tuichat_Android.md +0 -290
  92. package/resource/doc/chatuikit/android/quick_start_Android.md +0 -138
  93. package/resource/doc/chatuikit/android/show_typing_Android.md +0 -43
  94. package/resource/doc/chatuikit/flutter/generate_UserSig.md +0 -306
  95. package/resource/doc/chatuikit/flutter/integrate_tuikit_Flutter.md +0 -133
  96. package/resource/doc/chatuikit/iOS/generate_UserSig.md +0 -306
  97. package/resource/doc/chatuikit/iOS/integrate_only_tuichat_iOS.md +0 -748
  98. package/resource/doc/chatuikit/iOS/quick_start_iOS.md +0 -163
  99. package/resource/doc/chatuikit/iOS/show_typing_iOS.md +0 -52
  100. package/resource/doc/tuicallkit/flutter/how_to_run_flutter_callkit_demo.md +0 -101
  101. package/resource/doc/tuicallkit/iOS/how_to_run_iOS_callkit_demo.md +0 -98
  102. package/tools/definitions/get_native_live_extra_features_def.js.map +0 -1
  103. package/tools/definitions/get_native_live_interaction_def.js.map +0 -1
  104. package/tools/live/get_native_live_extra_features.js.map +0 -1
  105. package/tools/live/get_native_live_interaction.js.map +0 -1
  106. /package/resource/doc/chatuikit/android/{integrate_tuikit_Android.md → integration.md} +0 -0
  107. /package/resource/doc/chatuikit/{faq/native_sdk/faq.md → android/workflow.md} +0 -0
  108. /package/resource/doc/chatuikit/{flutter/client_api_Flutter.md → faq/flutter_sdk/client-api.md} +0 -0
  109. /package/resource/doc/chatuikit/iOS/{integrate_tuikit_iOS.md → integration.md} +0 -0
  110. /package/resource/doc/{tuicallkit/android/.gitkeep → chatuikit/iOS/workflow.md} +0 -0
  111. /package/resource/doc/chatuikit/react/components/{chatheader.md → chat-header.md} +0 -0
  112. /package/resource/doc/chatuikit/vue/components/{chatheader.md → chat-header.md} +0 -0
  113. /package/resource/doc/tuicallkit/android/{how_to_integrated_android_callkit.md → integration.md} +0 -0
  114. /package/resource/doc/tuicallkit/{android/api_TUICallObserver.md → faq/android_sdk/call-observer-api.md} +0 -0
  115. /package/resource/doc/tuicallkit/{android/api_TUICallKit.md → faq/android_sdk/callkit-api.md} +0 -0
  116. /package/resource/doc/tuicallkit/{flutter/api_TUICallDefine.md → faq/flutter_sdk/call-define-api.md} +0 -0
  117. /package/resource/doc/tuicallkit/{flutter/api_TUICallObserver.md → faq/flutter_sdk/call-observer-api.md} +0 -0
  118. /package/resource/doc/tuicallkit/{flutter/api_TUICallKit.md → faq/flutter_sdk/callkit-api.md} +0 -0
  119. /package/resource/doc/tuicallkit/{iOS/api_TUICallObserver.md → faq/ios_sdk/call-observer-api.md} +0 -0
  120. /package/resource/doc/tuicallkit/{iOS/api_TUICallKit.md → faq/ios_sdk/callkit-api.md} +0 -0
  121. /package/resource/doc/tuicallkit/flutter/{how_to_integrated_flutter_callkit.md → integration.md} +0 -0
  122. /package/resource/doc/tuicallkit/iOS/{how_to_integrated_iOS_callkit.md → integration.md} +0 -0
@@ -0,0 +1,454 @@
1
+ # Native Live AtomicXCore Code Generation Workflow Instructions (iOS)
2
+
3
+ ## 🚨 Core Principles (Highest Priority)
4
+
5
+ **The Agent MUST ensure that the generated code compiles and runs successfully. Delivering uncompilable code to the user is strictly prohibited!**
6
+
7
+ ### ⚠️ Mandatory Compilation Verification (Must be executed, cannot be omitted)
8
+
9
+ **🚫 Prohibited Actions**:
10
+ - ❌ DO NOT assume code is correct based only on `read_lints` checks.
11
+ - ❌ DO NOT use `grep` to filter compilation output (this will cause commands to be skipped).
12
+ - ❌ DO NOT deliver code without compilation verification.
13
+
14
+ **✅ The Only Correct Way to Verify**:
15
+
16
+ ```bash
17
+ # Step 1: Install dependencies (if needed)
18
+ cd <ProjectDir> && pod install
19
+
20
+ # Step 2: Compile verification (use tail to limit output)
21
+ cd <ProjectDir> && xcodebuild build \
22
+ -scheme <SchemeName> \
23
+ -workspace <WorkspaceName>.xcworkspace \
24
+ -destination 'generic/platform=iOS' \
25
+ CODE_SIGNING_ALLOWED=NO 2>&1 | tail -150
26
+ ```
27
+
28
+ **Judging Criteria**:
29
+ - ✅ Output contains `BUILD SUCCEEDED` → Compilation passed, ready for delivery.
30
+ - ❌ Output contains `BUILD FAILED` or `error:` → Must fix and recompile.
31
+
32
+ **Common Errors & Fixes**:
33
+ | Error Keyword | Reason | Fix |
34
+ |---------------|--------|-----|
35
+ | `No such module 'xxx'` | Missing Pod dependency | Add to Podfile and run `pod install`. |
36
+ | `Cannot find 'xxx' in scope` | Missing import | Add `import xxx`. |
37
+ | `Use of unresolved identifier` | Incorrect API name | Consult documentation for correct API. |
38
+ | `NSCameraUsageDescription` | Missing Info.plist permission | Add permission description. |
39
+
40
+ **Verification Loop (Must Follow)**:
41
+ ```
42
+ Execute Compilation → Failure → Analyze Error → Fix Code → Re-execute Compilation → ... → BUILD SUCCEEDED → Deliver
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 📋 Instruction Purpose & Architecture
48
+
49
+ Provides the Agent with a **code generation blueprint** for implementing core features of Native (iOS) Live AtomicXCore.
50
+
51
+ **Core Architecture**:
52
+ * **Container**: `LiveCoreView` (View layer)
53
+ * **State**: `Store` (Data-driven)
54
+ * **Events**: `Publisher` (Combine subscription)
55
+
56
+ **Feature Dependency Logic (Important)**:
57
+ 1. **Base First**: Basic live streaming (Broadcasting/Viewing/List) must be completed first using the base tool (`get_native_live_uikit_integration`).
58
+ 2. **Interaction Overlay**: If requirements include "Co-guesting", "PK", or "Audience List", the interaction tool (`get_native_live_uikit_interaction`) must be called **after** basic features are completed.
59
+ 3. **Empty Project Handling**: If the user requests interaction features in an empty project, the Agent **MUST implement basic features first**, then add interaction capabilities.
60
+
61
+ ---
62
+
63
+ ## ⚙️ Automated Workflow Steps (Must be created as TODO tasks)
64
+
65
+ **🚨 The Agent MUST create the following steps as a TODO task list, complete them one by one, and check them off:**
66
+
67
+ ### Step 1: Preparation
68
+ 1. **Generate Credentials**: Call the `get_usersig` tool to generate test credentials.
69
+ * Host: `anchor001`, `anchor002`, `anchor003`
70
+ * Audience: `user001`, `user002`, `user003`
71
+ 2. **Environment Check**: Check `Podfile` and add the following dependency if missing:
72
+ ```ruby
73
+ pod 'AtomicXCore'
74
+ ```
75
+ 3. **Permission Injection**: Add Camera and Microphone permission descriptions in `Info.plist`:
76
+ ```xml
77
+ <key>NSCameraUsageDescription</key>
78
+ <string>Needs camera access to record video.</string>
79
+ <key>NSMicrophoneUsageDescription</key>
80
+ <string>Needs microphone access to record audio.</string>
81
+ ```
82
+
83
+ ### Step 2: Code Generation
84
+ **PRIORITIZE and EXCLUSIVELY** use the **real-time documentation content** returned by this tool for code generation.
85
+ * **Host Only**: Generate `AnchorViewController`.
86
+ * **Audience Only**: Generate `AudienceViewController`.
87
+ * **Host + Audience**: Generate `MainViewController` (Entry selection) + `AnchorViewController` + `AudienceViewController`.
88
+
89
+ ### Step 3: 🚨 Compilation Verification (Mandatory, cannot be skipped)
90
+ **This step MUST be executed as a standalone TODO task, cannot be omitted or merged!**
91
+
92
+ **Execution Command**:
93
+ ```bash
94
+ cd <ProjectDir>/ios && pod install && \
95
+ xcodebuild build -scheme <SchemeName> -workspace <WorkspaceName>.xcworkspace \
96
+ -destination 'platform=iOS Simulator,name=iPhone 16' \
97
+ CODE_SIGNING_ALLOWED=NO 2>&1 | tail -150
98
+ ```
99
+
100
+ **Judgment & Handling**:
101
+ * Output contains **BUILD SUCCEEDED** → Proceed to Step 4.
102
+ * Output contains **BUILD FAILED** or **error:** → Analyze error → Fix code → **Re-execute this command**, loop until success.
103
+
104
+ ### Step 4: Deliver Results
105
+ Deliver the code after confirming compilation passes.
106
+
107
+ ---
108
+
109
+ ## 🚫 Code Generation Constraints (Strictly Follow)
110
+
111
+ ### 1. General Code Constraints
112
+ * **Strictly Prohibited to Modify Imports**: Import paths in the documentation are verified; DO NOT modify them.
113
+ * **Strictly Prohibited to Fabricate APIs**: If an API is not in the documentation, DO NOT invent method or parameter names.
114
+ * **MUST Consult API Docs**: For data model fields (e.g., `LiveInfo`), visit the documentation to confirm field names (e.g., confirm it's `liveOwner.userName` and not `name`).
115
+
116
+ ### 2. 🧩 Store & Publisher Management Constraints (Lifecycle Safety)
117
+ **Core Reason**: SDK uses Combine's `Publisher` for state subscription. Incorrect lifecycle management leads to listener failure or memory leaks.
118
+
119
+ * **Subscription Management Principle**: All `AnyCancellable` **MUST be declared as member variables** of the ViewController in `cancellableSet`.
120
+ * **No Ignoring Return Values**: Prohibited to not store the `AnyCancellable` returned by `.sink {}`.
121
+ * **Pairing Principle**: Setup subscriptions in `viewDidLoad`; they will be automatically released when the `cancellableSet` is deinitialized.
122
+
123
+ ### 3. ⏱️ Timeout Limits (Critical)
124
+ **Strictly adhere to the following parameter limits, prioritizing values from documentation examples:**
125
+
126
+ #### A. Co-guesting (`CoGuestStore`)
127
+ * **Rules**:
128
+ * Optional parameter; if not filled, timeout is not checked.
129
+ * If filled, the range MUST be between **5 - 1800 seconds**.
130
+ * **Correct Examples**:
131
+ ```swift
132
+ // ✅ Recommended: Follow doc examples (e.g., 30s)
133
+ CoGuestStore.shared.applyForSeat(seatIndex: -1, timeout: 30) { ... }
134
+ // ✅ Valid: No timeout check
135
+ CoGuestStore.shared.applyForSeat(seatIndex: -1, timeout: 0) { ... }
136
+ ```
137
+ * **Incorrect Examples**: ❌ `timeout: 3` (too short), ❌ `timeout: 2000` (too long).
138
+
139
+ #### B. Co-hosting/PK (`CoHostStore`)
140
+ * **Rules**:
141
+ * **Maximum 30 seconds** (Hard limit).
142
+ * **Correct Examples**:
143
+ ```swift
144
+ // ✅ Recommended: Use maximum value
145
+ CoHostStore.shared.requestHostConnection(..., timeout: 30) { ... }
146
+ ```
147
+ * **Incorrect Examples**: ❌ `timeout: 60` (will cause request failure).
148
+
149
+ ### 4. 🎨 Extra Feature Constraints (Beauty/Audio/UI)
150
+
151
+ #### A. Audio Effects
152
+ * **Voice Changer Enum (`AudioChangerType`)**:
153
+ * ✅ **Allowed**: `.child, .littleGirl, .man, .ethereal`, etc.
154
+ * ❌ **Prohibited**: `.uncle, .loli, .girl, .boy` (deprecated or incorrect).
155
+ * **Reverb Enum (`AudioReverbType`)**:
156
+ * ✅ **Allowed**: `.ktv, .smallRoom, .metallic`, etc.
157
+ * ❌ **Prohibited**: `.room, .hall, .low`.
158
+
159
+ #### B. Beauty
160
+ * **Parameter Range**: **0.0 - 9.0** (Float).
161
+ * ❌ NOT 0-1 (Float), and NOT 0-100 (Int).
162
+ * **UI Mapping Formula**: `sliderValue / 100.0 * 9.0`.
163
+
164
+ #### C. Barrage, Gift & Layout (Barrage, Gift & UI)
165
+ * **Layering Requirements**: Barrage list and full-screen gift animations MUST overlay **on top** of the video layer `LiveCoreView` using a `UIView`.
166
+ * **Split Screen Prohibited**: Strictly prohibited to split the screen (e.g., video on top, barrage at bottom); MUST use overlay mode.
167
+
168
+ ##### Barrage Input
169
+ * **Position**: Fixed at the bottom left of the screen, in the same row as function buttons (Gift, Co-guest, etc.).
170
+ * **Style**: Semi-transparent rounded background + placeholder text "Say something...".
171
+ * **Keyboard Adaptation**:
172
+ * When the keyboard is raised, the input box **must remain in its original position** and is prohibited from moving up with the keyboard.
173
+ * The `LiveCoreView` constraint must be fixed to `edges.equalToSuperview()`, prohibiting distortion or upward shifting.
174
+ * **Strictly Prohibited** to use `UIScrollView.contentInsetAdjustmentBehavior` or automatic constraint adjustments.
175
+
176
+ ##### Barrage Display Flow
177
+ ```
178
+ Sending Barrage:
179
+ User input → Click Send/Enter → BarrageStore.sendTextMessage(text) → Insert into local barrage list immediately
180
+
181
+ Receiving Barrage:
182
+ Subscribe to BarrageStore.barrageState.$barrageList → New message received → Insert into barrage list → Scroll to bottom
183
+ ```
184
+ * **Data Source**: Subscribe to `BarrageStore.shared.barrageState.$barrageList`.
185
+ * **Local Echo**: Insert into the local barrage list **immediately** after successful sending, without waiting for server callback.
186
+ * **Scrolling Behavior**: Automatically scroll to the bottom when a new message arrives (`scrollToRow(at: lastIndex, animated: true)`).
187
+ * **Message Format**: `[Nickname]: [Message Content]`, nickname uses theme color, content uses white.
188
+
189
+ * **Gift Barrage**: **If the user needs gift barrage integration**, when `onReceiveGift` is triggered, a gift message MUST be inserted into the barrage list on **both host and audience sides**. DO NOT display only on the audience side.
190
+
191
+ ##### Full-screen Gift Animation
192
+ **⚠️ MANDATORY**: Full-screen gift animation is a **mandatory requirement** when integrating gift features and cannot be omitted.
193
+
194
+ * **Layering**: The full-screen gift animation view MUST overlay **on top** of the `LiveCoreView` using a separate `UIView` container.
195
+ * **Layout**: Constrained to `edges.equalToSuperview()`, covering the entire screen.
196
+ * **Dual-side Sync**: Upon receiving the `.onReceiveGift` event, the full-screen animation MUST be played on **both host and audience sides**. Playing only on the audience side is strictly prohibited.
197
+
198
+ ##### ⚠️ SVGA Animation Playback (Mandatory use of SVGAPlayer, Strictly Prohibited to use UIImageView)
199
+ **Strictly Prohibited to use UIImageView/Kingfisher to load .svga files**. SVGA is a vector animation format, not a normal image; UIImageView cannot play it.
200
+
201
+ * **Dependency Configuration** (Podfile):
202
+ ```ruby
203
+ pod 'SVGAPlayer'
204
+ ```
205
+
206
+ * **Core Playback Logic (MUST use SVGAParser + SVGAPlayer)**:
207
+ ```swift
208
+ import SVGAPlayer
209
+
210
+ // ❌ Incorrect: Using UIImageView to load SVGA (cannot play animation)
211
+ // imageView.kf.setImage(with: URL(string: gift.resourceURL))
212
+
213
+ // ✅ Correct: Using SVGAParser to parse + SVGAPlayer to play
214
+ svgaParser.parse(with: url) { [weak self] videoItem in
215
+ guard let videoItem = videoItem else { return }
216
+ self?.svgaPlayer.videoItem = videoItem
217
+ self?.svgaPlayer.startAnimation() // Start playing animation
218
+ }
219
+ ```
220
+
221
+ * **Full Implementation Example (Within ViewController)**:
222
+ ```swift
223
+ import UIKit
224
+ import AtomicXCore
225
+ import Combine
226
+ import SVGAPlayer
227
+
228
+ class LiveRoomViewController: UIViewController, SVGAPlayerDelegate {
229
+ private var cancellables = Set<AnyCancellable>()
230
+
231
+ // SVGA Player Components
232
+ private let svgaPlayer = SVGAPlayer()
233
+ private let svgaParser = SVGAParser()
234
+
235
+ override func viewDidLoad() {
236
+ super.viewDidLoad()
237
+ setupSVGAPlayer()
238
+ subscribeGiftEvents()
239
+ }
240
+
241
+ // 1. Initialize SVGAPlayer
242
+ private func setupSVGAPlayer() {
243
+ svgaPlayer.delegate = self
244
+ svgaPlayer.loops = 1 // Play once
245
+ svgaPlayer.clearsAfterStop = true // Clear automatically after stopping
246
+ svgaPlayer.frame = view.bounds // Full screen
247
+ svgaPlayer.isHidden = true
248
+ view.addSubview(svgaPlayer)
249
+ // Ensure svgaPlayer is at the top level
250
+ view.bringSubviewToFront(svgaPlayer)
251
+ }
252
+
253
+ // 2. Subscribe to Gift Events
254
+ private func subscribeGiftEvents() {
255
+ let giftStore = GiftStore.create(liveID: liveId)
256
+ giftStore.giftEventPublisher
257
+ .receive(on: DispatchQueue.main)
258
+ .sink { [weak self] event in
259
+ guard case .onReceiveGift(_, let gift, let count, let sender) = event else { return }
260
+
261
+ // Play full-screen gift animation
262
+ if !gift.resourceURL.isEmpty, let url = URL(string: gift.resourceURL) {
263
+ self?.playGiftAnimation(from: url)
264
+ }
265
+
266
+ // (Optional) Insert gift message into barrage list
267
+ // let tipText = "\(sender.userName) sent \(gift.name) x \(count)"
268
+ // barrageStore.appendLocalTip(message: tipText)
269
+ }
270
+ .store(in: &cancellables)
271
+ }
272
+
273
+ // 3. Use SVGAParser to parse and play animation
274
+ private func playGiftAnimation(from url: URL) {
275
+ svgaParser.parse(with: url, completionBlock: { [weak self] videoItem in
276
+ guard let self = self, let videoItem = videoItem else { return }
277
+ DispatchQueue.main.async {
278
+ self.svgaPlayer.videoItem = videoItem
279
+ self.svgaPlayer.isHidden = false
280
+ self.svgaPlayer.startAnimation()
281
+ }
282
+ }, failureBlock: { error in
283
+ print("SVGA Parse Failed: \(error?.localizedDescription ?? "")")
284
+ })
285
+ }
286
+
287
+ // 4. SVGAPlayerDelegate - Playback Finished Callback
288
+ func svgaPlayerDidFinishedAnimation(_ player: SVGAPlayer!) {
289
+ svgaPlayer.isHidden = true
290
+ }
291
+ }
292
+ ```
293
+
294
+ * **Key Checkpoints**:
295
+ 1. ✅ Import `import SVGAPlayer`
296
+ 2. ✅ Use `SVGAParser().parse(with: url)` to parse animation URL
297
+ 3. ✅ Use `SVGAPlayer().startAnimation()` to play animation
298
+ 4. ✅ Implement `SVGAPlayerDelegate` to handle playback end
299
+ 5. ❌ PROHIBITED to use `UIImageView`/`Kingfisher`/`SDWebImage` to load .svga files
300
+
301
+ ### 🎨 Default UI/UX Design & Interaction Specifications (Only applies if user doesn't specify)
302
+
303
+ **⚠️ Note: The following specifications are only executed as default standards when the user does not provide specific UI design or requirements.**
304
+
305
+ ### 1. Global Aesthetics
306
+ * **Immersive Dark**: The background of the live page must be `.black`, and the video layer (`LiveCoreView`) must **fill the entire screen** (`edges.equalToSuperview()`) and be at the bottom layer.
307
+ * **Safe Area**: All floating UIs must be constrained within the `safeAreaLayoutGuide`, strictly prohibiting being blocked by notches or the bottom Home bar.
308
+ * **Text Readability**: White text above the video (e.g., barrage, ID) must have a **black shadow** (`shadowColor = .black, offset = 0x1`).
309
+ * **Error Prompts**: Use **Toast** uniformly; prohibit the use of modal Alerts that interrupt the user.
310
+
311
+ ### 2. Component Standards
312
+ * **Glass Capsule (Top)**:
313
+ * **Style**: **Frosted glass background** (`UIBlurEffect.dark`) + **full rounded corners**.
314
+ * **Application**: Only used at the top left to display "Host Avatar + ID + Popularity".
315
+ * **Flat Buttons**:
316
+ * **Style**: **"Text + Rounded Rectangle Background"**. Minimalist flat design, background color is semi-transparent black or theme color.
317
+ * **Close Button**: Special case, use a circular frosted glass icon.
318
+ * **Floating Panels**:
319
+ * **Style**: Only top rounded corners (`maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]`).
320
+ * **Taboo**: Solid color backgrounds at the bottom are prohibited; floating feeling must be maintained.
321
+
322
+ ### 3. Live Room Layout Blueprint
323
+ **⚠️ Dynamic Layout Principle: Only render function buttons that the user has actually integrated. If a user did not request a feature (e.g., PK/Beauty), DO NOT add corresponding empty buttons.**
324
+
325
+ #### A. Top Bar
326
+ * **Left [Room Info]**: Wrapped in a **frosted capsule** [Host Avatar | Host Nickname].
327
+ * **Right [Control Area]**: Horizontally arranged [Online Audience Count] + [Close Icon (X)].
328
+
329
+ #### B. Bottom Bar - Dynamically switches based on state
330
+ * **Preview Mode**:
331
+ * Content **aligned to the right**: [Beauty] [Audio Effects] [Start Live (Main Button)].
332
+ * **Anchor Live Mode**:
333
+ * **Left**: [Barrage List (Transparent Background)] + [Chat Input Box].
334
+ * **Right**: Function array [Beauty] [Audio Effects] [Co-hosting] [PK].
335
+ * **Audience Live Mode**:
336
+ * **Left**: [Barrage List] + [Chat Input Box].
337
+ * **Right**: [Gift] [Apply for Co-guesting].
338
+
339
+ ### 4. Home Layout & Interaction
340
+
341
+ #### A. Home Reference Layout
342
+ ```
343
+ ┌─────────────────────────────┐
344
+ │ AtomicXCore Live │
345
+ │ │
346
+ │ Live Room ID │
347
+ │ ┌─────────────────────────┐│
348
+ │ │ live_000001 ││ ← Input Box (with left padding, semi-transparent background)
349
+ │ └─────────────────────────┘│
350
+ │ │
351
+ │ Host Broadcasting │
352
+ │ (Click to login as anchor001)│
353
+ │ │
354
+ │ Audience Viewing │
355
+ │ (Click to login as user001) │
356
+ │ │
357
+ │ [ 📋 Live List ] │
358
+ └─────────────────────────────┘
359
+ ```
360
+
361
+ #### B. Implicit Login Flow
362
+ **No separate login button is required on the home page**; login is automatically completed when a function button is clicked:
363
+ * Click "Host Broadcasting" → Login using `anchor001` → Jump to host page.
364
+ * Click "Audience Viewing" → Login using `user001` → Jump to audience page.
365
+ * Click "Live List" → Login using `user001` → Jump to list page.
366
+
367
+ ---
368
+
369
+ ## 🎯 Implementation Details
370
+
371
+ ### 1. Host Broadcasting (`host_streaming`)
372
+ * **Core**: `LiveCoreView(viewType: .pushView)`
373
+ * **Flow**: `LiveListStore.shared.createLive()`
374
+ * **Cleanup**: `deinit` or when exiting the page, `endLive()` MUST be called.
375
+
376
+ ### 2. Audience Viewing (`audience_streaming`)
377
+ * **Core**: `LiveCoreView(viewType: .playView)`
378
+ * **Flow**: `LiveListStore.shared.joinLive()`
379
+ * **Cleanup**: `deinit` or when exiting the page, `leaveLive()` MUST be called.
380
+
381
+ ### 3. Live List (`live_list`)
382
+ * **Core**: `LiveListStore.shared.fetchLiveList()` + `UITableView/UICollectionView`
383
+ * **Data**: Subscribe to `liveState.liveList`.
384
+ * **Navigation**: Clicking a list item navigates to the audience page, passing the `liveID`.
385
+
386
+ ### 4. Co-guest & Co-host Interaction Specifications (`co_guest` & `co_host`)
387
+
388
+ #### A. Audience Co-guesting (Host passively receives)
389
+ * **Host UI**: ❌ **Strictly prohibited** to display a "Co-guest Application" list button in the bottom toolbar or anywhere else.
390
+ * **Interaction Logic**: Upon receiving a co-guest application callback, pop up a dialog (`UIAlertController`) directly in the center of the screen:
391
+ * **Title**: Co-guest Application
392
+ * **Content**: Received a co-guest application from audience [Nickname], accept?
393
+ * **Operations**: [Decline] [Accept]
394
+
395
+ #### B. Host Co-hosting Panel (Pops up when clicking bottom [Co-host] button)
396
+ * **Presentation**: Use a bottom floating panel (`UIView` animated up); prohibit `UIAlertController`.
397
+ * **UI Layout (Strictly follow illustration)**:
398
+ ```
399
+ ┌─────────────────────────────────────┐
400
+ │ │
401
+ │ Initiate Connection [🚪 End Co-host] │ ← Red text
402
+ │ │
403
+ │ Connected (2 persons) │
404
+ │ ┌─────────────────────────────────┐│
405
+ │ │ [👤] Li Ziming [💎20] PK... ││ ← Connected users
406
+ │ │ [👤] Filinna [💎32] PK... ││
407
+ │ └─────────────────────────────────┘│
408
+ ├─────────────────────────────────────┤
409
+ │ Other Live Users │
410
+ │ ┌─────────────────────────────────┐│
411
+ │ │ [👤] Li Ziming [💎20] [Cancel Inv] ││ ← Gray-black background button
412
+ │ │ [👤] Filinna [💎32] [Invite] ││ ← Blue background button
413
+ │ │ [👤] Tie Zhu [💗99] [Invite] ││
414
+ │ └─────────────────────────────────┘│
415
+ └─────────────────────────────────────┘
416
+ ```
417
+
418
+ #### C. PK Button Interaction Constraints
419
+ * **Pre-check**: When clicking the bottom [PK] button, current connection status must be checked (`CoHostStore.shared.connectedUsers.isEmpty`).
420
+ * **Status Handling**:
421
+ * **Not connected**: ❌ Prohibit jump, show Toast: `"Please initiate co-hosting first"`.
422
+ * **Connected**: ✅ Pop up PK invitation panel.
423
+
424
+ ---
425
+
426
+ ## 📋 Agent Final Checklist
427
+
428
+ ### 🚨 Must-do Items (None can be omitted)
429
+ - [ ] **🔴 Compilation Verification**: Executed the following command and output contains **BUILD SUCCEEDED** (This item must be explicitly listed in the TODO task)
430
+ ```bash
431
+ xcodebuild build -scheme <ProjectName> -workspace <ProjectName>.xcworkspace -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO 2>&1 | grep -E "(error:|warning:.*\.swift|BUILD SUCCEEDED|BUILD FAILED)" | head -30
432
+ ```
433
+ - [ ] **Credential Injection**: Called `get_usersig` to generate test credentials.
434
+ - [ ] **Dependencies Complete**: Checked `Podfile` and Info.plist permissions.
435
+
436
+ ### Code Quality Check
437
+ - [ ] **API Accuracy**: Imports not modified, APIs not fabricated, `LiveInfo` field names verified.
438
+ - [ ] **Timeout Compliance**: Co-guesting 5-1800s, Co-hosting ≤30s.
439
+ - [ ] **Extra Feature Compliance**: Audio enums correct, beauty range 0-9, barrage layout overlays, and keyboard adaptation.
440
+ - [ ] **Gift Compliance**: Full-screen gift animations implemented on both host and audience sides.
441
+
442
+ ---
443
+
444
+ ## 🚨 Security Reminder (Code Comment Template)
445
+
446
+ ```swift
447
+ /**
448
+ * ⚠️ Test Credential Warning
449
+ * - Current userSig is automatically generated by development tools and is valid for 7 days.
450
+ * - ❌ PROHIBITED from generating userSig on the client side in production.
451
+ * - ✅ userSig MUST be generated on a backend service before official launch.
452
+ * - Reference: https://trtc.io/document/35166?product=live&menulabel=uikit&platform=ios
453
+ */
454
+ ```
@@ -0,0 +1,87 @@
1
+
2
+ ## Function Description
3
+ This article mainly introduces the advanced usage of custom capture and custom rendering.
4
+
5
+ ## Custom Capture
6
+
7
+ By default, {@link TRTC#startLocalVideo startLocalVideo()} and {@link TRTC#startLocalAudio startLocalAudio()} will start camera and microphone, {@link TRTC#startScreenShare trtc.startScreenShare()} will start screen sharing.
8
+
9
+ If you need to customize the capture:
10
+
11
+ - `trtc.startLocalAudio({ option: { audioTrack }})`
12
+ - After passing this parameter, the SDK will not capture the microphone and use the custom audioTrack to publish the stream.
13
+ - If microphoneId and audioTrack are set at the same time, the capture priority is microphoneId > audioTrack, but it is not recommended to mix them.
14
+ - `trtc.startLocalVideo({ option: { videoTrack }})`
15
+ - After passing this parameter, the SDK will not capture the camera, the custom captured videoTrack will be published as main stream.
16
+ - If you set cameraId, useFrontCamera, videoTrack at the same time, the capture priority is cameraId > useFrontCamera > videoTrack, but it is not recommended to mix them.
17
+ - `trtc.startScreenShare({ option: { videoTrack }})`
18
+ - After passing this parameter, the SDK will not capture screen share, the custom captured videoTrack will be published as sub stream.
19
+
20
+ There are usually several ways to obtain audioTrack and videoTrack:
21
+
22
+ - Use [getUserMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) to capture the camera and microphone.
23
+ - Use [getDisplayMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) to capture screen sharing.
24
+ - Use [videoElement.captureStream](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/captureStream) to capture the audio and video being played in the video tag.
25
+ - Use [canvas.captureStream](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/captureStream) to capture the animation in the canvas.
26
+
27
+ ### Capture the video being played in the video tag
28
+
29
+ ```javascript
30
+ // Check if your current browser supports capturing streams from video elements
31
+ if (!HTMLVideoElement.prototype.captureStream) {
32
+ console.log('your browser does not support capturing stream from video element');
33
+ return
34
+ }
35
+ // Get the video tag that is playing video on your page
36
+ const video = document.getElementByID('your-video-element-ID');
37
+ // Capture the video stream from the playing video
38
+ const stream = video.captureStream();
39
+ const audioTrack = stream.getAudioTracks()[0];
40
+ const videoTrack = stream.getVideoTracks()[0];
41
+
42
+ trtc.startLocalVideo({ option:{ videoTrack } });
43
+ trtc.startLocalAudio({ option:{ audioTrack } });
44
+ ```
45
+
46
+ ### Capture the animation in the canvas
47
+
48
+ ```javascript
49
+ // Check if your current browser supports capturing streams from canvas elements
50
+ if (!HTMLCanvasElement.prototype.captureStream) {
51
+ console.log('your browser does not support capturing stream from canvas element');
52
+ return
53
+ }
54
+ // Get your canvas tag
55
+ const canvas = document.getElementByID('your-canvas-element-ID');
56
+
57
+ // Capture a 15 fps video stream from the canvas
58
+ const fps = 15;
59
+ const stream = canvas.captureStream(fps);
60
+ const videoTrack = stream.getVideoTracks()[0];
61
+
62
+ trtc.startLocalVideo({ option:{ videoTrack } });
63
+ ```
64
+
65
+
66
+ ## Custom Rendering
67
+
68
+ By default, when calling {@link TRTC#startLocalVideo startLocalVideo()} or {@link TRTC#startRemoteVideo startRemoteVideo()}, you need to pass in the view parameter. The SDK will create a `video` tag under the specified element tag to play the video.
69
+
70
+ If you need to customize the rendering, and do not need the SDK to play the video, you can refer to the following steps:
71
+
72
+ - Do not fill in the view parameter or pass in null when calling the startLocalVideo or startRemoteVideo method.
73
+ - Listen the TRTC.EVENT.TRACK, SDK will fires this event when there has a new MediaStreamTrack, then you can get the MediaStreamTrack for custom rendering.
74
+ - Use your own player for video rendering.
75
+ - If you using the custom rendering, the {@link module:EVENT.VIDEO_PLAY_STATE_CHANGED VIDEO_PLAY_STATE_CHANGED} event will not be fired. You need to listen to the `mute/unmute/ended` events of the video track [MediaStreamTrack](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack) to determine the status of the current video data stream.
76
+ - For remote video, you also need to listen to the {@link module:EVENT.REMOTE_VIDEO_AVAILABLE REMOTE_VIDEO_AVAILABLE} and {@link module:EVENT.REMOTE_VIDEO_UNAVAILABLE REMOTE_VIDEO_UNAVAILABLE} events to handle the lifecycle of remote video.
77
+
78
+ ### Custom rendering by TRTC.EVENT.TRACK
79
+
80
+ ```javascript
81
+ trtc.on(TRTC.EVENT.TRACK, event => {
82
+ const isLocal = event.userId === ''; // userId === '' means event.track is a local track, otherwise it's a remote track
83
+ const isSubStream = event.streamType === TRTC.TYPE.STREAM_TYPE_SUB; // Usually the sub stream is a screen-sharing video stream.
84
+ const mediaStreamTrack = event.track;
85
+ const kind = event.track.kind; // audio or video
86
+ })
87
+ ```
@@ -0,0 +1,87 @@
1
+ ## Introduction
2
+
3
+ In order to prevent web pages from automatically playing audio and video and causing interference to users, browsers have restricted the automatic playback function of audio and video: **before the user interacts with the web page (such as clicking, touching the page, etc.), the web page will be prohibited from playing media with sound. In iOS 10+, if low power mode is enabled, media without sound will also be prohibited from playing.**
4
+
5
+ Affected by the above browser autoplay policy, when using the TRTC Web SDK, there may be problems with playing silently. The most common scenario is: in your product design, support users to automatically enter the room and pull the stream for playback without the need for users to click after refreshing the page.
6
+
7
+ This article mainly introduces **how to solve the problem of playback failure caused by the restriction of autoplay policy**.
8
+
9
+ ## Solution 1: Use the SDK's autoplay popup window
10
+
11
+ By default, when autoplay fails, the SDK will pop up to guide the user to interact with the page. After the interaction occurs, the SDK will actively call the interface to resume playback.
12
+
13
+ - Advantages: The business side does not need to do anything, simple and efficient.
14
+
15
+ - Disadvantages: The popup window provided by the SDK may not meet the design requirements of the business product. At this time, you can consider using Solution 2.
16
+
17
+ The popup window provided by the SDK is adapted to desktop and mobile browser, and the style is as follows:
18
+
19
+ <div style="display:flex;align-items:center;">
20
+ <img src="./assets/autoplay-dialog-pc-en.png" style="width:40%;max-width:450px;margin-right:16px;" />
21
+ <img src="./assets/autoplay-dialog-en.png" style="width:30%;max-width:300px;" />
22
+ </div>
23
+
24
+
25
+ - The SDK will switch the Chinese and English popup prompts according to the value of [navigator.language](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language).
26
+
27
+ - When the user clicks "OK", the SDK automatically calls the relevant interface to resume playback.
28
+
29
+ - In order to ensure that the popup window is displayed on the top layer as much as possible, its z-index value is 1500.
30
+
31
+ ## Solution 2: Custom handling of autoplay restrictions
32
+
33
+ If you want to have complete control over the user experience when autoplay fails, you can follow these steps:
34
+
35
+ ### Step 1: Disable SDK default popup
36
+
37
+ Set the `enableAutoPlayDialog` parameter to `false` when calling the [TRTC.enterRoom](./TRTC.html#enterRoom) interface:
38
+
39
+ ```javascript
40
+ await trtc.enterRoom({
41
+ // ... other parameters
42
+ enableAutoPlayDialog: false
43
+ });
44
+ ```
45
+
46
+ ### Step 2: Listen for autoplay failure events (Required)
47
+
48
+ Listen to the [AUTOPLAY_FAILED](./module-EVENT.html#.AUTOPLAY_FAILED) event to handle autoplay failures. The SDK will automatically monitor user click events and resume playback after the user clicks.
49
+
50
+ ```javascript
51
+ trtc.on(TRTC.EVENT.AUTOPLAY_FAILED, event => {
52
+ // Add your custom handling logic here
53
+ // For example: display a custom prompt to guide users to click on the page
54
+ });
55
+ ```
56
+
57
+ ### Step 3: Actively resume playback (Optional)
58
+
59
+ > Supported from version 5.9.0
60
+
61
+ In some special scenarios (such as in iframes or when using specific frontend frameworks), you may need to actively call the resume playback method. In this case, you can use the `resume` method provided in the event:
62
+
63
+ ```javascript
64
+ trtc.on(TRTC.EVENT.AUTOPLAY_FAILED, (event) => {
65
+ showCustomDialog(event);
66
+ });
67
+ function showCustomDialog(event) {
68
+ const { userId, resume } = event;
69
+ // The restricted user id is userId, resume is the function to resume playback for this user
70
+ // Need to display a custom button, prompt that userId playback is restricted, and call 'resume()' in the button click callback
71
+ }
72
+ ```
73
+
74
+ ### Important Notes
75
+
76
+ 1. Some browsers may check user interaction status before each playback, so autoplay failure events may be triggered multiple times.
77
+
78
+ 2. Special requirements in iOS WeChat browser and mini-program webview:
79
+ - When playing remote streams for the first time, you must call the playback interface directly in the user click event callback
80
+ - You cannot use asynchronous methods like setTimeout to call the playback interface, otherwise playback will fail
81
+
82
+ ## Disable Autoplay Policy in Webview
83
+
84
+ The default autoplay policy in Android and iOS Webview may be different to the browser. You can refer to the following document to turn off autoplay restrictions in your App.
85
+
86
+ - Android Webview: Call [setMediaPlaybackRequiresUserGesture(false)](https://developer.android.com/reference/android/webkit/WebSettings#setMediaPlaybackRequiresUserGesture(boolean)).
87
+ - iOS Webview: Set [mediaTypesRequiringUserActionForPlayback](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1851524-mediatypesrequiringuseractionfor) to WKAudiovisualMediaTypeNone.