@vivix-ai/ivi-frontend-sdk 0.2.2 → 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 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
- 当前包尚未发布到 npm,通过 **GitLab 仓库地址**直接安装:
10
+ 当前包发布到 npm 官方仓库,包名为 `@vivix-ai/ivi-frontend-sdk`。
11
+
12
+ 安装 SDK:
11
13
 
12
14
  ```bash
13
15
  # npm
14
- npm install git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main
16
+ npm install @vivix-ai/ivi-frontend-sdk
15
17
 
16
18
  # pnpm
17
- pnpm add git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main
19
+ pnpm add @vivix-ai/ivi-frontend-sdk
18
20
 
19
21
  # yarn
20
- yarn add git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main
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": "git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main"
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(Git 依赖建议显式指定分支、tag 或 commit)
39
- npm install git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main
38
+ # npm
39
+ npm update @vivix-ai/ivi-frontend-sdk
40
40
 
41
41
  # pnpm
42
- pnpm add git+https://gitlab.vivix.work/vinf-2.0/ivi-sdk/ivi-frontend-sdk.git#main
42
+ pnpm update @vivix-ai/ivi-frontend-sdk
43
43
 
44
- # 若 lockfile 固定了旧 commit,可重新安装或删除 lock 中该依赖条目后 install
45
- npm install
44
+ # yarn
45
+ yarn up @vivix-ai/ivi-frontend-sdk
46
46
  ```
47
47
 
48
- ### `dist` 与 Git 直装
48
+ ### `dist` 与 npm 发布
49
49
 
50
- `package.json` 的 `main` / `module` / `types` / `exports` 均指向 `dist/`,且 npm 包通过 `"files": ["dist"]` 发布。从 **Git 引用安装**(如 `git+https://…#dev`)时,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
- url: "wss://your-domain/v1/realtime",
107
- sessionId: "sess_xxx",
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 { IviRuntimeCoordinator } from "@vivix/ivi-frontend-sdk";
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
- url: "wss://your-domain/v1/realtime",
132
- sessionId: "sess_xxx",
133
- socketFactory: (url, protocols) => new WebSocket(url, protocols),
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
- | `protocols` | `string \| string[]` | WebSocket 子协议 |
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` 链路日志回调,包含发送、WebSocket 状态和重连链路 |
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.sendUserTextAndTriggerStreamResponse({
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
- onStreamResponseCreated: (event) => console.log("response created")
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` | `IviRealtimeSession \| null` | 当前会话 |
202
- | `stage` | `IviStage \| null` | 当前 stage(slot → track 映射) |
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({ url: "wss://your-domain/v1/realtime", sessionId: "sess_xxx" });
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({ sessionId }: { sessionId: string }) {
254
+ export function AutoStagePage({ livekitToken }: { livekitToken: string }) {
250
255
  const runtime = useManagedIviRuntime({
251
256
  clientConfig: {
252
- url: "https://your-domain.com/v1/realtime",
253
- sessionId
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.url`
273
- 2. 若 `clientConfig.url` `https://` / `http://`,内部会自动确保为 `wss://` / `ws://`
274
- 3. `clientConfig.sessionId` 为空,则不创建 runtime
275
- 4. `clientConfig.url` 为空,会通过 `onRuntimeInitError` 抛出初始化错误;若未提供回调,则直接抛错
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` | `IviClientConfig` | — | `IviClient` 配置;其中 `url` 用于建立连接,`sessionId` 用于决定是否创建 runtime |
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-WS]`、`[IVI-RECONNECT]`、`[IVI-EVT]`、`[IVI-STATE]`、`[IVI-TRTC]` |
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-WS]"、"[IVI-STATE]"
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
- 以下 hooks 为 `IVITrackSlot` 内部实现,当前不属于公开导出 API。
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 组件只有 `IVIStageView` 与 `IVITrackSlot`;当前公开导出的 React hooks 只有 `useManagedIviRuntime` 与 `useIviStageView`。
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
- | `renderMedia` | `(ctx: IviTrackSlotRenderContext) => ReactNode` | — | 自定义非 TRTC 媒体渲染 |
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
- 以下组件为 `IVITrackSlot` 依赖的内部实现,当前不属于公开导出 API。
467
+ 以下远端播放器可由 `IVITrackSlot` 默认使用,也可在业务侧按需直接使用。
421
468
 
422
469
  ### `IVITrtcPlayer`
423
470
 
@@ -425,7 +472,21 @@ TRTC 远端流播放器,自动以 audience 身份入会并订阅远端流。
425
472
 
426
473
  | Prop | 类型 | 说明 |
427
474
  |------|------|------|
428
- | `trtc` | TRTC 实例 | TRTC SDK 实例 |
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`),用于 `.m3u8` 地址播放。辅助函数 `isM3u8Url(url)` 可判断 URL 是否为 m3u8。
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` 关闭整套原生控件,适用于 `IVIHlsVideo` 与 `IVITrackSlot`:
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
- | `conversations` | `IviRuntimeConversationItem[]` | — | 会话条目列表 |
476
- | `maxVisible` | `number` | `2` | 同时可见的最大条目数 |
477
- | `dismissAfterMs` | `number` | `5000` | 条目完成后自动消失毫秒数 |
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
- | `sendConversationUserText(text, itemId?)` | 发送用户文本,返回 `Promise<string>`,resolve 为最终 itemId |
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.2.2
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.2.2
619
+ chore: update package version to 0.3.0
559
620
  ```
560
621
 
561
- 并创建 tag:`v0.2.2`。
622
+ 并创建 tag:`v0.3.0`。