@wq-hook/volcano-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @wq-hook/volcano-react
2
+
3
+ 火山引擎 ASR & TTS 的 React 封装库,提供了一套易用的 Hooks 和组件,帮助开发者快速在 React 应用中集成语音能力。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add @wq-hook/volcano-react
9
+ ```
10
+
11
+ ## 核心 Hooks
12
+
13
+ ### 1. `useMessageTTS`
14
+
15
+ 用于文本转语音(TTS)的高级 Hook,支持流式播放、自动缓存、降级策略和音频可视化。
16
+
17
+ **特性**:
18
+ - **流式合成**:利用 WebSocket 实现低延迟流式播放。
19
+ - **多级缓存**:内置内存和 IndexedDB 缓存,相同的文本和参数不会重复请求。
20
+ - **自动降级**:如果火山引擎服务不可用,自动降级到浏览器原生的 `SpeechSynthesis`。
21
+ - **可视化支持**:提供 `getFrequencyData` 和 `getTimeDomainData` 方法用于绘制波形。
22
+
23
+ **使用示例**:
24
+
25
+ ```tsx
26
+ import { useMessageTTS } from '@wq-hook/volcano-react';
27
+
28
+ const MyComponent = () => {
29
+ const { play, stop, isPlaying, isSynthesizing } = useMessageTTS({
30
+ ttsConfig: {
31
+ appid: 'YOUR_APPID',
32
+ token: 'YOUR_TOKEN',
33
+ uid: 'user-1'
34
+ },
35
+ audioParams: {
36
+ speaker: 'zh_female_vv_uranus_bigtts', // 发音人
37
+ speech_rate: 1.0, // 语速
38
+ }
39
+ });
40
+
41
+ return (
42
+ <div>
43
+ <button onClick={() => play("你好,这是一个测试文本。")}>播放</button>
44
+ <button onClick={stop}>停止</button>
45
+ {isPlaying && <p>正在播放...</p>}
46
+ {isSynthesizing && <p>正在合成...</p>}
47
+ </div>
48
+ );
49
+ };
50
+ ```
51
+
52
+ ### 2. `useVolcanoASR`
53
+
54
+ 用于实时语音识别(ASR)的 Hook,支持麦克风录音并实时转换为文本。
55
+
56
+ **使用示例**:
57
+
58
+ ```tsx
59
+ import { useVolcanoASR } from '@wq-hook/volcano-react';
60
+
61
+ const ASRComponent = () => {
62
+ const { start, stop, result, status } = useVolcanoASR({
63
+ config: {
64
+ appId: 'YOUR_APPID',
65
+ token: 'YOUR_TOKEN',
66
+ uid: 'user-1'
67
+ }
68
+ });
69
+
70
+ return (
71
+ <div>
72
+ <button onClick={start}>开始录音</button>
73
+ <button onClick={stop}>停止录音</button>
74
+ <p>状态: {status}</p>
75
+ <p>识别结果: {result}</p>
76
+ </div>
77
+ );
78
+ };
79
+ ```
80
+
81
+ ## 组件
82
+
83
+ ### `AudioWaveVisualizer`
84
+
85
+ 一个用于显示音频波形的 Canvas 组件。
86
+
87
+ ```tsx
88
+ import { AudioWaveVisualizer } from '@wq-hook/volcano-react';
89
+
90
+ // 在使用 useMessageTTS 的组件中
91
+ <AudioWaveVisualizer
92
+ width={300}
93
+ height={100}
94
+ barWidth={2}
95
+ gap={1}
96
+ barColor="#4F46E5"
97
+ getFrequencyData={getFrequencyData} // 来自 useMessageTTS
98
+ />
99
+ ```
100
+
101
+ ## 配置说明
102
+
103
+ ### UseTTSParams
104
+
105
+ | 参数 | 类型 | 说明 |
106
+ |------|------|------|
107
+ | `ttsConfig` | `TTSConfig` | 火山引擎鉴权配置 (appid, token, etc.) |
108
+ | `audioParams` | `AudioParams` | 音频参数 (speaker, speech_rate, etc.) |
109
+ | `autoPlay` | `boolean` | 合成收到数据后是否自动播放,默认为 `true` |
110
+ | `exclusive` | `boolean` | 是否互斥播放(播放时暂停其他实例),默认为 `true` |
111
+ | `fallbackVoice` | `string` | 备用音色 ID,当主音色失败时尝试 |
112
+
@@ -0,0 +1,358 @@
1
+ import { WebsocketMSE } from '@wq-hook/volcano-sdk/tts';
2
+ import React$1 from 'react';
3
+
4
+ type ASRStatus = 'idle' | 'connecting' | 'recording' | 'error';
5
+ interface ASRHookParams {
6
+ /** 应用 ID */
7
+ appId: string;
8
+ /** 访问令牌 */
9
+ token: string;
10
+ }
11
+ interface ASRHookReturn {
12
+ status: ASRStatus;
13
+ text: string;
14
+ error: string | null;
15
+ start: () => Promise<void>;
16
+ stop: () => void;
17
+ }
18
+
19
+ declare function useVolcanoASR(params: ASRHookParams): ASRHookReturn;
20
+
21
+ /**
22
+ * useVTS Hook 类型定义
23
+ *
24
+ * 本文件定义了 useVTS Hook 所需的所有 TypeScript 类型接口
25
+ */
26
+
27
+ /**
28
+ * TTS 实例类型
29
+ */
30
+ type TTSInstance = typeof WebsocketMSE;
31
+ /**
32
+ * TTS 配置接口
33
+ *
34
+ * @description 定义 TTS 服务的鉴权和配置信息
35
+ */
36
+ interface TTSConfig {
37
+ /** 应用 ID */
38
+ appid: string;
39
+ /** JWT Token(需要从服务端获取) */
40
+ token: string;
41
+ /** 音色服务 ID(可选,克隆音色需要) */
42
+ resourceId?: string;
43
+ /** 命名空间(可选) */
44
+ namespace?: string;
45
+ }
46
+ /**
47
+ * useVolcanoTTS Hook 参数接口
48
+ *
49
+ * @description 定义 useVolcanoTTS Hook 的参数结构
50
+ */
51
+ interface UseTTSParams {
52
+ /** TTS 配置 */
53
+ ttsConfig: TTSConfig;
54
+ /** 音频参数(可选) */
55
+ audioParams?: AudioParams;
56
+ }
57
+ /**
58
+ * 鉴权参数接口
59
+ *
60
+ * @description 定义 WebSocket 连接的鉴权参数
61
+ */
62
+ interface AuthParams {
63
+ /** API 资源 ID */
64
+ api_resource_id?: string;
65
+ /** API 应用密钥 */
66
+ api_app_key?: string;
67
+ /** JWT Token,格式为 `Jwt; {token}` */
68
+ api_access_key?: string;
69
+ }
70
+ /**
71
+ * 音频参数接口
72
+ *
73
+ * @description 定义音频合成的参数配置
74
+ */
75
+ interface AudioParams {
76
+ /** 发音人(如 zh_female_vv_uranus_bigtts) */
77
+ speaker?: string;
78
+ /** 音频格式(如 mp3, wav) */
79
+ format?: string;
80
+ /** 采样率(如 24000, 16000) */
81
+ sample_rate?: number;
82
+ /** 语速(可选) */
83
+ speech_rate?: number;
84
+ /** 音调(可选) */
85
+ pitch_rate?: number;
86
+ /** 音量(可选) */
87
+ loudness_rate?: number;
88
+ }
89
+ /**
90
+ * 消息状态类型
91
+ *
92
+ * @description 定义 TTS 消息的生命周期状态
93
+ */
94
+ type MessageStatus = 'pending' | 'synthesizing' | 'playing' | 'completed' | 'error';
95
+ /**
96
+ * TTS 消息接口
97
+ *
98
+ * @description 定义单条 TTS 消息的数据结构
99
+ */
100
+ interface TTSMessage {
101
+ /** 消息唯一标识 */
102
+ id: string;
103
+ /** 文本内容 */
104
+ text: string;
105
+ /** 消息状态 */
106
+ status: MessageStatus;
107
+ /** MediaSource URL(可选) */
108
+ audioUrl?: string;
109
+ /** 错误信息(可选) */
110
+ error?: string;
111
+ /** TTS 实例(可选) */
112
+ instance?: ReturnType<typeof WebsocketMSE>;
113
+ }
114
+ /**
115
+ * Hook 配置选项接口
116
+ *
117
+ * @description 定义 useVTS Hook 的配置选项
118
+ */
119
+ interface UseVTSOptions {
120
+ /** TTS 配置 */
121
+ tts: TTSConfig;
122
+ /** 音频参数 */
123
+ audio: AudioParams;
124
+ /** 模式:队列模式或并发模式 */
125
+ mode?: 'queue' | 'concurrent';
126
+ /** 是否自动播放 */
127
+ autoPlay?: boolean;
128
+ /** 最大并发数(仅并发模式有效) */
129
+ maxConcurrent?: number;
130
+ /** 消息开始回调 */
131
+ onMessageStart?: (id: string, text: string) => void;
132
+ /** 消息结束回调 */
133
+ onMessageEnd?: (id: string) => void;
134
+ /** 错误回调 */
135
+ onError?: (id: string, error: string) => void;
136
+ }
137
+ /**
138
+ * Hook 连接状态类型
139
+ *
140
+ * @description 定义 Hook 的连接状态
141
+ */
142
+ type ConnectionStatus = 'idle' | 'connecting' | 'connected' | 'session-started' | 'error';
143
+ /**
144
+ * Hook 返回类型
145
+ *
146
+ * @description 定义 useVTS Hook 的返回值
147
+ */
148
+ interface UseVTSReturn {
149
+ /** 连接状态 */
150
+ status: ConnectionStatus;
151
+ /** 错误信息 */
152
+ error: string | null;
153
+ /** 当前播放的消息 ID */
154
+ currentMessageId?: string;
155
+ /** 连接方法,返回 audioUrl */
156
+ connect: () => Promise<string>;
157
+ /** 断开连接方法 */
158
+ disconnect: () => void;
159
+ /** 添加消息方法 */
160
+ addMessage: (id: string, text: string) => void;
161
+ /** 发送文本方法 */
162
+ sendText: (id: string, text: string) => void;
163
+ /** 结束会话方法 */
164
+ finishSession: () => void;
165
+ /** 播放音频方法(实现互斥播放) */
166
+ playAudio: (id: string, audioUrl: string) => void;
167
+ /** 配置选项 */
168
+ config: UseVTSOptions;
169
+ }
170
+
171
+ declare function useVolcanoTTS({ ttsConfig, audioParams, }: UseTTSParams): {
172
+ status: ConnectionStatus;
173
+ error: string | null;
174
+ connect: () => Promise<string>;
175
+ disconnect: () => void;
176
+ startSession: () => void;
177
+ finishSession: () => void;
178
+ sendText: (text: string) => Promise<void>;
179
+ };
180
+
181
+ interface TTSMetric {
182
+ name: 'tts_request' | 'tts_latency' | 'tts_cache_hit' | 'tts_error';
183
+ labels: {
184
+ voice?: string;
185
+ speed?: number;
186
+ text_length?: number;
187
+ error_code?: string;
188
+ stage?: 'synthesis' | 'first_packet' | 'playback';
189
+ [key: string]: any;
190
+ };
191
+ value: number;
192
+ timestamp: number;
193
+ }
194
+ interface MetricsCollector {
195
+ record(metric: TTSMetric): void;
196
+ }
197
+
198
+ interface UseMessageTTSParams {
199
+ /** TTS配置(与现有useVolcanoTTS保持一致) */
200
+ ttsConfig: TTSConfig;
201
+ /** 音频参数(可选) */
202
+ audioParams?: AudioParams;
203
+ /** 是否自动播放(默认:true) */
204
+ autoPlay?: boolean;
205
+ /** 指标收集器(可选) */
206
+ metricsCollector?: MetricsCollector;
207
+ /** 播放开始回调 */
208
+ onPlayStart?: () => void;
209
+ /** 播放暂停回调 */
210
+ onPlayPause?: () => void;
211
+ /** 播放恢复回调 */
212
+ onPlayResume?: () => void;
213
+ /** 播放结束回调 */
214
+ onPlayEnd?: () => void;
215
+ /** 播放错误回调 */
216
+ onError?: (error: Error) => void;
217
+ /** 互斥播放控制(默认:true) */
218
+ exclusive?: boolean;
219
+ /** 备用音色(可选,当主音色失败时尝试,再次失败则降级到离线语音) */
220
+ fallbackVoice?: string;
221
+ /** 可视化配置 */
222
+ visualization?: VisualizationConfig;
223
+ }
224
+ interface VisualizationConfig {
225
+ /** 是否开启可视化数据自动更新 */
226
+ enabled: boolean;
227
+ /** 更新频率(毫秒),默认跟随 requestAnimationFrame */
228
+ refreshInterval?: number;
229
+ /** FFT 大小,必须是 2 的幂次方,默认 256 */
230
+ fftSize?: number;
231
+ }
232
+ interface VisualizationData {
233
+ frequencyData: Uint8Array;
234
+ timeDomainData: Uint8Array;
235
+ }
236
+ interface UseMessageTTSReturn {
237
+ /** 播放状态 */
238
+ isPlaying: boolean;
239
+ /** 暂停状态 */
240
+ isPaused: boolean;
241
+ /** 设置播放进度(0-100) */
242
+ seek: (percentage: number) => void;
243
+ /** 是否正在合成 */
244
+ isSynthesizing: boolean;
245
+ /** 错误信息 */
246
+ error: string | null;
247
+ /** 播放进度(0-1) */
248
+ progress: number;
249
+ /** 播放文本方法 */
250
+ play: (text: string) => Promise<void>;
251
+ /** 暂停播放方法 */
252
+ pause: () => void;
253
+ /** 恢复播放方法 */
254
+ resume: () => void;
255
+ /** 停止播放方法 */
256
+ stop: () => void;
257
+ /** 切换播放/暂停方法 */
258
+ togglePlay: () => void;
259
+ /** 获取音浪频率数据(用于可视化) */
260
+ getFrequencyData: () => Uint8Array;
261
+ /** 获取音浪时域数据(用于可视化) */
262
+ getTimeDomainData: () => Uint8Array;
263
+ /** 实时可视化数据(仅当 visualization.enabled 为 true 时更新) */
264
+ visualizationData: VisualizationData;
265
+ }
266
+
267
+ declare function useMessageTTS({ ttsConfig, audioParams, autoPlay, metricsCollector, onPlayStart, onPlayPause, onPlayResume, onPlayEnd, onError, exclusive, fallbackVoice, visualization, }: UseMessageTTSParams): UseMessageTTSReturn;
268
+
269
+ /**
270
+ * TextSplitter 类型声明
271
+ *
272
+ * @description
273
+ * TextSplitter 模块的所有类型定义,与实现代码分离
274
+ */
275
+ /**
276
+ * 文本分段接口
277
+ *
278
+ * @description
279
+ * 定义分割后的文本段结构,用于处理长文本分段
280
+ */
281
+ interface TextSegment {
282
+ /** 分段索引 */
283
+ index: number;
284
+ /** 分段内容 */
285
+ content: string;
286
+ /** 字符长度 */
287
+ length: number;
288
+ /** 是否已发送 */
289
+ sent?: boolean;
290
+ /** 发送时间戳 */
291
+ sentAt?: number;
292
+ }
293
+
294
+ /**
295
+ * 文本分段
296
+ */
297
+
298
+ /**
299
+ * 智能分段文本 - 根据语义、标点符号进行分段,优化并行请求
300
+ *
301
+ * @param text - 原始文本
302
+ * @param minLength - 单段最小字符数(默认10,避免过碎)
303
+ * @param maxLength - 单段最大字符数(默认150,平衡并发请求)
304
+ * @returns 文本分段数组
305
+ */
306
+ declare function splitTextByDelimiters(text: string, minLength?: number, maxLength?: number): TextSegment[];
307
+
308
+ interface AudioWaveVisualizerProps {
309
+ /** 是否正在播放 */
310
+ isPlaying: boolean;
311
+ /** 是否暂停 */
312
+ isPaused: boolean;
313
+ /** 音频频率数据(来自Web Audio API) */
314
+ frequencyData?: Uint8Array;
315
+ /** 音频时域数据(来自Web Audio API) */
316
+ timeDomainData?: Uint8Array;
317
+ /** 波形样式:'bar' | 'line' | 'circle' | 'wave' */
318
+ style?: 'bar' | 'line' | 'circle' | 'wave';
319
+ /** 颜色主题(支持渐变) */
320
+ color?: string | [string, string];
321
+ /** 波形条数 */
322
+ bars?: number;
323
+ /** 高度(px) */
324
+ height?: number;
325
+ /** 宽度(px) */
326
+ width?: number;
327
+ /** 自定义类名 */
328
+ className?: string;
329
+ /** 自定义样式 */
330
+ styleObj?: React.CSSProperties;
331
+ }
332
+
333
+ declare const AudioWaveVisualizer: React$1.FC<AudioWaveVisualizerProps>;
334
+
335
+ interface AudioProgressBarProps {
336
+ /** 播放进度(0-100) */
337
+ progress: number;
338
+ /** 宽度(px 或百分比) */
339
+ width?: number | string;
340
+ /** 高度(px) */
341
+ height?: number;
342
+ /** 颜色主题(支持渐变) */
343
+ color?: string | [string, string];
344
+ /** 背景颜色 */
345
+ backgroundColor?: string;
346
+ /** 是否显示百分比文本 */
347
+ showText?: boolean;
348
+ /** 进度改变回调 */
349
+ onSeek?: (progress: number) => void;
350
+ /** 自定义类名 */
351
+ className?: string;
352
+ /** 自定义样式 */
353
+ style?: React.CSSProperties;
354
+ }
355
+
356
+ declare const AudioProgressBar: React$1.FC<AudioProgressBarProps>;
357
+
358
+ export { type ASRHookParams, type ASRHookReturn, type ASRStatus, type AudioParams, AudioProgressBar, type AudioProgressBarProps, AudioWaveVisualizer, type AudioWaveVisualizerProps, type AuthParams, type ConnectionStatus, type MessageStatus, type TTSConfig, type TTSInstance, type TTSMessage, type TextSegment, type UseMessageTTSParams, type UseMessageTTSReturn, type UseTTSParams, type UseVTSOptions, type UseVTSReturn, type VisualizationConfig, type VisualizationData, splitTextByDelimiters, useMessageTTS, useVolcanoASR, useVolcanoTTS };