@tencent-rtc/mcp 1.3.5 → 1.3.7
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.
- package/index.js +4 -4
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/resource/doc/livekit/live/flutter/live-audience-list.md +339 -0
- package/resource/doc/livekit/live/flutter/live-audio-effect.md +742 -0
- package/resource/doc/livekit/live/flutter/live-barrage.md +581 -0
- package/resource/doc/livekit/live/flutter/live-base-beauty.md +486 -0
- package/resource/doc/livekit/live/flutter/live-co-guest-interaction.md +608 -0
- package/resource/doc/livekit/live/flutter/live-gift.md +800 -0
- package/resource/doc/livekit/live/flutter/live-host-interaction.md +1113 -0
- package/resource/doc/livekit/live/flutter/live-integration.md +1041 -0
- package/resource/doc/livekit/live/flutter/live-live-list.md +865 -0
- package/resource/doc/livekit/live/flutter/workflow.md +353 -0
- package/resource/doc/tuicallkit/flutter/workflow.md +331 -0
- package/tools/call/get-native-call-integration.js +27 -11
- package/tools/call/get-native-call-integration.js.map +1 -1
- package/tools/definitions/get_native_call_uikit_integration_def.js +17 -7
- package/tools/definitions/get_native_call_uikit_integration_def.js.map +1 -1
- package/utils/report-cls-client.js +1 -1
- package/utils/report-es-client.js +1 -1
- package/resource/doc/tuicallkit/flutter/how_to_run_flutter_callkit_demo.md +0 -101
- package/resource/doc/tuicallkit/iOS/how_to_run_iOS_callkit_demo.md +0 -98
- /package/resource/doc/tuicallkit/android/{how_to_integrated_android_callkit.md → integration.md} +0 -0
- /package/resource/doc/tuicallkit/android/{.gitkeep → workflow.md} +0 -0
- /package/resource/doc/tuicallkit/{android/api_TUICallObserver.md → faq/android_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{android/api_TUICallKit.md → faq/android_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallDefine.md → faq/flutter_sdk/call-define-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallObserver.md → faq/flutter_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{flutter/api_TUICallKit.md → faq/flutter_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/{iOS/api_TUICallObserver.md → faq/ios_sdk/call-observer-api.md} +0 -0
- /package/resource/doc/tuicallkit/{iOS/api_TUICallKit.md → faq/ios_sdk/callkit-api.md} +0 -0
- /package/resource/doc/tuicallkit/flutter/{how_to_integrated_flutter_callkit.md → integration.md} +0 -0
- /package/resource/doc/tuicallkit/iOS/{how_to_integrated_iOS_callkit.md → integration.md} +0 -0
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
`GiftStore` is a module in `AtomicXCore` specialized in managing the gift function of live streaming rooms. With it, you can build a complete gift system for your live stream application to achieve various revenue and interactive scenarios.
|
|
2
|
+
<table>
|
|
3
|
+
<tr>
|
|
4
|
+
<td rowspan="1" colSpan="1" >**Gift Panel**</td>
|
|
5
|
+
|
|
6
|
+
<td rowspan="1" colSpan="1" >**Barrage Gift**</td>
|
|
7
|
+
|
|
8
|
+
<td rowspan="1" colSpan="1" >**Full-Screen Gift**</td>
|
|
9
|
+
</tr>
|
|
10
|
+
|
|
11
|
+
<tr>
|
|
12
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
13
|
+
|
|
14
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
15
|
+
|
|
16
|
+
<td rowspan="1" colSpan="1" ></td>
|
|
17
|
+
</tr>
|
|
18
|
+
</table>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Core Features
|
|
22
|
+
- **Gift List Retrieval**: Obtain the required data for the gift panel from the server, including gift categories and gift details.
|
|
23
|
+
|
|
24
|
+
- **Send a Gift**: The audience can send a selected gift to the Anchor with quantity.
|
|
25
|
+
|
|
26
|
+
- **Gift Event Broadcast**: Receive gift giveaway events inside the room in real time for showing gift animation and bullet screen notification.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Core Concepts
|
|
30
|
+
|
|
31
|
+
Before starting integration, let's learn about several core concepts related to `GiftStore` in the following table:
|
|
32
|
+
<table>
|
|
33
|
+
<tr>
|
|
34
|
+
<td rowspan="1" colSpan="1" >**Core Concepts**</td>
|
|
35
|
+
|
|
36
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
37
|
+
|
|
38
|
+
<td rowspan="1" colSpan="1" >**Core Responsibilities and Description**</td>
|
|
39
|
+
</tr>
|
|
40
|
+
|
|
41
|
+
<tr>
|
|
42
|
+
<td rowspan="1" colSpan="1" >[Gift](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/Gift-class.html)</td>
|
|
43
|
+
|
|
44
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
45
|
+
|
|
46
|
+
<td rowspan="1" colSpan="1" >Represents a specific gift data model. It contains the gift ID, name, icon address, animation resource URL and price (coins).</td>
|
|
47
|
+
</tr>
|
|
48
|
+
|
|
49
|
+
<tr>
|
|
50
|
+
<td rowspan="1" colSpan="1" >[GiftCategory](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftCategory-class.html)</td>
|
|
51
|
+
|
|
52
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
53
|
+
|
|
54
|
+
<td rowspan="1" colSpan="1" >Represents a gift category, such as "popular" and "luxury". It contains the category name as well as the **Gift** list under this category.</td>
|
|
55
|
+
</tr>
|
|
56
|
+
|
|
57
|
+
<tr>
|
|
58
|
+
<td rowspan="1" colSpan="1" >[GiftState](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftState-class.html)</td>
|
|
59
|
+
|
|
60
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
61
|
+
|
|
62
|
+
<td rowspan="1" colSpan="1" >Represents the current status of the gift module. Its core attribute `usableGifts` is a `ValueListenable<List<GiftCategory>>`, storing the complete gift list fetched from the server.</td>
|
|
63
|
+
</tr>
|
|
64
|
+
|
|
65
|
+
<tr>
|
|
66
|
+
<td rowspan="1" colSpan="1" >[GiftListener](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftListener-class.html)</td>
|
|
67
|
+
|
|
68
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
69
|
+
|
|
70
|
+
<td rowspan="1" colSpan="1" >Gift event listener, receive gift giveaway event through the `onReceiveGift` callback. When anyone (including itself) sends a gift, all people in the room will receive this event.</td>
|
|
71
|
+
</tr>
|
|
72
|
+
|
|
73
|
+
<tr>
|
|
74
|
+
<td rowspan="1" colSpan="1" >[GiftStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftStore-class.html)</td>
|
|
75
|
+
|
|
76
|
+
<td rowspan="1" colSpan="1" >`class`</td>
|
|
77
|
+
|
|
78
|
+
<td rowspan="1" colSpan="1" >This is the core management class for interacting with the gift function. Through it, you can fetch the gift list, send a gift, and receive gift events via `addGiftListener`.</td>
|
|
79
|
+
</tr>
|
|
80
|
+
</table>
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## Implementation Steps
|
|
84
|
+
|
|
85
|
+
### Step 1: Integrating the Component
|
|
86
|
+
|
|
87
|
+
> **Note:**
|
|
88
|
+
>
|
|
89
|
+
|
|
90
|
+
> To use the gifting system, activate either the **Free Trial,** or **Pro **edition. The number of configurable gifts depends on the selected package. For details, see the **Gift System** section in [Feature and Billing Description](https://write.woa.com/document/137771241658241024) and choose the package that fits your needs.
|
|
91
|
+
>
|
|
92
|
+
|
|
93
|
+
- **Live streaming**: Refer to [Quick Access](https://write.woa.com/document/200455640177692672) for seamless integration with **AtomicXCore** and access completed.
|
|
94
|
+
|
|
95
|
+
- **Voice chat room**: Refer to [Quick Access](https://write.woa.com/document/200555778169073664) for seamless integration with **AtomicXCore** and access completed.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### Step 2: Initialize and Listen for Gift Events
|
|
99
|
+
|
|
100
|
+
Get the `GiftStore` instance and set a listener for receiving gifts and list update events.
|
|
101
|
+
|
|
102
|
+
#### Implementation Approach
|
|
103
|
+
1. **Get instance**: Use `GiftStore.create(liveId)` to get the `GiftStore` instance bound to the current live streaming room.
|
|
104
|
+
|
|
105
|
+
2. **Subscribe to events**: Add a gift event listener via `giftStore.addGiftListener(listener)`.
|
|
106
|
+
|
|
107
|
+
3. **Subscription status**: Listen to `giftStore.giftState.usableGifts` to get gift list updates.
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
#### Sample code:
|
|
111
|
+
``` java
|
|
112
|
+
import 'package:flutter/foundation.dart';
|
|
113
|
+
import 'package:atomic_x_core/atomicxcore.dart';
|
|
114
|
+
|
|
115
|
+
class GiftManager {
|
|
116
|
+
final String liveId;
|
|
117
|
+
late final GiftStore giftStore;
|
|
118
|
+
late final GiftListener _giftListener;
|
|
119
|
+
late final VoidCallback _giftListChangedListener = _onGiftListChanged;
|
|
120
|
+
|
|
121
|
+
// Expose gift event callback externally
|
|
122
|
+
void Function(String liveID, Gift gift, int count, LiveUserInfo sender)? onReceiveGift;
|
|
123
|
+
|
|
124
|
+
// Expose the gift list externally
|
|
125
|
+
ValueNotifier<List<GiftCategory>> giftListNotifier = ValueNotifier([]);
|
|
126
|
+
|
|
127
|
+
GiftManager({required this.liveId}) {
|
|
128
|
+
// 1. Get the instance of GiftStore by liveId
|
|
129
|
+
giftStore = GiftStore.create(liveId);
|
|
130
|
+
|
|
131
|
+
_subscribeToGiftState();
|
|
132
|
+
_subscribeToGiftEvents();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/// 2. Subscribe to gift events
|
|
136
|
+
void _subscribeToGiftEvents() {
|
|
137
|
+
_giftListener = GiftListener(
|
|
138
|
+
onReceiveGift: (liveID, gift, count, sender) {
|
|
139
|
+
// After receiving the event, forward it to external processing
|
|
140
|
+
onReceiveGift?.call(liveID, gift, count, sender);
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
giftStore.addGiftListener(_giftListener);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// 3. Subscribe to gift list status
|
|
147
|
+
void _subscribeToGiftState() {
|
|
148
|
+
giftStore.giftState.usableGifts.addListener(_giftListChangedListener);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
void _onGiftListChanged() {
|
|
152
|
+
giftListNotifier.value = giftStore.giftState.usableGifts.value;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Call the dispose method to reclaim resources when exiting the live streaming room
|
|
156
|
+
void dispose() {
|
|
157
|
+
giftStore.removeGiftListener(_giftListener);
|
|
158
|
+
giftStore.giftState.usableGifts.removeListener(_giftListChangedListener);
|
|
159
|
+
giftListNotifier.dispose();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### Gift List Structure Parameter
|
|
165
|
+
- `GiftCategory`**Parameter description**
|
|
166
|
+
|
|
167
|
+
<table>
|
|
168
|
+
<tr>
|
|
169
|
+
<td rowspan="1" colSpan="1" >**Parameter**</td>
|
|
170
|
+
|
|
171
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
172
|
+
|
|
173
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
174
|
+
</tr>
|
|
175
|
+
|
|
176
|
+
<tr>
|
|
177
|
+
<td rowspan="1" colSpan="1" >`categoryID`</td>
|
|
178
|
+
|
|
179
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
180
|
+
|
|
181
|
+
<td rowspan="1" colSpan="1" >Unique ID of the gift category.</td>
|
|
182
|
+
</tr>
|
|
183
|
+
|
|
184
|
+
<tr>
|
|
185
|
+
<td rowspan="1" colSpan="1" >`name`</td>
|
|
186
|
+
|
|
187
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
188
|
+
|
|
189
|
+
<td rowspan="1" colSpan="1" >Display name of the gift category.</td>
|
|
190
|
+
</tr>
|
|
191
|
+
|
|
192
|
+
<tr>
|
|
193
|
+
<td rowspan="1" colSpan="1" >`desc`</td>
|
|
194
|
+
|
|
195
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
196
|
+
|
|
197
|
+
<td rowspan="1" colSpan="1" >Description of the gift category.</td>
|
|
198
|
+
</tr>
|
|
199
|
+
|
|
200
|
+
<tr>
|
|
201
|
+
<td rowspan="1" colSpan="1" >`extensionInfo`</td>
|
|
202
|
+
|
|
203
|
+
<td rowspan="1" colSpan="1" >`Map<String, String>`</td>
|
|
204
|
+
|
|
205
|
+
<td rowspan="1" colSpan="1" >Extended information field.</td>
|
|
206
|
+
</tr>
|
|
207
|
+
|
|
208
|
+
<tr>
|
|
209
|
+
<td rowspan="1" colSpan="1" >`giftList`</td>
|
|
210
|
+
|
|
211
|
+
<td rowspan="1" colSpan="1" >`List<Gift>`</td>
|
|
212
|
+
|
|
213
|
+
<td rowspan="1" colSpan="1" >Array of Gift objects under this category.</td>
|
|
214
|
+
</tr>
|
|
215
|
+
</table>
|
|
216
|
+
|
|
217
|
+
- `Gift`**Parameter description**
|
|
218
|
+
|
|
219
|
+
<table>
|
|
220
|
+
<tr>
|
|
221
|
+
<td rowspan="1" colSpan="1" >**Parameter**</td>
|
|
222
|
+
|
|
223
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
224
|
+
|
|
225
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
226
|
+
</tr>
|
|
227
|
+
|
|
228
|
+
<tr>
|
|
229
|
+
<td rowspan="1" colSpan="1" >`giftID`</td>
|
|
230
|
+
|
|
231
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
232
|
+
|
|
233
|
+
<td rowspan="1" colSpan="1" >Unique ID of the gift.</td>
|
|
234
|
+
</tr>
|
|
235
|
+
|
|
236
|
+
<tr>
|
|
237
|
+
<td rowspan="1" colSpan="1" >`name`</td>
|
|
238
|
+
|
|
239
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
240
|
+
|
|
241
|
+
<td rowspan="1" colSpan="1" >Display name of the gift.</td>
|
|
242
|
+
</tr>
|
|
243
|
+
|
|
244
|
+
<tr>
|
|
245
|
+
<td rowspan="1" colSpan="1" >`desc`</td>
|
|
246
|
+
|
|
247
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
248
|
+
|
|
249
|
+
<td rowspan="1" colSpan="1" >Description of the gift.</td>
|
|
250
|
+
</tr>
|
|
251
|
+
|
|
252
|
+
<tr>
|
|
253
|
+
<td rowspan="1" colSpan="1" >`iconURL`</td>
|
|
254
|
+
|
|
255
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
256
|
+
|
|
257
|
+
<td rowspan="1" colSpan="1" >Icon URL of the gift.</td>
|
|
258
|
+
</tr>
|
|
259
|
+
|
|
260
|
+
<tr>
|
|
261
|
+
<td rowspan="1" colSpan="1" >`resourceURL`</td>
|
|
262
|
+
|
|
263
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
264
|
+
|
|
265
|
+
<td rowspan="1" colSpan="1" >Resource URL of the gift animation.</td>
|
|
266
|
+
</tr>
|
|
267
|
+
|
|
268
|
+
<tr>
|
|
269
|
+
<td rowspan="1" colSpan="1" >`level`</td>
|
|
270
|
+
|
|
271
|
+
<td rowspan="1" colSpan="1" >`int`</td>
|
|
272
|
+
|
|
273
|
+
<td rowspan="1" colSpan="1" >Gift level.</td>
|
|
274
|
+
</tr>
|
|
275
|
+
|
|
276
|
+
<tr>
|
|
277
|
+
<td rowspan="1" colSpan="1" >`coins`</td>
|
|
278
|
+
|
|
279
|
+
<td rowspan="1" colSpan="1" >`int`</td>
|
|
280
|
+
|
|
281
|
+
<td rowspan="1" colSpan="1" >Gift price.</td>
|
|
282
|
+
</tr>
|
|
283
|
+
|
|
284
|
+
<tr>
|
|
285
|
+
<td rowspan="1" colSpan="1" >`extensionInfo`</td>
|
|
286
|
+
|
|
287
|
+
<td rowspan="1" colSpan="1" >`Map<String, String>`</td>
|
|
288
|
+
|
|
289
|
+
<td rowspan="1" colSpan="1" >Extended information field.</td>
|
|
290
|
+
</tr>
|
|
291
|
+
</table>
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
### Step 3: Obtain the Gift List
|
|
295
|
+
|
|
296
|
+
Call the `refreshUsableGifts` method to fetch gift data from the server.
|
|
297
|
+
|
|
298
|
+
#### Implementation Approach
|
|
299
|
+
1. **API call**: Call `giftStore.refreshUsableGifts()` at the appropriate timing (such as after entering the live room).
|
|
300
|
+
|
|
301
|
+
2. **Processing result**: Optionally process the returned results to fetch the pull results.
|
|
302
|
+
|
|
303
|
+
3. **Data reception**: After the update, the gift list is automatically received by listening to `giftStore.giftState.usableGifts` in procedure 2.
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
#### Sample code:
|
|
307
|
+
``` java
|
|
308
|
+
extension GiftManagerFetch on GiftManager {
|
|
309
|
+
/// Refresh the gift list from the server
|
|
310
|
+
Future<void> fetchGiftList() async {
|
|
311
|
+
final result = await giftStore.refreshUsableGifts();
|
|
312
|
+
if (result.isSuccess) {
|
|
313
|
+
debugPrint("Gift list success message");
|
|
314
|
+
// Upon success, the data is auto-updated via usableGifts listen
|
|
315
|
+
} else {
|
|
316
|
+
debugPrint("Gift list failed to pull: ${result.errorMessage}");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Step 4: Sending a Gift
|
|
323
|
+
|
|
324
|
+
When a user selects a gift in the gift panel and clicks send, call the `sendGift` API to send the gift.
|
|
325
|
+
|
|
326
|
+
#### Implementation Approach
|
|
327
|
+
1. **Get parameter**: Obtain the giftID selected by the user and the number of messages sent (count) from the UI.
|
|
328
|
+
|
|
329
|
+
2. **API call**: Call `giftStore.sendGift(giftID:, count:)`.
|
|
330
|
+
|
|
331
|
+
3. **Processing result**: Handle failure cases (such as insufficient account balance notification) in the returned result. UI updates (animation, bullet screen) after successful sending should be event-driven by `onReceiveGift`.
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
#### Sample code:
|
|
335
|
+
``` java
|
|
336
|
+
extension GiftManagerSend on GiftManager {
|
|
337
|
+
/// User sends a gift
|
|
338
|
+
Future<void> sendGift(String giftID, int count) async {
|
|
339
|
+
final result = await giftStore.sendGift(giftID: giftID, count: count);
|
|
340
|
+
if (result.isSuccess) {
|
|
341
|
+
debugPrint("Gift $giftID sent successfully");
|
|
342
|
+
// After the message is sent successfully, everyone including the sender will receive the onReceiveGift event
|
|
343
|
+
} else {
|
|
344
|
+
debugPrint("Gift sending failed: ${result.errorMessage}");
|
|
345
|
+
// You can prompt user here, such as "Insufficient balance" or "Network error"
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### `SendGift` API Parameter
|
|
352
|
+
<table>
|
|
353
|
+
<tr>
|
|
354
|
+
<td rowspan="1" colSpan="1" >**Parameter Name**</td>
|
|
355
|
+
|
|
356
|
+
<td rowspan="1" colSpan="1" >**Type**</td>
|
|
357
|
+
|
|
358
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
359
|
+
</tr>
|
|
360
|
+
|
|
361
|
+
<tr>
|
|
362
|
+
<td rowspan="1" colSpan="1" >`giftID`</td>
|
|
363
|
+
|
|
364
|
+
<td rowspan="1" colSpan="1" >`String`</td>
|
|
365
|
+
|
|
366
|
+
<td rowspan="1" colSpan="1" >Unique ID of the gift to send.</td>
|
|
367
|
+
</tr>
|
|
368
|
+
|
|
369
|
+
<tr>
|
|
370
|
+
<td rowspan="1" colSpan="1" >`count`</td>
|
|
371
|
+
|
|
372
|
+
<td rowspan="1" colSpan="1" >`int`</td>
|
|
373
|
+
|
|
374
|
+
<td rowspan="1" colSpan="1" >The number of sent.</td>
|
|
375
|
+
</tr>
|
|
376
|
+
</table>
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
## Advanced Features
|
|
380
|
+
|
|
381
|
+
`GiftStore` feature heavily depends on your business backend service. This chapter will guide you on how to build a feature-rich, outstanding experience interactive system through server configuration and client implementation.
|
|
382
|
+
|
|
383
|
+
### **Gift Material Configuration**
|
|
384
|
+
|
|
385
|
+
You need to customize the available gift type, category, name, icon, price, and animated effects in the live streaming room to meet operational needs and brand feature.
|
|
386
|
+
|
|
387
|
+
#### Implementation
|
|
388
|
+
1. **Server-Side Configuration**: Use the LiveKit server REST API to manage gift information, categories, and multi-language support. See the [Gift Configuration Guide](https://write.woa.com/document/185130564680273920).
|
|
389
|
+
|
|
390
|
+
2. **Client Fetch**: On the client, call `refreshUsableGifts` to retrieve configuration data.
|
|
391
|
+
|
|
392
|
+
3. **UI Display**: Use the retrieved `List<GiftCategory>` to render the gift panel.
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
#### Configuration Sequence Diagram
|
|
396
|
+
|
|
397
|
+

|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
#### Related REST API Interfaces Overview
|
|
401
|
+
<table>
|
|
402
|
+
<tr>
|
|
403
|
+
<td rowspan="1" colSpan="1" >**Interface Category**</td>
|
|
404
|
+
|
|
405
|
+
<td rowspan="1" colSpan="1" >**Interface**</td>
|
|
406
|
+
|
|
407
|
+
<td rowspan="1" colSpan="1" >**Request Example**</td>
|
|
408
|
+
</tr>
|
|
409
|
+
|
|
410
|
+
<tr>
|
|
411
|
+
<td rowspan="3" colSpan="1" >**Gift Management**</td>
|
|
412
|
+
|
|
413
|
+
<td rowspan="1" colSpan="1" >Add Gift Information</td>
|
|
414
|
+
|
|
415
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185130814885187584)</td>
|
|
416
|
+
</tr>
|
|
417
|
+
|
|
418
|
+
<tr>
|
|
419
|
+
<td rowspan="1" colSpan="1" >Delete Gift Information</td>
|
|
420
|
+
|
|
421
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131021432451072)</td>
|
|
422
|
+
</tr>
|
|
423
|
+
|
|
424
|
+
<tr>
|
|
425
|
+
<td rowspan="1" colSpan="1" >Query Gift Information</td>
|
|
426
|
+
|
|
427
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185130925608591360)</td>
|
|
428
|
+
</tr>
|
|
429
|
+
|
|
430
|
+
<tr>
|
|
431
|
+
<td rowspan="3" colSpan="1" >**Gift Category Management**</td>
|
|
432
|
+
|
|
433
|
+
<td rowspan="1" colSpan="1" >Add Gift Category Information</td>
|
|
434
|
+
|
|
435
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131054187974656)</td>
|
|
436
|
+
</tr>
|
|
437
|
+
|
|
438
|
+
<tr>
|
|
439
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Category Information</td>
|
|
440
|
+
|
|
441
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131288984932352)</td>
|
|
442
|
+
</tr>
|
|
443
|
+
|
|
444
|
+
<tr>
|
|
445
|
+
<td rowspan="1" colSpan="1" >Get Specific Gift Category Information</td>
|
|
446
|
+
|
|
447
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131164168736768)</td>
|
|
448
|
+
</tr>
|
|
449
|
+
|
|
450
|
+
<tr>
|
|
451
|
+
<td rowspan="3" colSpan="1" >**Gift Relationship Management**</td>
|
|
452
|
+
|
|
453
|
+
<td rowspan="1" colSpan="1" >Add Relationship between a Specific Gift Category and Gift</td>
|
|
454
|
+
|
|
455
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131388068356096)</td>
|
|
456
|
+
</tr>
|
|
457
|
+
|
|
458
|
+
<tr>
|
|
459
|
+
<td rowspan="1" colSpan="1" >Delete Relationship between a Specific Gift Category and Gift</td>
|
|
460
|
+
|
|
461
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131491225227264)</td>
|
|
462
|
+
</tr>
|
|
463
|
+
|
|
464
|
+
<tr>
|
|
465
|
+
<td rowspan="1" colSpan="1" >Get Gift Relationships under a Specific Gift Category</td>
|
|
466
|
+
|
|
467
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131634710056960)</td>
|
|
468
|
+
</tr>
|
|
469
|
+
|
|
470
|
+
<tr>
|
|
471
|
+
<td rowspan="6" colSpan="1" >**Gift Multi-language Management**</td>
|
|
472
|
+
|
|
473
|
+
<td rowspan="1" colSpan="1" >Add Gift Multi-language Information</td>
|
|
474
|
+
|
|
475
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131766094020608)</td>
|
|
476
|
+
</tr>
|
|
477
|
+
|
|
478
|
+
<tr>
|
|
479
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Multi-language Information</td>
|
|
480
|
+
|
|
481
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132041665441792)</td>
|
|
482
|
+
</tr>
|
|
483
|
+
|
|
484
|
+
<tr>
|
|
485
|
+
<td rowspan="1" colSpan="1" >Get Gift Multi-language Information</td>
|
|
486
|
+
|
|
487
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185131910582956032)</td>
|
|
488
|
+
</tr>
|
|
489
|
+
|
|
490
|
+
<tr>
|
|
491
|
+
<td rowspan="1" colSpan="1" >Add Gift Category Multi-language Information</td>
|
|
492
|
+
|
|
493
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132145524985856)</td>
|
|
494
|
+
</tr>
|
|
495
|
+
|
|
496
|
+
<tr>
|
|
497
|
+
<td rowspan="1" colSpan="1" >Delete Specific Gift Category Multi-language Information</td>
|
|
498
|
+
|
|
499
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132396568891392)</td>
|
|
500
|
+
</tr>
|
|
501
|
+
|
|
502
|
+
<tr>
|
|
503
|
+
<td rowspan="1" colSpan="1" >Get Gift Category Multi-language Information</td>
|
|
504
|
+
|
|
505
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/185132283123777536)</td>
|
|
506
|
+
</tr>
|
|
507
|
+
</table>
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
### Billing and Gift Sending Process
|
|
511
|
+
|
|
512
|
+
When the audience sends gifts, ensure sufficient account balance and complete the actual deduction before triggering the gift effect playback and broadcast.
|
|
513
|
+
|
|
514
|
+
#### Workflow
|
|
515
|
+
1. **Backend Callback Configuration**: Configure your billing system's callback URL in the LiveKit backend. See [Callback Configuration Documentation](https://write.woa.com/document/155612057789870080).
|
|
516
|
+
|
|
517
|
+
2. **Client Request**: The client calls `sendGift`.
|
|
518
|
+
|
|
519
|
+
3. **Backend Verification**: The LiveKit backend calls your callback URL; your billing system processes the deduction and returns the result.
|
|
520
|
+
|
|
521
|
+
4. **Result Synchronization**: If succeeds, **AtomicXCore** broadcasts the `onReceiveGift` event; if fails, the completion callback of `sendGift` receives an error.
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
#### Call Flow
|
|
525
|
+
|
|
526
|
+

|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
#### Related REST API Interfaces Overview
|
|
530
|
+
<table>
|
|
531
|
+
<tr>
|
|
532
|
+
<td rowspan="1" colSpan="1" >**Interface**</td>
|
|
533
|
+
|
|
534
|
+
<td rowspan="1" colSpan="1" >**Description**</td>
|
|
535
|
+
|
|
536
|
+
<td rowspan="1" colSpan="1" >**Request Example**</td>
|
|
537
|
+
</tr>
|
|
538
|
+
|
|
539
|
+
<tr>
|
|
540
|
+
<td rowspan="1" colSpan="1" >**Callback Configuration - Callback before sending a gift**</td>
|
|
541
|
+
|
|
542
|
+
<td rowspan="1" colSpan="1" >Pre-gifting validation hook. <br>Allows your backend to intercept gift requests to perform necessary checks (e.g., sufficient balance, risk control) before the gift is processed.</td>
|
|
543
|
+
|
|
544
|
+
<td rowspan="1" colSpan="1" >[Example](https://write.woa.com/document/183772991768039424)</td>
|
|
545
|
+
</tr>
|
|
546
|
+
</table>
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
### Play Full-Screen Gift Animation
|
|
550
|
+
|
|
551
|
+
When a user (including itself) sends luxury gifts such as "rocket" or "carnival" in the live streaming room, play a cool gift animation (for example, SVGA animation) in full-screen playback to create a lively communication environment.
|
|
552
|
+
|
|
553
|
+
#### Implementation
|
|
554
|
+
|
|
555
|
+
`AtomicXCore` itself does not include a gift animation player. You need to select and integrate a third-party library based on business requirements. The following is a comparison of two solutions:
|
|
556
|
+
<table>
|
|
557
|
+
<tr>
|
|
558
|
+
<td rowspan="1" colSpan="1" >**Comparison Item**</td>
|
|
559
|
+
|
|
560
|
+
<td rowspan="1" colSpan="1" >**Basic Solution (Svgaplayer_flutter)**</td>
|
|
561
|
+
|
|
562
|
+
<td rowspan="1" colSpan="1" >**Advanced Plan (TCEffectPlayerKit)**</td>
|
|
563
|
+
</tr>
|
|
564
|
+
|
|
565
|
+
<tr>
|
|
566
|
+
<td rowspan="1" colSpan="1" >Billing</td>
|
|
567
|
+
|
|
568
|
+
<td rowspan="1" colSpan="1" >Free (open-source library)</td>
|
|
569
|
+
|
|
570
|
+
<td rowspan="1" colSpan="1" >Paid (License purchase required), please see [Payment Guide](https://trtc.io/document/69949?product=beautyar&menulabel=core%20sdk&platform=android#X-Series-Capabilities)</td>
|
|
571
|
+
</tr>
|
|
572
|
+
|
|
573
|
+
<tr>
|
|
574
|
+
<td rowspan="1" colSpan="1" >Integration Method</td>
|
|
575
|
+
|
|
576
|
+
<td rowspan="1" colSpan="1" >Manual integration of the [svgaplayer_flutter](https://pub.dev/packages/svgaplayer_flutter) library is required.</td>
|
|
577
|
+
|
|
578
|
+
<td rowspan="1" colSpan="1" >Additional integration of the [flutter_effect_player](https://github.com/Tencent-RTC/EffectPlayer_Flutter) library and authentication are required.</td>
|
|
579
|
+
</tr>
|
|
580
|
+
|
|
581
|
+
<tr>
|
|
582
|
+
<td rowspan="1" colSpan="1" >Animation Format Support</td>
|
|
583
|
+
|
|
584
|
+
<td rowspan="1" colSpan="1" >SVGA only</td>
|
|
585
|
+
|
|
586
|
+
<td rowspan="1" colSpan="1" >SVGA, PAG, WebP, Lottie, MP4, and other formats</td>
|
|
587
|
+
</tr>
|
|
588
|
+
|
|
589
|
+
<tr>
|
|
590
|
+
<td rowspan="1" colSpan="1" >Performance</td>
|
|
591
|
+
|
|
592
|
+
<td rowspan="1" colSpan="1" >Recommend SVGA files ≤ 10MB</td>
|
|
593
|
+
|
|
594
|
+
<td rowspan="1" colSpan="1" >Support larger animation files, better performance for complex effects, multi-animation concurrency, and low-end devices</td>
|
|
595
|
+
</tr>
|
|
596
|
+
|
|
597
|
+
<tr>
|
|
598
|
+
<td rowspan="1" colSpan="1" >Recommended scenarios</td>
|
|
599
|
+
|
|
600
|
+
<td rowspan="1" colSpan="1" >Gift animation format is unified as SVGA with controllable file size</td>
|
|
601
|
+
|
|
602
|
+
<td rowspan="1" colSpan="1" >Support multiple animation formats or higher performance/compatibility requirements</td>
|
|
603
|
+
</tr>
|
|
604
|
+
</table>
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
This section demonstrates the basic solution. If you select the advanced plan, refer to [EffectPlayer Flutter integration guide](https://trtc.io/document/73975?product=beautyar&menulabel=core%20sdk&platform=flutter).
|
|
608
|
+
|
|
609
|
+
#### Basic Solution Implementation: Use Svgaplayer_flutter
|
|
610
|
+
1. **Integrate svgaplayer_flutter**: In your `pubspec.yaml` file, add dependency and run `flutter pub get`.
|
|
611
|
+
|
|
612
|
+
``` yaml
|
|
613
|
+
dependencies:
|
|
614
|
+
svgaplayer_flutter: ^2.0.0
|
|
615
|
+
```
|
|
616
|
+
2. **Listen for gift events**: Add a listener via `GiftStore`'s `addGiftListener`.
|
|
617
|
+
|
|
618
|
+
3. **Parse and play**: When the `onReceiveGift` event is received, check if `gift.resourceURL` is valid and points to an SVGA file. If so, use `SVGAAnimationController` to play the animation.
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
#### Sample Code
|
|
622
|
+
``` java
|
|
623
|
+
import 'package:flutter/material.dart';
|
|
624
|
+
import 'package:atomic_x_core/atomicxcore.dart';
|
|
625
|
+
import 'package:svgaplayer_flutter/svgaplayer_flutter.dart';
|
|
626
|
+
|
|
627
|
+
class LiveRoomWidget extends StatefulWidget {
|
|
628
|
+
final String liveId;
|
|
629
|
+
const LiveRoomWidget({Key? key, required this.liveId}) : super(key: key);
|
|
630
|
+
|
|
631
|
+
@override
|
|
632
|
+
State<LiveRoomWidget> createState() => _LiveRoomWidgetState();
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
class _LiveRoomWidgetState extends State<LiveRoomWidget> with SingleTickerProviderStateMixin {
|
|
636
|
+
late GiftManager giftManager;
|
|
637
|
+
|
|
638
|
+
// SVGA player
|
|
639
|
+
late SVGAAnimationController _svgaController;
|
|
640
|
+
bool _showAnimation = false;
|
|
641
|
+
|
|
642
|
+
@override
|
|
643
|
+
void initState() {
|
|
644
|
+
super.initState();
|
|
645
|
+
_svgaController = SVGAAnimationController(vsync: this);
|
|
646
|
+
_setupGiftSubscription();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
void _setupGiftSubscription() {
|
|
650
|
+
giftManager = GiftManager(liveId: widget.liveId);
|
|
651
|
+
|
|
652
|
+
giftManager.onReceiveGift = (liveID, gift, count, sender) {
|
|
653
|
+
if (gift.resourceURL.isNotEmpty) {
|
|
654
|
+
_playAnimation(gift.resourceURL);
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
Future<void> _playAnimation(String url) async {
|
|
660
|
+
try {
|
|
661
|
+
final videoItem = await SVGAParser.shared.decodeFromURL(url);
|
|
662
|
+
_svgaController.videoItem = videoItem;
|
|
663
|
+
setState(() {
|
|
664
|
+
_showAnimation = true;
|
|
665
|
+
});
|
|
666
|
+
_svgaController.forward().whenComplete(() {
|
|
667
|
+
setState(() {
|
|
668
|
+
_showAnimation = false;
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
} catch (e) {
|
|
672
|
+
debugPrint("SVGA animation parsing failure: $e");
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
@override
|
|
677
|
+
void dispose() {
|
|
678
|
+
_svgaController.dispose();
|
|
679
|
+
giftManager.dispose();
|
|
680
|
+
super.dispose();
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
@override
|
|
684
|
+
Widget build(BuildContext context) {
|
|
685
|
+
return Stack(
|
|
686
|
+
children: [
|
|
687
|
+
// Live stream
|
|
688
|
+
// ...
|
|
689
|
+
|
|
690
|
+
// Full-Screen Gift Animation
|
|
691
|
+
if (_showAnimation)
|
|
692
|
+
Positioned.fill(
|
|
693
|
+
child: SVGAImage(_svgaController),
|
|
694
|
+
),
|
|
695
|
+
],
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
### Show Gift Giveaway Messages in the Bullet Screen Area
|
|
702
|
+
|
|
703
|
+
When a user sends a gift, it not only plays the animation but also displays a system message in the on-screen comment area, such as "[Nickname] sent [gift name] x [quantity]", so all audience can see.
|
|
704
|
+
|
|
705
|
+
#### Implementation Method
|
|
706
|
+
1. **Listen for events**: Add a listener via `giftStore.addGiftListener`.
|
|
707
|
+
|
|
708
|
+
2. **Obtain information**: After the `onReceiveGift` event is received, extract the sender, gift, and count.
|
|
709
|
+
|
|
710
|
+
3. **Retrieve the bullet screen Store**: Use `BarrageStore.create(liveId)` to get the instance bound to the current room.
|
|
711
|
+
|
|
712
|
+
4. **Concatenate messages**: Create a `Barrage` object, set `messageType = BarrageType.text`, and `textContent` as the concatenated string (such as "[`sender.userName`] sent [`gift.name`] x [`count`]").
|
|
713
|
+
|
|
714
|
+
5. **Local insertion**: Call `barrageStore.appendLocalTip(giftTip)` to insert the message into the local list.
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
#### Sample Code
|
|
718
|
+
``` java
|
|
719
|
+
// In LiveRoomManager or similar top-level managers
|
|
720
|
+
void _setupGiftToBarrageFlow() {
|
|
721
|
+
final giftStore = GiftStore.create(liveId);
|
|
722
|
+
final barrageStore = BarrageStore.create(liveId);
|
|
723
|
+
|
|
724
|
+
final giftListener = GiftListener(
|
|
725
|
+
onReceiveGift: (liveID, gift, count, sender) {
|
|
726
|
+
// Concatenate the message
|
|
727
|
+
final tipText = "${sender.userName} sent ${gift.name} x $count";
|
|
728
|
+
final giftTip = Barrage(
|
|
729
|
+
messageType: BarrageType.text,
|
|
730
|
+
textContent: tipText,
|
|
731
|
+
);
|
|
732
|
+
// Optional: Set a special sender
|
|
733
|
+
|
|
734
|
+
// local insertion
|
|
735
|
+
barrageStore.appendLocalTip(giftTip);
|
|
736
|
+
},
|
|
737
|
+
);
|
|
738
|
+
|
|
739
|
+
giftStore.addGiftListener(giftListener);
|
|
740
|
+
}
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
## API documentation
|
|
744
|
+
|
|
745
|
+
For detailed information about all public interfaces, attributes, and methods of [GiftStore](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftStore-class.html) and its related classes, see the official API documentation of the [AtomicXCore](https://tencent-rtc.github.io/TUIKit_Flutter/index.html) framework. The related Stores used in this guide are as follows:
|
|
746
|
+
<table>
|
|
747
|
+
<tr>
|
|
748
|
+
<td rowspan="1" colSpan="1" >**Store/Component**</td>
|
|
749
|
+
|
|
750
|
+
<td rowspan="1" colSpan="1" >**Feature Description**</td>
|
|
751
|
+
|
|
752
|
+
<td rowspan="1" colSpan="1" >**API Reference**</td>
|
|
753
|
+
</tr>
|
|
754
|
+
|
|
755
|
+
<tr>
|
|
756
|
+
<td rowspan="1" colSpan="1" >**GiftStore**</td>
|
|
757
|
+
|
|
758
|
+
<td rowspan="1" colSpan="1" >Gift interaction: Get gift list, send/receive gifts, listen to gift events (including sender, gift details).</td>
|
|
759
|
+
|
|
760
|
+
<td rowspan="1" colSpan="1" >[API documentation](https://tencent-rtc.github.io/TUIKit_Flutter/api_gift_gift_store/GiftStore-class.html)</td>
|
|
761
|
+
</tr>
|
|
762
|
+
|
|
763
|
+
<tr>
|
|
764
|
+
<td rowspan="1" colSpan="1" >**BarrageStore**</td>
|
|
765
|
+
|
|
766
|
+
<td rowspan="1" colSpan="1" >Danmaku function: send text / custom barrage item, maintain bullet screen list, monitor in real time.</td>
|
|
767
|
+
|
|
768
|
+
<td rowspan="1" colSpan="1" >[API documentation](https://tencent-rtc.github.io/TUIKit_Flutter/api_barrage_barrage_store/BarrageStore-class.html)</td>
|
|
769
|
+
</tr>
|
|
770
|
+
</table>
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
## FAQs
|
|
774
|
+
|
|
775
|
+
### `GiftStore` Gift List Is Empty. What Should Be Done?
|
|
776
|
+
|
|
777
|
+
You must actively call `refreshUsableGifts()` to fetch gift data from your backend. These gift data need to be configured in your backend via server-side REST API.
|
|
778
|
+
|
|
779
|
+
### How to Achieve Multilingual Gift Display (Such As Chinese, English)
|
|
780
|
+
|
|
781
|
+
`GiftStore` provides the `setLanguage(String language)` API. You can call this method before `refreshUsableGifts`, input the target language code (such as "en" or "zh-CN"). The server will return the gift name and description in the corresponding language based on this language code.
|
|
782
|
+
|
|
783
|
+
### I Called SendGift to Send the Gift, Why Did the Gift Animation Repeat Playback Twice?
|
|
784
|
+
|
|
785
|
+
`onReceiveGift` is a broadcast to all members in the room (including the sender). If you perform a UI operation in the success callback of `sendGift`, and simultaneously execute the same UI operation in the `onReceiveGift` callback, it can lead to duplication.
|
|
786
|
+
- **Best practice**: UI updates (such as playing animation, bullet screen notification) should only be handled in the callback of the `onReceiveGift` event. The returned results of `sendGift` are only used to process the logic of sending failure (such as prompting the user "sending failure" or "insufficient balance").
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
### Where Is the Gift Charge Logic Implemented?
|
|
790
|
+
|
|
791
|
+
The gift charge logic is fully handled by your self-built billing system. `AtomicXCore` connects with your billing system through a backend callback mechanism. The client calls `sendGift` to trigger the callback. After your backend service completes the charge, it returns the result to the `AtomicXCore` backend, thereby determining whether to broadcast the gift event.
|
|
792
|
+
|
|
793
|
+
### Will Gift Sending Notifications Be Muted or Blocked by Frequency Control?
|
|
794
|
+
|
|
795
|
+
No. Gift sending notifications (`onReceiveGift` event) are not affected by muting or message frequency control, ensuring reliable delivery.
|
|
796
|
+
|
|
797
|
+
### What to Do About Playback Lag in Gift Animation
|
|
798
|
+
|
|
799
|
+
Please check your SVGA file size. Player SDKs recommend not exceeding 10MB. If the file is too large or the animation is complex, you can consider seamless integration with the advanced effect player provided by TUILiveKit to get better performance.
|
|
800
|
+
|