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