@vivix-ai/ivi-frontend-sdk 0.2.3 → 0.3.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 +166 -105
- package/dist/index.cjs +875 -381
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -37
- package/dist/index.d.ts +196 -37
- package/dist/index.js +868 -383
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -2,32 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
用于前端应用集成 IVI 实时能力的 TypeScript SDK,包含:
|
|
4
4
|
|
|
5
|
-
- 基于 `@vivix/ivi-sdk-ts` 的 runtime 协调层
|
|
5
|
+
- 基于 `@vivix-ai/ivi-sdk-ts` 的 runtime 协调层
|
|
6
6
|
- 面向舞台渲染的 React 组件与 hooks
|
|
7
7
|
|
|
8
8
|
## 安装依赖
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
当前包发布到 npm 官方仓库,包名为 `@vivix-ai/ivi-frontend-sdk`。
|
|
11
|
+
|
|
12
|
+
安装 SDK:
|
|
11
13
|
|
|
12
14
|
```bash
|
|
13
15
|
# npm
|
|
14
|
-
npm install
|
|
16
|
+
npm install @vivix-ai/ivi-frontend-sdk
|
|
15
17
|
|
|
16
18
|
# pnpm
|
|
17
|
-
pnpm add
|
|
19
|
+
pnpm add @vivix-ai/ivi-frontend-sdk
|
|
18
20
|
|
|
19
21
|
# yarn
|
|
20
|
-
yarn add
|
|
22
|
+
yarn add @vivix-ai/ivi-frontend-sdk
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
> **推荐使用 `#main` 分支。** `dev` 分支可能引入尚未稳定的新特性,不保证向后兼容;`main` 分支仅包含经过验证的变更。如需锁定到更精确的版本,可替换为具体 tag 或 commit hash。
|
|
24
|
-
|
|
25
25
|
安装后 `package.json` 中会出现类似条目:
|
|
26
26
|
|
|
27
27
|
```json
|
|
28
28
|
{
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@vivix/ivi-frontend-sdk": "
|
|
30
|
+
"@vivix-ai/ivi-frontend-sdk": "^0.3.0"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
```
|
|
@@ -35,19 +35,19 @@ yarn add git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#mai
|
|
|
35
35
|
**更新到最新版本**:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
# npm
|
|
39
|
-
npm
|
|
38
|
+
# npm
|
|
39
|
+
npm update @vivix-ai/ivi-frontend-sdk
|
|
40
40
|
|
|
41
41
|
# pnpm
|
|
42
|
-
pnpm
|
|
42
|
+
pnpm update @vivix-ai/ivi-frontend-sdk
|
|
43
43
|
|
|
44
|
-
#
|
|
45
|
-
|
|
44
|
+
# yarn
|
|
45
|
+
yarn up @vivix-ai/ivi-frontend-sdk
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
### `dist` 与
|
|
48
|
+
### `dist` 与 npm 发布
|
|
49
49
|
|
|
50
|
-
`package.json` 的 `main` / `module` / `types` / `exports` 均指向 `dist/`,且 npm 包通过 `"files": ["dist"]`
|
|
50
|
+
`package.json` 的 `main` / `module` / `types` / `exports` 均指向 `dist/`,且 npm 包通过 `"files": ["dist"]` 发布到 npm 官方仓库。因此发布前必须先完成构建,确保 npm 包包含可运行、可解析类型的产物。
|
|
51
51
|
|
|
52
52
|
**协作约定**:修改 `src/` 后必须在本地执行 `npm run build`(或 `pnpm run build`),并将**与本次源码变更对应的一次完整 `dist/` 输出**一并提交:可与功能改动放在**同一提交**,或在必要时单独提交,提交信息示例:`chore: 重新构建 dist`。禁止只改源码而不更新 `dist/`,避免仓库内源码与产物不一致。
|
|
53
53
|
|
|
@@ -64,34 +64,6 @@ React 为可选 peer dependency,仅使用 React 组件时需要:
|
|
|
64
64
|
|
|
65
65
|
如果只使用 runtime 能力、不接入 React 组件与 hooks,可忽略本文中的 React 用法部分。
|
|
66
66
|
|
|
67
|
-
## 包导出与导入方式
|
|
68
|
-
|
|
69
|
-
当前仅支持单一主入口:
|
|
70
|
-
|
|
71
|
-
| 入口 | 路径 | 说明 |
|
|
72
|
-
|------|------|------|
|
|
73
|
-
| 主入口 | `@vivix/ivi-frontend-sdk` | 导出 runtime 能力、`IviFrontendSdk`、以及当前公开的 React API:`IVIStageView`、`IVITrackSlot`、`useManagedIviRuntime`、`useIviStageView` |
|
|
74
|
-
|
|
75
|
-
**导入示例**:
|
|
76
|
-
|
|
77
|
-
```ts
|
|
78
|
-
// 底层 client 由 @vivix/ivi-sdk-ts 提供
|
|
79
|
-
import { IviClient } from "@vivix/ivi-sdk-ts";
|
|
80
|
-
|
|
81
|
-
// 本包主入口
|
|
82
|
-
import {
|
|
83
|
-
IviRuntimeCoordinator,
|
|
84
|
-
IviRuntimeDispatcher,
|
|
85
|
-
IviFrontendSdk,
|
|
86
|
-
IVIStageView,
|
|
87
|
-
IVITrackSlot,
|
|
88
|
-
useManagedIviRuntime,
|
|
89
|
-
useIviStageView
|
|
90
|
-
} from "@vivix/ivi-frontend-sdk";
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
> 当前包没有 `@vivix/ivi-frontend-sdk/core` / `@vivix/ivi-frontend-sdk/react` 子入口;底层 WebSocket client、事件解析与协议类型请直接从 `@vivix/ivi-sdk-ts` 导入。
|
|
94
|
-
|
|
95
67
|
---
|
|
96
68
|
|
|
97
69
|
## 快速开始
|
|
@@ -99,12 +71,15 @@ import {
|
|
|
99
71
|
### 1)创建 client + runtime
|
|
100
72
|
|
|
101
73
|
```ts
|
|
102
|
-
import { IviClient } from "@vivix/ivi-sdk-ts";
|
|
103
|
-
import { IviRuntimeCoordinator } from "@vivix/ivi-frontend-sdk";
|
|
74
|
+
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
|
|
75
|
+
import { IviRuntimeCoordinator } from "@vivix-ai/ivi-frontend-sdk";
|
|
76
|
+
import { LiveKitBrowserTransport } from "@vivix-ai/ivi-sdk-ts/transports/livekit-browser";
|
|
104
77
|
|
|
105
78
|
const client = new IviClient({
|
|
106
|
-
|
|
107
|
-
|
|
79
|
+
transport: new LiveKitBrowserTransport({
|
|
80
|
+
url: "wss://livekit.example.com",
|
|
81
|
+
token: "livekit_access_token"
|
|
82
|
+
}),
|
|
108
83
|
onParseError: (error, raw) => {
|
|
109
84
|
console.error("parse error", error, raw);
|
|
110
85
|
}
|
|
@@ -120,17 +95,42 @@ const runtime = new IviRuntimeCoordinator(client, {
|
|
|
120
95
|
await runtime.start();
|
|
121
96
|
```
|
|
122
97
|
|
|
98
|
+
也可以使用 `IviFrontendSdk` 创建 client/runtime:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { IviFrontendSdk } from "@vivix-ai/ivi-frontend-sdk";
|
|
102
|
+
import { LiveKitBrowserTransport } from "@vivix-ai/ivi-sdk-ts/transports/livekit-browser";
|
|
103
|
+
|
|
104
|
+
const sdk = new IviFrontendSdk();
|
|
105
|
+
const runtime = sdk.createRuntimeCoordinator(
|
|
106
|
+
{
|
|
107
|
+
transport: new LiveKitBrowserTransport({
|
|
108
|
+
url: "wss://livekit.example.com",
|
|
109
|
+
token: "livekit_access_token"
|
|
110
|
+
})
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
syncStageOnSessionCreated: true
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
await runtime.start();
|
|
118
|
+
```
|
|
119
|
+
|
|
123
120
|
**使用自定义 WebSocket 运行时**(Node.js / 自定义环境):
|
|
124
121
|
|
|
125
122
|
```ts
|
|
126
123
|
import WebSocket from "ws"; // Node.js 环境
|
|
127
|
-
import { IviClient } from "@vivix/ivi-sdk-ts";
|
|
128
|
-
import {
|
|
124
|
+
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
|
|
125
|
+
import { WebSocketTransport } from "@vivix-ai/ivi-sdk-ts/transports/websocket";
|
|
126
|
+
import { IviRuntimeCoordinator } from "@vivix-ai/ivi-frontend-sdk";
|
|
129
127
|
|
|
130
128
|
const client = new IviClient({
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
transport: new WebSocketTransport({
|
|
130
|
+
url: "wss://your-domain/v1/realtime",
|
|
131
|
+
sessionId: "sess_xxx",
|
|
132
|
+
socketFactory: (url, protocols) => new WebSocket(url, protocols)
|
|
133
|
+
}),
|
|
134
134
|
onParseError: (error, raw) => {
|
|
135
135
|
console.error("parse error", error, raw);
|
|
136
136
|
}
|
|
@@ -140,15 +140,13 @@ const runtime = new IviRuntimeCoordinator(client);
|
|
|
140
140
|
await runtime.start();
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
`IviClientConfig`
|
|
143
|
+
`IviFrontendClientConfig` 等同于 `@vivix-ai/ivi-sdk-ts` 的 `IviClientConfig`,需要直接传入通用 `transport`。
|
|
144
144
|
|
|
145
145
|
| 参数 | 类型 | 说明 |
|
|
146
146
|
|------|------|------|
|
|
147
|
-
| `
|
|
148
|
-
| `sessionId` | `string` | 会话 ID,连接时自动追加到 URL query `session_id=<id>` |
|
|
149
|
-
| `socketFactory` | `(url, protocols?) => WebSocket` | 自定义 Socket 工厂,用于替换默认 WebSocket 构造 |
|
|
147
|
+
| `transport` | `IviRealtimeTransport` | 通用 transport,直接透传给 `@vivix-ai/ivi-sdk-ts`;浏览器 LiveKit 场景可传 `LiveKitBrowserTransport` |
|
|
150
148
|
| `onParseError` | `(error, rawMessage) => void` | 事件解析失败回调 |
|
|
151
|
-
| `onLog` | `(entry) => void` | `IviClient` 链路日志回调,包含发送、
|
|
149
|
+
| `onLog` | `(entry) => void` | `IviClient` 链路日志回调,包含发送、transport 状态和重连链路 |
|
|
152
150
|
| `reconnect` | `IviClientReconnectOptions` | 自动重连配置;默认启用,指数退避 |
|
|
153
151
|
| `sendWaitTimeoutMs` | `number` | 发送时等待连接恢复的超时,默认 `30000` ms,`<=0` 表示无限等待 |
|
|
154
152
|
|
|
@@ -172,14 +170,14 @@ runtime.stop();
|
|
|
172
170
|
### 3)发送用户文本并触发模型回复
|
|
173
171
|
|
|
174
172
|
```ts
|
|
175
|
-
const result = await runtime.
|
|
173
|
+
const result = await runtime.sendUserTextAndTriggerResponse({
|
|
176
174
|
streamId: "stream_001",
|
|
177
175
|
text: "你好",
|
|
178
176
|
callbacks: {
|
|
179
177
|
onConversationItemAdded: (event) => console.log("item added"),
|
|
180
178
|
onConversationItemDone: (event) => console.log("item done"),
|
|
181
179
|
onConversationItemReady: ({ itemId }) => console.log("item ready:", itemId),
|
|
182
|
-
|
|
180
|
+
onResponseCreated: (event) => console.log("response created")
|
|
183
181
|
}
|
|
184
182
|
});
|
|
185
183
|
console.log("完成:", result.itemId, result.streamId);
|
|
@@ -198,8 +196,8 @@ runtime.sendSessionSourcePlaybackCompleted("source_001", "track_001");
|
|
|
198
196
|
| 字段 | 类型 | 说明 |
|
|
199
197
|
|------|------|------|
|
|
200
198
|
| `status` | `"idle" \| "connecting" \| "syncing" \| "running" \| "stopped"` | 生命周期状态 |
|
|
201
|
-
| `session` | `
|
|
202
|
-
| `stage` | `
|
|
199
|
+
| `session` | `IviRealtimeSessionConfig \| null` | 当前会话(来自 `@vivix-ai/ivi-sdk-ts`) |
|
|
200
|
+
| `stage` | `IviStageComposition \| null` | 当前 stage(slot → track 映射,来自 `@vivix-ai/ivi-sdk-ts`) |
|
|
203
201
|
| `tracks` | `Map<string, IviTrack>` | 所有 track |
|
|
204
202
|
| `sources` | `Map<string, IviRuntimeSource>` | 所有 source(含 `status: created \| ready \| failed`) |
|
|
205
203
|
| `conversationItems` | `Map<string, IviRuntimeConversationItem>` | 对话条目映射 |
|
|
@@ -212,11 +210,17 @@ runtime.sendSessionSourcePlaybackCompleted("source_001", "track_001");
|
|
|
212
210
|
### 方式 A:传入外部 runtime
|
|
213
211
|
|
|
214
212
|
```tsx
|
|
215
|
-
import { IviClient } from "@vivix/ivi-sdk-ts";
|
|
216
|
-
import { IviRuntimeCoordinator, IVIStageView, IVITrackSlot, useIviStageView } from "@vivix/ivi-frontend-sdk";
|
|
213
|
+
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
|
|
214
|
+
import { IviRuntimeCoordinator, IVIStageView, IVITrackSlot, useIviStageView } from "@vivix-ai/ivi-frontend-sdk";
|
|
215
|
+
import { LiveKitBrowserTransport } from "@vivix-ai/ivi-sdk-ts/transports/livekit-browser";
|
|
217
216
|
|
|
218
217
|
// 初始化 runtime(参考上方 Core 用法)
|
|
219
|
-
const client = new IviClient({
|
|
218
|
+
const client = new IviClient({
|
|
219
|
+
transport: new LiveKitBrowserTransport({
|
|
220
|
+
url: "wss://livekit.example.com",
|
|
221
|
+
token: "livekit_access_token"
|
|
222
|
+
})
|
|
223
|
+
});
|
|
220
224
|
const runtime = new IviRuntimeCoordinator(client);
|
|
221
225
|
await runtime.start();
|
|
222
226
|
|
|
@@ -244,16 +248,19 @@ export function StagePage() {
|
|
|
244
248
|
### 方式 B:使用 `useManagedIviRuntime` 管理 runtime
|
|
245
249
|
|
|
246
250
|
```tsx
|
|
247
|
-
import { IVIStageView, IVITrackSlot, useManagedIviRuntime } from "@vivix/ivi-frontend-sdk";
|
|
251
|
+
import { IVIStageView, IVITrackSlot, useManagedIviRuntime } from "@vivix-ai/ivi-frontend-sdk";
|
|
252
|
+
import { LiveKitBrowserTransport } from "@vivix-ai/ivi-sdk-ts/transports/livekit-browser";
|
|
248
253
|
|
|
249
|
-
export function AutoStagePage({
|
|
254
|
+
export function AutoStagePage({ livekitToken }: { livekitToken: string }) {
|
|
250
255
|
const runtime = useManagedIviRuntime({
|
|
251
256
|
clientConfig: {
|
|
252
|
-
|
|
253
|
-
|
|
257
|
+
transport: new LiveKitBrowserTransport({
|
|
258
|
+
url: "wss://livekit.example.com",
|
|
259
|
+
token: livekitToken
|
|
260
|
+
})
|
|
254
261
|
},
|
|
255
262
|
onLog: (entry) => {
|
|
256
|
-
// 统一收集 client / runtime / TRTC 的 IVI 链路日志
|
|
263
|
+
// 统一收集 client / runtime / TRTC / LiveKit 的 IVI 链路日志
|
|
257
264
|
console.log(entry.tag, entry.message, entry.data);
|
|
258
265
|
},
|
|
259
266
|
onRuntimeInitError: (err) => console.error("runtime init failed", err)
|
|
@@ -267,14 +274,12 @@ export function AutoStagePage({ sessionId }: { sessionId: string }) {
|
|
|
267
274
|
}
|
|
268
275
|
```
|
|
269
276
|
|
|
270
|
-
`useManagedIviRuntime`
|
|
277
|
+
`useManagedIviRuntime` 的连接规则:
|
|
271
278
|
|
|
272
|
-
1. 使用 `clientConfig.
|
|
273
|
-
2. 若 `clientConfig.
|
|
274
|
-
3.
|
|
275
|
-
4.
|
|
276
|
-
|
|
277
|
-
连接时自动追加 query:`?session_id=<sessionId>`。
|
|
279
|
+
1. 使用 `clientConfig.transport`
|
|
280
|
+
2. 若 `clientConfig.transport` 为空,则不创建 runtime
|
|
281
|
+
3. 浏览器 LiveKit 场景可传 `LiveKitBrowserTransport`
|
|
282
|
+
4. WebSocket、测试 fake transport 或其它 transport 也通过同一个 `transport` 字段传入
|
|
278
283
|
|
|
279
284
|
---
|
|
280
285
|
|
|
@@ -292,17 +297,17 @@ function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRuntimeCoordi
|
|
|
292
297
|
- `autoStart` 为 `true` 时自动调用 `runtime.start()`
|
|
293
298
|
- 卸载时自动 `runtime.stop()`
|
|
294
299
|
- 初始化错误通过 `onRuntimeInitError` 上抛
|
|
295
|
-
- 通过 `onLog` 统一收集 `IviClient`、runtime 状态变更、TRTC 管理器等 IVI 链路日志
|
|
300
|
+
- 通过 `onLog` 统一收集 `IviClient`、runtime 状态变更、TRTC / LiveKit 管理器等 IVI 链路日志
|
|
296
301
|
|
|
297
302
|
`IviManagedRuntimeConfig` 关键字段:
|
|
298
303
|
|
|
299
304
|
| 字段 | 类型 | 默认值 | 说明 |
|
|
300
305
|
|------|------|--------|------|
|
|
301
|
-
| `clientConfig` | `
|
|
306
|
+
| `clientConfig` | `Partial<IviFrontendClientConfig>` | — | `IviClient` 配置;`transport` 为空时不创建 runtime |
|
|
302
307
|
| `autoStart` | `boolean` | `true` | 是否自动启动 runtime |
|
|
303
308
|
| `runtimeConfig` | `IviRuntimeCoordinatorConfig` | — | 透传给 `IviRuntimeCoordinator` |
|
|
304
309
|
| `onRuntimeInitError` | `(error) => void` | — | 初始化或启动失败回调 |
|
|
305
|
-
| `onLog` | `(entry) => void` | — | 统一日志回调,覆盖 `[IVI-SEND]`、`[IVI-
|
|
310
|
+
| `onLog` | `(entry) => void` | — | 统一日志回调,覆盖 `[IVI-SEND]`、`[IVI-TRANSPORT]`、`[IVI-RECONNECT]`、`[IVI-EVT]`、`[IVI-STATE]`、`[IVI-TRTC]`、`[IVI-LIVEKIT]` |
|
|
306
311
|
|
|
307
312
|
`onLog` 的统一入参格式:
|
|
308
313
|
|
|
@@ -310,7 +315,7 @@ function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRuntimeCoordi
|
|
|
310
315
|
interface IviManagedRuntimeLogEntry {
|
|
311
316
|
level: "info" | "warn" | "error";
|
|
312
317
|
source: "client" | "runtime";
|
|
313
|
-
tag: string; // 例如 "[IVI-
|
|
318
|
+
tag: string; // 例如 "[IVI-TRANSPORT]"、"[IVI-STATE]"
|
|
314
319
|
message: string; // 带 tag 的可读日志
|
|
315
320
|
args: unknown[]; // 接近原 console 调用的参数
|
|
316
321
|
data?: unknown; // 结构化数据
|
|
@@ -341,7 +346,50 @@ function MyOverlay() {
|
|
|
341
346
|
}
|
|
342
347
|
```
|
|
343
348
|
|
|
344
|
-
|
|
349
|
+
### `useRuntimeState`
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
function useRuntimeState(runtime: IviRuntimeCoordinator | null): IviRuntimeState;
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
订阅 runtime 状态变化。`runtime` 为 `null` 时返回 `EMPTY_RUNTIME_STATE`。
|
|
356
|
+
|
|
357
|
+
### `useIviSubtitles`
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
function useIviSubtitles(
|
|
361
|
+
runtime: IviRuntimeCoordinator | null,
|
|
362
|
+
options?: IviUseSubtitlesOptions
|
|
363
|
+
): IviSubtitleItem[];
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
基于 runtime 的 conversation / response 事件维护字幕队列,不负责渲染,也不按时间自动消失。
|
|
367
|
+
|
|
368
|
+
| Option | 类型 | 默认值 | 说明 |
|
|
369
|
+
|--------|------|--------|------|
|
|
370
|
+
| `roles` | `IviSubtitleRole \| IviSubtitleRole[]` | `"user"` | 要收集的发言人角色 |
|
|
371
|
+
| `maxItems` | `number` | `2` | 最多保留的字幕条数,超过后清理最旧条目 |
|
|
372
|
+
|
|
373
|
+
`IviSubtitleItem` 包含 `id`、`role`、`lifecycle`、`status`、`text`、`transcript`、`displayText`、`timestamp`、`updatedAt`、`content`、`item`。
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
function CustomSubtitles({ runtime }: { runtime: IviRuntimeCoordinator | null }) {
|
|
377
|
+
const subtitles = useIviSubtitles(runtime, {
|
|
378
|
+
roles: ["user", "model"],
|
|
379
|
+
maxItems: 5
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
return (
|
|
383
|
+
<div>
|
|
384
|
+
{subtitles.map((item) => (
|
|
385
|
+
<span key={item.id}>{item.displayText}</span>
|
|
386
|
+
))}
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
以下 hooks 为 `IVITrackSlot` 内部实现,当前不属于包根公开导出 API。
|
|
345
393
|
|
|
346
394
|
### `useVolumeMemory`
|
|
347
395
|
|
|
@@ -349,7 +397,7 @@ function MyOverlay() {
|
|
|
349
397
|
function useVolumeMemory(mediaType: IviMediaVolumeType | null): [number, (v: number) => void];
|
|
350
398
|
```
|
|
351
399
|
|
|
352
|
-
按媒体类型(`"trtc" | "video" | "hls"`)在 `localStorage` 中持久化音量(0–100)。`mediaType` 为 `null` 时不持久化。
|
|
400
|
+
按媒体类型(`"trtc" | "livekit" | "video" | "hls"`)在 `localStorage` 中持久化音量(0–100)。`mediaType` 为 `null` 时不持久化。
|
|
353
401
|
|
|
354
402
|
### `useApplyVolumeToSlot`
|
|
355
403
|
|
|
@@ -362,13 +410,13 @@ function useApplyVolumeToSlot(
|
|
|
362
410
|
): void;
|
|
363
411
|
```
|
|
364
412
|
|
|
365
|
-
将音量同步应用到容器内带 `data-ivi-slot-role="active"` 属性的 `<video>` / `<audio>` 元素,通过 `MutationObserver` 监听异步插入的媒体(如 TRTC 远端流)。
|
|
413
|
+
将音量同步应用到容器内带 `data-ivi-slot-role="active"` 属性的 `<video>` / `<audio>` 元素,通过 `MutationObserver` 监听异步插入的媒体(如 TRTC / LiveKit 远端流)。
|
|
366
414
|
|
|
367
415
|
---
|
|
368
416
|
|
|
369
417
|
## React 组件
|
|
370
418
|
|
|
371
|
-
当前公开导出的 React
|
|
419
|
+
当前公开导出的 React 组件包括 `IVIStageView`、`IVITrackSlot`、`IVITrtcPlayer`、`IVILivekitPlayer` 与 `IVISubtitleOverlay`;当前公开导出的 React hooks 包括 `useManagedIviRuntime`、`useRuntimeState`、`useIviStageView` 与 `useIviSubtitles`。
|
|
372
420
|
|
|
373
421
|
### `IVIStageView`
|
|
374
422
|
|
|
@@ -392,20 +440,19 @@ function useApplyVolumeToSlot(
|
|
|
392
440
|
| `trackId` | `string` | — | 直接绑定 trackId |
|
|
393
441
|
| `emptyFallback` | `ReactNode` | — | 无 source 时的兜底内容 |
|
|
394
442
|
| `renderTrtc` | `(ctx: IviTrackSlotRenderContext) => ReactNode` | — | 自定义 TRTC 渲染 |
|
|
395
|
-
| `
|
|
443
|
+
| `renderLivekit` | `(ctx: IviTrackSlotRenderContext) => ReactNode` | — | 自定义 LiveKit 远端流渲染 |
|
|
444
|
+
| `renderMedia` | `(ctx: IviTrackSlotRenderContext) => ReactNode` | — | 自定义非 TRTC / LiveKit 媒体渲染 |
|
|
396
445
|
| `fitStrategy` | `"contain" \| "cover" \| "auto"` | — | 媒体适配策略 |
|
|
397
446
|
| `adaptToSourceSize` | `boolean` | — | 是否根据 source 尺寸自适应 |
|
|
398
|
-
| `background` | `IviTrackSlotBackground` | `"black"` | 媒体空白区域(letterbox/pillarbox)背景模式 |
|
|
399
447
|
| `showVolumeControl` | `boolean` | — | 是否显示音量控制浮层 |
|
|
400
448
|
| `volumeControlProps` | — | — | 音量控制自定义配置 |
|
|
401
449
|
| `showSubtitle` | `boolean` | — | 是否显示字幕浮层 |
|
|
402
|
-
| `subtitleProps` |
|
|
450
|
+
| `subtitleProps` | `Omit<IVISubtitleOverlayProps, "runtime">` | — | 字幕自定义配置 |
|
|
403
451
|
| `trtcPlayerProps` | — | — | TRTC 播放器自定义配置 |
|
|
452
|
+
| `livekitPlayerProps` | — | — | LiveKit 播放器自定义配置 |
|
|
404
453
|
| `videoProps` / `imageProps` | — | — | 透传给原生 `<video>` / `<img>` |
|
|
405
454
|
| `className` / `style` | — | — | 容器样式 |
|
|
406
455
|
|
|
407
|
-
`IviTrackSlotBackground` 支持的值:`"black"` | `"white"` | `"transparent"` | `{ color: string }` | `"blur"` | `{ blur: "live" | "static" }`
|
|
408
|
-
|
|
409
456
|
`IviTrackSlotRenderContext`:
|
|
410
457
|
|
|
411
458
|
```ts
|
|
@@ -417,7 +464,7 @@ interface IviTrackSlotRenderContext {
|
|
|
417
464
|
}
|
|
418
465
|
```
|
|
419
466
|
|
|
420
|
-
|
|
467
|
+
以下远端播放器可由 `IVITrackSlot` 默认使用,也可在业务侧按需直接使用。
|
|
421
468
|
|
|
422
469
|
### `IVITrtcPlayer`
|
|
423
470
|
|
|
@@ -425,7 +472,21 @@ TRTC 远端流播放器,自动以 audience 身份入会并订阅远端流。
|
|
|
425
472
|
|
|
426
473
|
| Prop | 类型 | 说明 |
|
|
427
474
|
|------|------|------|
|
|
428
|
-
| `trtc` |
|
|
475
|
+
| `trtc` | `IviSourcePlaybackTrtc` | TRTC 拉流配置 |
|
|
476
|
+
| `sourceId` | `string` | source ID |
|
|
477
|
+
| `runtime` | `IviRuntimeCoordinator` | runtime 实例 |
|
|
478
|
+
| `loadingFallback` | `ReactNode` | 加载中兜底 |
|
|
479
|
+
| `errorFallback` | `ReactNode` | 错误兜底 |
|
|
480
|
+
| `muted` | `boolean` | 是否静音 |
|
|
481
|
+
| `className` / `style` | — | 容器样式 |
|
|
482
|
+
|
|
483
|
+
### `IVILivekitPlayer`
|
|
484
|
+
|
|
485
|
+
LiveKit 远端音视频播放器,挂载后加入房间并订阅远端 tracks。`ivi-frontend-sdk` 只负责拉取和播放远端音视频流,不再发布用户麦克风;麦克风采集 / ASR 数据链路请使用 `@vivix-ai/ivi-sdk-ts/transports/livekit-browser` 或业务侧 transport。
|
|
486
|
+
|
|
487
|
+
| Prop | 类型 | 说明 |
|
|
488
|
+
|------|------|------|
|
|
489
|
+
| `livekit` | LiveKit playback 配置 | 包含 `ws_url`、`token`,以及可选 `room` / `identity` |
|
|
429
490
|
| `sourceId` | `string` | source ID |
|
|
430
491
|
| `runtime` | `IviRuntimeCoordinator` | runtime 实例 |
|
|
431
492
|
| `loadingFallback` | `ReactNode` | 加载中兜底 |
|
|
@@ -433,9 +494,9 @@ TRTC 远端流播放器,自动以 audience 身份入会并订阅远端流。
|
|
|
433
494
|
| `muted` | `boolean` | 是否静音 |
|
|
434
495
|
| `className` / `style` | — | 容器样式 |
|
|
435
496
|
|
|
436
|
-
### `IVIHlsVideo
|
|
497
|
+
### `IVIHlsVideo`(内部组件)
|
|
437
498
|
|
|
438
|
-
HLS 流播放器(基于 `hls.js
|
|
499
|
+
HLS 流播放器(基于 `hls.js`),由 `IVITrackSlot` 内部用于 `.m3u8` 地址播放;当前不从包根公开导出。
|
|
439
500
|
|
|
440
501
|
| Prop | 类型 | 说明 |
|
|
441
502
|
|------|------|------|
|
|
@@ -445,18 +506,17 @@ HLS 流播放器(基于 `hls.js`),用于 `.m3u8` 地址播放。辅助函
|
|
|
445
506
|
| `aggressivePreload` | `boolean` | 激进预加载模式 |
|
|
446
507
|
| `paused` | `boolean` | 是否暂停 |
|
|
447
508
|
|
|
448
|
-
> 隐藏原生控件(包括进度条):SDK 未提供单独隐藏进度条的开关,HTML5 `<video>` 也不支持只隐藏 timeline。可通过 `videoProps.controls = false` 关闭整套原生控件,适用于 `
|
|
509
|
+
> 隐藏原生控件(包括进度条):SDK 未提供单独隐藏进度条的开关,HTML5 `<video>` 也不支持只隐藏 timeline。可通过 `videoProps.controls = false` 关闭整套原生控件,适用于 `IVITrackSlot`:
|
|
449
510
|
>
|
|
450
511
|
> ```tsx
|
|
451
|
-
> <IVIHlsVideo url={url} videoProps={{ controls: false }} />
|
|
452
512
|
> <IVITrackSlot slot="main" videoProps={{ controls: false }} />
|
|
453
513
|
> ```
|
|
454
514
|
>
|
|
455
515
|
> 若需“保留播放/音量,仅隐藏进度条”,请在上层自行渲染自定义控制栏。
|
|
456
516
|
|
|
457
|
-
### `IVIVolumeControl
|
|
517
|
+
### `IVIVolumeControl`(内部组件)
|
|
458
518
|
|
|
459
|
-
|
|
519
|
+
音量控制浮层组件,由 `IVITrackSlot` 在 `showVolumeControl` 开启时内部使用;当前不从包根公开导出。
|
|
460
520
|
|
|
461
521
|
| Prop | 类型 | 说明 |
|
|
462
522
|
|------|------|------|
|
|
@@ -468,13 +528,14 @@ HLS 流播放器(基于 `hls.js`),用于 `.m3u8` 地址播放。辅助函
|
|
|
468
528
|
|
|
469
529
|
### `IVISubtitleOverlay`
|
|
470
530
|
|
|
471
|
-
|
|
531
|
+
预制字幕浮层组件,内部通过 `useIviSubtitles` 监听 runtime 的 conversation / response 事件并展示字幕。
|
|
472
532
|
|
|
473
533
|
| Prop | 类型 | 默认值 | 说明 |
|
|
474
534
|
|------|------|--------|------|
|
|
475
|
-
| `
|
|
476
|
-
| `
|
|
477
|
-
| `
|
|
535
|
+
| `runtime` | `IviRuntimeCoordinator \| null` | — | 字幕来源 runtime |
|
|
536
|
+
| `roles` | `IviSubtitleRole \| IviSubtitleRole[]` | `"user"` | 要展示的发言人角色 |
|
|
537
|
+
| `maxItems` | `number` | `2` | 最多保留的字幕条数,超过后清理最旧条目 |
|
|
538
|
+
| `maxVisible` | `number` | — | 已废弃,兼容旧字段;请使用 `maxItems` |
|
|
478
539
|
| `subtitleStyle` | `IVISubtitleOverlayStyle` | — | 样式配置 |
|
|
479
540
|
| `className` / `style` | — | — | 样式 |
|
|
480
541
|
|
|
@@ -493,7 +554,7 @@ HLS 流播放器(基于 `hls.js`),用于 `.m3u8` 地址播放。辅助函
|
|
|
493
554
|
| `sendSessionSourcePlaybackCompleted(sourceId, trackId?)` | 上报 source 播放完成 |
|
|
494
555
|
| `sendConversationList()` | 请求对话列表 |
|
|
495
556
|
| `sendConversationItemCreate(item)` | 创建对话条目 |
|
|
496
|
-
| `
|
|
557
|
+
| `sendUserText(text, itemId?)` | 发送用户文本 |
|
|
497
558
|
| `sendResponseCreate(streamId?, response?)` | 触发模型回复;`streamId` 可选,省略时使用 session 级配置 |
|
|
498
559
|
| `sendResponseCreateByItemId(itemId, streamId?, response?)` | 基于条目 ID 触发模型回复 |
|
|
499
560
|
|
|
@@ -549,13 +610,13 @@ npm run test
|
|
|
549
610
|
仓库提供版本提升脚本,执行前要求工作区干净:
|
|
550
611
|
|
|
551
612
|
```bash
|
|
552
|
-
npm run release:version -- 0.
|
|
613
|
+
npm run release:version -- 0.3.0
|
|
553
614
|
```
|
|
554
615
|
|
|
555
616
|
脚本会同步更新 `package.json` / `package-lock.json`,提交:
|
|
556
617
|
|
|
557
618
|
```text
|
|
558
|
-
chore: update package version to 0.
|
|
619
|
+
chore: update package version to 0.3.0
|
|
559
620
|
```
|
|
560
621
|
|
|
561
|
-
并创建 tag:`v0.
|
|
622
|
+
并创建 tag:`v0.3.0`。
|