@spatialwalk/avatarkit 1.0.0-beta.1 → 1.0.0-beta.3
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/README.md +164 -135
- package/dist/{StreamingAudioPlayer-C2TfYsO8.js → StreamingAudioPlayer-BeLlDiwE.js} +10 -15
- package/dist/{StreamingAudioPlayer-C2TfYsO8.js.map → StreamingAudioPlayer-BeLlDiwE.js.map} +1 -1
- package/dist/animation/AnimationWebSocketClient.d.ts.map +1 -1
- package/dist/animation/utils/flameConverter.d.ts.map +1 -1
- package/dist/audio/StreamingAudioPlayer.d.ts.map +1 -1
- package/dist/{index-DwhR9l52.js → index-NmYXWJnL.js} +7 -7
- package/dist/index-NmYXWJnL.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -8
- package/dist/config/region-config.d.ts +0 -17
- package/dist/config/region-config.d.ts.map +0 -1
- package/dist/generated/google/protobuf/any.d.ts +0 -145
- package/dist/generated/google/protobuf/any.d.ts.map +0 -1
- package/dist/generated/jsonapi/v1/base.d.ts +0 -140
- package/dist/generated/jsonapi/v1/base.d.ts.map +0 -1
- package/dist/generated/platform/v1/asset_groups.d.ts +0 -225
- package/dist/generated/platform/v1/asset_groups.d.ts.map +0 -1
- package/dist/generated/platform/v1/assets.d.ts +0 -149
- package/dist/generated/platform/v1/assets.d.ts.map +0 -1
- package/dist/generated/platform/v1/character.d.ts +0 -395
- package/dist/generated/platform/v1/character.d.ts.map +0 -1
- package/dist/generated/platform/v1/redeem.d.ts +0 -22
- package/dist/generated/platform/v1/redeem.d.ts.map +0 -1
- package/dist/index-DwhR9l52.js.map +0 -1
- package/dist/utils/toast.d.ts +0 -74
- package/dist/utils/toast.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# SPAvatarKit SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Real-time virtual avatar rendering SDK based on 3D Gaussian Splatting, supporting audio-driven animation rendering and high-quality 3D rendering.
|
|
4
4
|
|
|
5
|
-
## 🚀
|
|
5
|
+
## 🚀 Features
|
|
6
6
|
|
|
7
|
-
- **3D Gaussian Splatting
|
|
8
|
-
-
|
|
9
|
-
- **WebGPU/WebGL
|
|
10
|
-
- **WASM
|
|
11
|
-
- **TypeScript
|
|
12
|
-
-
|
|
7
|
+
- **3D Gaussian Splatting Rendering** - Based on the latest point cloud rendering technology, providing high-quality 3D virtual avatars
|
|
8
|
+
- **Audio-Driven Real-Time Animation Rendering** - Users provide audio data, SDK handles receiving animation data and rendering
|
|
9
|
+
- **WebGPU/WebGL Dual Rendering Backend** - Automatically selects the best rendering backend for compatibility
|
|
10
|
+
- **WASM High-Performance Computing** - Uses C++ compiled WebAssembly modules for geometric calculations
|
|
11
|
+
- **TypeScript Support** - Complete type definitions and IntelliSense
|
|
12
|
+
- **Modular Architecture** - Clear component separation, easy to integrate and extend
|
|
13
13
|
|
|
14
|
-
## 📦
|
|
14
|
+
## 📦 Installation
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
npm install @spatialwalk/avatarkit
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
## 🎯
|
|
20
|
+
## 🎯 Quick Start
|
|
21
21
|
|
|
22
|
-
###
|
|
22
|
+
### Basic Usage
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
import {
|
|
@@ -30,150 +30,173 @@ import {
|
|
|
30
30
|
Environment
|
|
31
31
|
} from '@spatialwalk/avatarkit'
|
|
32
32
|
|
|
33
|
-
// 1.
|
|
33
|
+
// 1. Initialize SDK
|
|
34
34
|
const configuration: Configuration = {
|
|
35
35
|
environment: Environment.test,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
await AvatarKit.initialize('your-app-id', configuration)
|
|
39
39
|
|
|
40
|
-
//
|
|
40
|
+
// Set sessionToken (if needed, call separately)
|
|
41
41
|
// AvatarKit.setSessionToken('your-session-token')
|
|
42
42
|
|
|
43
|
-
// 2.
|
|
43
|
+
// 2. Load character
|
|
44
44
|
const avatarManager = new AvatarManager()
|
|
45
45
|
const avatar = await avatarManager.load('character-id', (progress) => {
|
|
46
46
|
console.log(`Loading progress: ${progress.progress}%`)
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
// 3.
|
|
49
|
+
// 3. Create view (automatically creates Canvas and AvatarController)
|
|
50
50
|
const container = document.getElementById('avatar-container')
|
|
51
51
|
const avatarView = new AvatarView(avatar, container)
|
|
52
52
|
|
|
53
|
-
// 4.
|
|
53
|
+
// 4. Start real-time communication
|
|
54
54
|
await avatarView.avatarController.start()
|
|
55
55
|
|
|
56
|
-
// 5.
|
|
57
|
-
//
|
|
58
|
-
const audioUint8 = new Uint8Array(1024) //
|
|
59
|
-
const audioData = audioUint8.slice().buffer //
|
|
60
|
-
avatarView.avatarController.send(audioData, false) //
|
|
61
|
-
avatarView.avatarController.send(audioData, true) // end=true
|
|
56
|
+
// 5. Send audio data
|
|
57
|
+
// If audio is Uint8Array, you can use slice().buffer to convert to ArrayBuffer
|
|
58
|
+
const audioUint8 = new Uint8Array(1024) // Example: audio data
|
|
59
|
+
const audioData = audioUint8.slice().buffer // Simplified conversion, works for ArrayBuffer and SharedArrayBuffer
|
|
60
|
+
avatarView.avatarController.send(audioData, false) // Send audio data, will automatically start playing after accumulating enough data
|
|
61
|
+
avatarView.avatarController.send(audioData, true) // end=true means immediately return animation data, no longer accumulating
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
###
|
|
64
|
+
### Complete Example
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Check the example code in the GitHub repository for the complete usage flow.
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
**Example Project:** [Avatarkit-web-demo](https://github.com/spatialwalk/Avatarkit-web-demo)
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
This repository contains complete examples for Vanilla JS, Vue 3, and React, demonstrating how to integrate and use SPAvatarKit SDK in different frameworks.
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
- **AvatarManager** - 角色资源加载和管理
|
|
74
|
-
- **AvatarView** - 3D 渲染视图(内部包含 AvatarController)
|
|
75
|
-
- **AvatarController** - 实时通信和数据处理
|
|
76
|
-
- **AvatarCoreAdapter** - WASM 模块适配器
|
|
72
|
+
## 🏗️ Architecture Overview
|
|
77
73
|
|
|
78
|
-
###
|
|
74
|
+
### Core Components
|
|
75
|
+
|
|
76
|
+
- **AvatarKit** - SDK initialization and management
|
|
77
|
+
- **AvatarManager** - Character resource loading and management
|
|
78
|
+
- **AvatarView** - 3D rendering view (internally contains AvatarController)
|
|
79
|
+
- **AvatarController** - Real-time communication and data processing
|
|
80
|
+
- **AvatarCoreAdapter** - WASM module adapter
|
|
81
|
+
|
|
82
|
+
### Data Flow
|
|
79
83
|
|
|
80
84
|
```
|
|
81
|
-
|
|
85
|
+
User audio input (16kHz mono PCM) → AvatarController → WebSocket → Backend processing
|
|
82
86
|
↓
|
|
83
|
-
|
|
87
|
+
Backend returns animation data (FLAME keyframes) → AvatarController → AnimationPlayer
|
|
84
88
|
↓
|
|
85
|
-
FLAME
|
|
89
|
+
FLAME parameters → AvatarCore.computeFrameFlatFromParams() → Splat data
|
|
86
90
|
↓
|
|
87
|
-
Splat
|
|
91
|
+
Splat data → RenderSystem → WebGPU/WebGL → Canvas rendering
|
|
88
92
|
```
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
**Note:** Users need to provide audio data themselves (16kHz mono PCM), SDK handles receiving animation data and rendering.
|
|
91
95
|
|
|
92
|
-
## 📚 API
|
|
96
|
+
## 📚 API Reference
|
|
93
97
|
|
|
94
98
|
### AvatarKit
|
|
95
99
|
|
|
96
|
-
SDK
|
|
100
|
+
The core management class of the SDK, responsible for initialization and global configuration.
|
|
97
101
|
|
|
98
102
|
```typescript
|
|
99
|
-
//
|
|
103
|
+
// Initialize SDK
|
|
100
104
|
await AvatarKit.initialize(appId: string, configuration: Configuration)
|
|
101
105
|
|
|
102
|
-
//
|
|
106
|
+
// Check initialization status
|
|
103
107
|
const isInitialized = AvatarKit.isInitialized
|
|
104
108
|
|
|
105
|
-
//
|
|
109
|
+
// Cleanup resources (must be called when no longer in use)
|
|
106
110
|
AvatarKit.cleanup()
|
|
107
111
|
```
|
|
108
112
|
|
|
109
113
|
### AvatarManager
|
|
110
114
|
|
|
111
|
-
|
|
115
|
+
Character resource manager, responsible for downloading, caching, and loading character data.
|
|
112
116
|
|
|
113
117
|
```typescript
|
|
114
118
|
const manager = new AvatarManager()
|
|
115
119
|
|
|
116
|
-
//
|
|
120
|
+
// Load character
|
|
117
121
|
const avatar = await manager.load(
|
|
118
122
|
characterId: string,
|
|
119
123
|
onProgress?: (progress: LoadProgressInfo) => void
|
|
120
124
|
)
|
|
121
125
|
|
|
122
|
-
//
|
|
126
|
+
// Clear cache
|
|
123
127
|
manager.clearCache()
|
|
124
128
|
```
|
|
125
129
|
|
|
126
130
|
### AvatarView
|
|
127
131
|
|
|
128
|
-
3D
|
|
132
|
+
3D rendering view, internally automatically creates and manages AvatarController.
|
|
133
|
+
|
|
134
|
+
**⚠️ Important Limitation:** Currently, the SDK only supports one AvatarView instance at a time. If you need to switch characters, you must first call the `dispose()` method to clean up the current AvatarView, then create a new instance.
|
|
129
135
|
|
|
130
136
|
```typescript
|
|
131
|
-
//
|
|
137
|
+
// Create view (Canvas is automatically added to container)
|
|
132
138
|
const avatarView = new AvatarView(avatar: Avatar, container?: HTMLElement)
|
|
133
139
|
|
|
134
|
-
//
|
|
140
|
+
// Get Canvas element
|
|
135
141
|
const canvas = avatarView.getCanvas()
|
|
136
142
|
|
|
137
|
-
//
|
|
143
|
+
// Set background
|
|
138
144
|
avatarView.setBackgroundImage('path/to/image.jpg')
|
|
139
145
|
avatarView.setBackgroundOpaque(true)
|
|
140
146
|
|
|
141
|
-
//
|
|
147
|
+
// Update camera configuration
|
|
142
148
|
avatarView.updateCameraConfig(cameraConfig: CameraConfig)
|
|
143
149
|
|
|
144
|
-
//
|
|
150
|
+
// Cleanup resources (must be called before switching characters)
|
|
145
151
|
avatarView.dispose()
|
|
146
152
|
```
|
|
147
153
|
|
|
154
|
+
**Character Switching Example:**
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// Before switching characters, must clean up old AvatarView first
|
|
158
|
+
if (currentAvatarView) {
|
|
159
|
+
currentAvatarView.dispose()
|
|
160
|
+
currentAvatarView = null
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Load new character
|
|
164
|
+
const newAvatar = await avatarManager.load('new-character-id')
|
|
165
|
+
|
|
166
|
+
// Create new AvatarView
|
|
167
|
+
currentAvatarView = new AvatarView(newAvatar, container)
|
|
168
|
+
await currentAvatarView.avatarController.start()
|
|
169
|
+
```
|
|
170
|
+
|
|
148
171
|
### AvatarController
|
|
149
172
|
|
|
150
|
-
|
|
173
|
+
Real-time communication controller, handles WebSocket connections and animation data.
|
|
151
174
|
|
|
152
175
|
```typescript
|
|
153
|
-
//
|
|
176
|
+
// Start connection
|
|
154
177
|
await avatarView.avatarController.start()
|
|
155
178
|
|
|
156
|
-
//
|
|
179
|
+
// Send audio data
|
|
157
180
|
avatarView.avatarController.send(audioData: ArrayBuffer, end: boolean)
|
|
158
|
-
// audioData:
|
|
159
|
-
// end: false
|
|
160
|
-
// end: true -
|
|
181
|
+
// audioData: Audio data (ArrayBuffer format)
|
|
182
|
+
// end: false (default) - Normal audio data sending, server will accumulate audio data, automatically returns animation data and starts synchronized playback of animation and audio after accumulating enough data
|
|
183
|
+
// end: true - Immediately return animation data, no longer accumulating, used for ending current conversation or scenarios requiring immediate response
|
|
161
184
|
|
|
162
|
-
//
|
|
185
|
+
// Interrupt conversation
|
|
163
186
|
avatarView.avatarController.interrupt()
|
|
164
187
|
|
|
165
|
-
//
|
|
188
|
+
// Close connection
|
|
166
189
|
avatarView.avatarController.close()
|
|
167
190
|
|
|
168
|
-
//
|
|
191
|
+
// Set event callbacks
|
|
169
192
|
avatarView.avatarController.onConnectionState = (state: ConnectionState) => {}
|
|
170
193
|
avatarView.avatarController.onAvatarState = (state: AvatarState) => {}
|
|
171
194
|
avatarView.avatarController.onError = (error: Error) => {}
|
|
172
195
|
|
|
173
|
-
//
|
|
196
|
+
// Note: sendText() method is not supported, calling it will throw an error
|
|
174
197
|
```
|
|
175
198
|
|
|
176
|
-
## 🔧
|
|
199
|
+
## 🔧 Configuration
|
|
177
200
|
|
|
178
201
|
### Configuration
|
|
179
202
|
|
|
@@ -183,14 +206,15 @@ interface Configuration {
|
|
|
183
206
|
}
|
|
184
207
|
```
|
|
185
208
|
|
|
186
|
-
|
|
187
|
-
- `environment`:
|
|
188
|
-
- `sessionToken`:
|
|
209
|
+
**Description:**
|
|
210
|
+
- `environment`: Specifies the environment (cn/us/test), SDK will automatically use the corresponding API address and WebSocket address based on the environment
|
|
211
|
+
- `sessionToken`: Set separately via `AvatarKit.setSessionToken()`, not in Configuration
|
|
189
212
|
|
|
213
|
+
```typescript
|
|
190
214
|
enum Environment {
|
|
191
|
-
cn = 'cn', //
|
|
192
|
-
us = 'us', //
|
|
193
|
-
test = 'test' //
|
|
215
|
+
cn = 'cn', // China region
|
|
216
|
+
us = 'us', // US region
|
|
217
|
+
test = 'test' // Test environment
|
|
194
218
|
}
|
|
195
219
|
```
|
|
196
220
|
|
|
@@ -198,17 +222,17 @@ enum Environment {
|
|
|
198
222
|
|
|
199
223
|
```typescript
|
|
200
224
|
interface CameraConfig {
|
|
201
|
-
position: [number, number, number] //
|
|
202
|
-
target: [number, number, number] //
|
|
203
|
-
fov: number //
|
|
204
|
-
near: number //
|
|
205
|
-
far: number //
|
|
206
|
-
up?: [number, number, number] //
|
|
207
|
-
aspect?: number //
|
|
225
|
+
position: [number, number, number] // Camera position
|
|
226
|
+
target: [number, number, number] // Camera target
|
|
227
|
+
fov: number // Field of view angle
|
|
228
|
+
near: number // Near clipping plane
|
|
229
|
+
far: number // Far clipping plane
|
|
230
|
+
up?: [number, number, number] // Up direction
|
|
231
|
+
aspect?: number // Aspect ratio
|
|
208
232
|
}
|
|
209
233
|
```
|
|
210
234
|
|
|
211
|
-
## 📊
|
|
235
|
+
## 📊 State Management
|
|
212
236
|
|
|
213
237
|
### ConnectionState
|
|
214
238
|
|
|
@@ -225,77 +249,77 @@ enum ConnectionState {
|
|
|
225
249
|
|
|
226
250
|
```typescript
|
|
227
251
|
enum AvatarState {
|
|
228
|
-
idle = 'idle', //
|
|
229
|
-
active = 'active', //
|
|
230
|
-
playing = 'playing' //
|
|
252
|
+
idle = 'idle', // Idle state, showing breathing animation
|
|
253
|
+
active = 'active', // Active, waiting for playable content
|
|
254
|
+
playing = 'playing' // Playing
|
|
231
255
|
}
|
|
232
256
|
```
|
|
233
257
|
|
|
234
|
-
## 🎨
|
|
258
|
+
## 🎨 Rendering System
|
|
235
259
|
|
|
236
|
-
SDK
|
|
260
|
+
The SDK supports two rendering backends:
|
|
237
261
|
|
|
238
|
-
- **WebGPU** -
|
|
239
|
-
- **WebGL** -
|
|
262
|
+
- **WebGPU** - High-performance rendering for modern browsers
|
|
263
|
+
- **WebGL** - Better compatibility traditional rendering
|
|
240
264
|
|
|
241
|
-
|
|
265
|
+
The rendering system automatically selects the best backend, no manual configuration needed.
|
|
242
266
|
|
|
243
|
-
## 🔍
|
|
267
|
+
## 🔍 Debugging and Monitoring
|
|
244
268
|
|
|
245
|
-
###
|
|
269
|
+
### Logging System
|
|
246
270
|
|
|
247
|
-
SDK
|
|
271
|
+
The SDK has a built-in complete logging system, supporting different levels of log output:
|
|
248
272
|
|
|
249
273
|
```typescript
|
|
250
274
|
import { logger } from '@spatialwalk/avatarkit'
|
|
251
275
|
|
|
252
|
-
//
|
|
276
|
+
// Set log level
|
|
253
277
|
logger.setLevel('verbose') // 'basic' | 'verbose'
|
|
254
278
|
|
|
255
|
-
//
|
|
279
|
+
// Manual log output
|
|
256
280
|
logger.log('Info message')
|
|
257
281
|
logger.warn('Warning message')
|
|
258
282
|
logger.error('Error message')
|
|
259
283
|
```
|
|
260
284
|
|
|
261
|
-
###
|
|
285
|
+
### Performance Monitoring
|
|
262
286
|
|
|
263
|
-
SDK
|
|
287
|
+
The SDK provides performance monitoring interfaces to monitor rendering performance:
|
|
264
288
|
|
|
265
289
|
```typescript
|
|
266
|
-
//
|
|
290
|
+
// Get rendering performance statistics
|
|
267
291
|
const stats = avatarView.getPerformanceStats()
|
|
268
292
|
|
|
269
293
|
if (stats) {
|
|
270
|
-
console.log(
|
|
271
|
-
console.log(
|
|
272
|
-
console.log(
|
|
294
|
+
console.log(`Render time: ${stats.renderTime.toFixed(2)}ms`)
|
|
295
|
+
console.log(`Sort time: ${stats.sortTime.toFixed(2)}ms`)
|
|
296
|
+
console.log(`Rendering backend: ${stats.backend}`)
|
|
273
297
|
|
|
274
|
-
//
|
|
298
|
+
// Calculate frame rate
|
|
275
299
|
const fps = 1000 / stats.renderTime
|
|
276
|
-
console.log(
|
|
300
|
+
console.log(`Frame rate: ${fps.toFixed(2)} FPS`)
|
|
277
301
|
}
|
|
278
302
|
|
|
279
|
-
//
|
|
303
|
+
// Regular performance monitoring
|
|
280
304
|
setInterval(() => {
|
|
281
305
|
const stats = avatarView.getPerformanceStats()
|
|
282
306
|
if (stats) {
|
|
283
|
-
//
|
|
307
|
+
// Send to monitoring service or display on UI
|
|
284
308
|
console.log('Performance:', stats)
|
|
285
309
|
}
|
|
286
310
|
}, 1000)
|
|
287
311
|
```
|
|
288
312
|
|
|
289
|
-
|
|
290
|
-
- `renderTime`:
|
|
291
|
-
- `sortTime`:
|
|
292
|
-
- `backend`:
|
|
313
|
+
**Performance Statistics Description:**
|
|
314
|
+
- `renderTime`: Total rendering time (milliseconds), includes sorting and GPU rendering
|
|
315
|
+
- `sortTime`: Sorting time (milliseconds), uses Radix Sort algorithm to depth-sort point cloud
|
|
316
|
+
- `backend`: Currently used rendering backend (`'webgpu'` | `'webgl'` | `null`)
|
|
293
317
|
|
|
294
|
-
## 🚨
|
|
318
|
+
## 🚨 Error Handling
|
|
295
319
|
|
|
296
320
|
### SPAvatarError
|
|
297
321
|
|
|
298
|
-
SDK
|
|
322
|
+
The SDK uses custom error types, providing more detailed error information:
|
|
299
323
|
|
|
300
324
|
```typescript
|
|
301
325
|
import { SPAvatarError } from '@spatialwalk/avatarkit'
|
|
@@ -311,65 +335,70 @@ try {
|
|
|
311
335
|
}
|
|
312
336
|
```
|
|
313
337
|
|
|
314
|
-
###
|
|
338
|
+
### Error Callbacks
|
|
315
339
|
|
|
316
340
|
```typescript
|
|
317
341
|
avatarView.avatarController.onError = (error: Error) => {
|
|
318
342
|
console.error('AvatarController error:', error)
|
|
319
|
-
//
|
|
343
|
+
// Handle error, such as reconnection, user notification, etc.
|
|
320
344
|
}
|
|
321
345
|
```
|
|
322
346
|
|
|
323
|
-
## 🔄
|
|
347
|
+
## 🔄 Resource Management
|
|
324
348
|
|
|
325
|
-
###
|
|
349
|
+
### Lifecycle Management
|
|
326
350
|
|
|
327
351
|
```typescript
|
|
328
|
-
//
|
|
352
|
+
// Initialize
|
|
329
353
|
const avatarView = new AvatarView(avatar, container)
|
|
330
354
|
await avatarView.avatarController.start()
|
|
331
355
|
|
|
332
|
-
//
|
|
356
|
+
// Use
|
|
333
357
|
avatarView.avatarController.send(audioData, false)
|
|
334
358
|
|
|
335
|
-
//
|
|
336
|
-
avatarView.dispose() //
|
|
359
|
+
// Cleanup (must be called before switching characters)
|
|
360
|
+
avatarView.dispose() // Automatically cleans up all resources
|
|
337
361
|
```
|
|
338
362
|
|
|
339
|
-
|
|
363
|
+
**⚠️ Important Notes:**
|
|
364
|
+
- SDK currently only supports one AvatarView instance at a time
|
|
365
|
+
- When switching characters, must first call `dispose()` to clean up old AvatarView, then create new instance
|
|
366
|
+
- Not properly cleaning up may cause resource leaks and rendering errors
|
|
367
|
+
|
|
368
|
+
### Memory Optimization
|
|
340
369
|
|
|
341
|
-
- SDK
|
|
342
|
-
-
|
|
343
|
-
-
|
|
370
|
+
- SDK automatically manages WASM memory allocation
|
|
371
|
+
- Supports dynamic loading/unloading of character and animation resources
|
|
372
|
+
- Provides memory usage monitoring interface
|
|
344
373
|
|
|
345
|
-
###
|
|
374
|
+
### Audio Data Sending
|
|
346
375
|
|
|
347
|
-
`send()`
|
|
376
|
+
The `send()` method receives audio data in `ArrayBuffer` format:
|
|
348
377
|
|
|
349
|
-
|
|
350
|
-
- `audioData`:
|
|
351
|
-
- `end=false
|
|
352
|
-
- `end=true` -
|
|
353
|
-
-
|
|
378
|
+
**Usage:**
|
|
379
|
+
- `audioData`: Audio data (ArrayBuffer format)
|
|
380
|
+
- `end=false` (default) - Normal audio data sending, server will accumulate audio data, automatically returns animation data and starts synchronized playback of animation and audio after accumulating enough data
|
|
381
|
+
- `end=true` - Immediately return animation data, no longer accumulating, used for ending current conversation or scenarios requiring immediate response
|
|
382
|
+
- **Important**: No need to wait for `end=true` to start playing, it will automatically start playing after accumulating enough audio data
|
|
354
383
|
|
|
355
|
-
## 🌐
|
|
384
|
+
## 🌐 Browser Compatibility
|
|
356
385
|
|
|
357
|
-
- **Chrome/Edge** 90+ (
|
|
386
|
+
- **Chrome/Edge** 90+ (WebGPU recommended)
|
|
358
387
|
- **Firefox** 90+ (WebGL)
|
|
359
388
|
- **Safari** 14+ (WebGL)
|
|
360
|
-
-
|
|
389
|
+
- **Mobile** iOS 14+, Android 8+
|
|
361
390
|
|
|
362
|
-
## 📝
|
|
391
|
+
## 📝 License
|
|
363
392
|
|
|
364
393
|
MIT License
|
|
365
394
|
|
|
366
|
-
## 🤝
|
|
395
|
+
## 🤝 Contributing
|
|
367
396
|
|
|
368
|
-
|
|
397
|
+
Issues and Pull Requests are welcome!
|
|
369
398
|
|
|
370
|
-
## 📞
|
|
399
|
+
## 📞 Support
|
|
371
400
|
|
|
372
|
-
|
|
373
|
-
-
|
|
374
|
-
-
|
|
375
|
-
- GitHub
|
|
401
|
+
For questions, please contact:
|
|
402
|
+
- Email: support@spavatar.com
|
|
403
|
+
- Documentation: https://docs.spavatar.com
|
|
404
|
+
- GitHub: https://github.com/spavatar/sdk
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var c = Object.defineProperty;
|
|
2
2
|
var g = (h, t, e) => t in h ? c(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
|
|
3
3
|
var s = (h, t, e) => g(h, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
import { l
|
|
4
|
+
import { l } from "./index-NmYXWJnL.js";
|
|
5
5
|
class k {
|
|
6
6
|
constructor(t) {
|
|
7
7
|
// AudioContext is managed internally
|
|
@@ -48,7 +48,7 @@ class k {
|
|
|
48
48
|
*/
|
|
49
49
|
addChunk(t, e = !1) {
|
|
50
50
|
if (!this.audioContext) {
|
|
51
|
-
|
|
51
|
+
l.error("AudioContext not initialized");
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
this.audioChunks.push({ data: t, isLast: e }), this.log(`Added chunk ${this.audioChunks.length}`, {
|
|
@@ -117,9 +117,9 @@ class k {
|
|
|
117
117
|
this.scheduledChunks++;
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
const
|
|
120
|
+
const r = e.data, d = e.isLast, n = this.pcmToAudioBuffer(r);
|
|
121
121
|
if (!n) {
|
|
122
|
-
|
|
122
|
+
l.error("Failed to create AudioBuffer from PCM data");
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
try {
|
|
@@ -135,7 +135,7 @@ class k {
|
|
|
135
135
|
activeSources: this.activeSources.length
|
|
136
136
|
});
|
|
137
137
|
} catch (i) {
|
|
138
|
-
|
|
138
|
+
l.errorWithError("Failed to schedule audio chunk:", i);
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
@@ -155,7 +155,7 @@ class k {
|
|
|
155
155
|
a.getChannelData(o).fill(0);
|
|
156
156
|
return a;
|
|
157
157
|
}
|
|
158
|
-
const e = new Uint8Array(t),
|
|
158
|
+
const e = new Uint8Array(t), r = new Int16Array(e.buffer, 0, e.length / 2), d = r.length / this.channelCount, n = this.audioContext.createBuffer(
|
|
159
159
|
this.channelCount,
|
|
160
160
|
d,
|
|
161
161
|
this.sampleRate
|
|
@@ -164,7 +164,7 @@ class k {
|
|
|
164
164
|
const u = n.getChannelData(i);
|
|
165
165
|
for (let a = 0; a < d; a++) {
|
|
166
166
|
const o = a * this.channelCount + i;
|
|
167
|
-
u[a] =
|
|
167
|
+
u[a] = r[o] / 32768;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
return n;
|
|
@@ -205,12 +205,7 @@ class k {
|
|
|
205
205
|
*/
|
|
206
206
|
stop() {
|
|
207
207
|
if (this.audioContext) {
|
|
208
|
-
this.
|
|
209
|
-
isPlaying: this.isPlaying,
|
|
210
|
-
audioChunks: this.audioChunks.length,
|
|
211
|
-
scheduledChunks: this.scheduledChunks,
|
|
212
|
-
activeSources: this.activeSources.length
|
|
213
|
-
}), this.isPlaying = !1, this.isPaused = !1, this.sessionStartTime = 0, this.scheduledTime = 0;
|
|
208
|
+
this.isPlaying = !1, this.isPaused = !1, this.sessionStartTime = 0, this.scheduledTime = 0;
|
|
214
209
|
for (const t of this.activeSources) {
|
|
215
210
|
t.onended = null;
|
|
216
211
|
try {
|
|
@@ -284,10 +279,10 @@ class k {
|
|
|
284
279
|
* Debug logging
|
|
285
280
|
*/
|
|
286
281
|
log(t, e) {
|
|
287
|
-
this.debug &&
|
|
282
|
+
this.debug && l.log(`[StreamingAudioPlayer] ${t}`, e || "");
|
|
288
283
|
}
|
|
289
284
|
}
|
|
290
285
|
export {
|
|
291
286
|
k as StreamingAudioPlayer
|
|
292
287
|
};
|
|
293
|
-
//# sourceMappingURL=StreamingAudioPlayer-
|
|
288
|
+
//# sourceMappingURL=StreamingAudioPlayer-BeLlDiwE.js.map
|