@vivix-ai/ivi-frontend-sdk 0.3.8 → 0.3.10

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
@@ -3,7 +3,9 @@
3
3
  用于前端应用集成 IVI 实时能力的 TypeScript SDK,包含:
4
4
 
5
5
  - 基于 `@vivix-ai/ivi-sdk-ts` 的 runtime 协调层
6
+ - 通过 API 网关创建 IVI Session 的 HTTP 辅助方法
6
7
  - 面向舞台渲染的 React 组件与 hooks
8
+ - 基于 OpenTelemetry API 的链路 span(SDK 不内置 exporter/provider)
7
9
 
8
10
  ## 安装依赖
9
11
 
@@ -111,6 +113,147 @@ const runtime = sdk.createRuntimeCoordinator(
111
113
  await runtime.start();
112
114
  ```
113
115
 
116
+ ### 1.1)通过 API 网关创建 IVI Session 并启动 runtime
117
+
118
+ 如果业务侧已经接入 API 网关,可直接使用 SDK 内置的 `createIVISession` HTTP 封装。该方法会调用 `POST /v1/ivi/sessions`,拿到 `ivi_session_id` / `endpoint` 后创建 WebSocket runtime。
119
+
120
+ 当创建会话响应里包含 `prebuild_trtc_info` 时,SDK 会把它转换成一个临时的 bootstrap source,并在 websocket 真实 `stage/track/source` 事件到达前,提前通过 `IVITrackSlot slot="main"` 展示画面。真实 source ready 后会自动接管,业务 UI 不需要区分“快速开播”和“常规开播”。
121
+
122
+ ```ts
123
+ import {
124
+ createIVISession,
125
+ createRuntimeFromSession
126
+ } from "@vivix-ai/ivi-frontend-sdk";
127
+
128
+ const session = await createIVISession(
129
+ {
130
+ idempotencyKey: crypto.randomUUID(),
131
+ streamType: "TRTC",
132
+ iviVersion: "dev",
133
+ sessionParameters: {
134
+ resolution: "720p"
135
+ },
136
+ prebuiltCharacters: [
137
+ {
138
+ characterId: "character_claire",
139
+ characterPayload: characterJson
140
+ }
141
+ ],
142
+ prebuiltStream: {
143
+ streamId: "stream_claire",
144
+ mode: "character",
145
+ streamConfig: {
146
+ scene_description: "Claire on stage",
147
+ character_ids: ["character_claire"],
148
+ realtime_cvi_config: { enabled: false }
149
+ }
150
+ }
151
+ },
152
+ {
153
+ baseUrl: "https://api.example.com",
154
+ headers: async () => ({
155
+ Authorization: `Bearer ${token}`
156
+ })
157
+ }
158
+ );
159
+
160
+ const { runtime } = createRuntimeFromSession(session, {
161
+ fastStart: true,
162
+ bootstrapSlot: "main",
163
+ websocket: {
164
+ query: {
165
+ x_auth_jwt: authJwt
166
+ },
167
+ protocols: authJwt ? ["ivi", authJwt] : undefined
168
+ }
169
+ });
170
+
171
+ await runtime.start();
172
+ ```
173
+
174
+ 也可以一步完成创建 session 与 runtime:
175
+
176
+ ```ts
177
+ import { createIVISessionRuntime } from "@vivix-ai/ivi-frontend-sdk";
178
+
179
+ const { session, runtime } = await createIVISessionRuntime(request, {
180
+ http: {
181
+ baseUrl: "https://api.example.com",
182
+ headers: { Authorization: `Bearer ${token}` }
183
+ },
184
+ fastStart: true,
185
+ bootstrapSlot: "main"
186
+ });
187
+
188
+ await runtime.start();
189
+ ```
190
+
191
+ `createIVISession` 返回值会保留原始 response,同时提供 SDK 归一化字段:
192
+
193
+ | 字段 | 类型 | 说明 |
194
+ |------|------|------|
195
+ | `iviSessionId` | `string` | 会话 ID,对应后端 `ivi_session_id` |
196
+ | `endpoint` | `string` | IVI realtime websocket 地址 |
197
+ | `trtcInfo` / `livekitInfo` | — | 会话级播放/传输信息(如果后端返回) |
198
+ | `prebuildTrtcInfo` | — | 后端 `prebuild_trtc_info` 的 camelCase 视图 |
199
+ | `prebuiltPlayback` | — | SDK 归一化后的快速开播播放源;存在时可用于 bootstrap source |
200
+ | `raw` | `unknown` | 原始 HTTP response body |
201
+ | `requestBody` | `Record<string, unknown>` | 实际发给网关的 snake_case JSON |
202
+
203
+ `IviCreateIVISessionRequest` 使用 camelCase 字段,SDK 会在发送前转换为 CP transcoder 需要的 snake_case JSON:
204
+
205
+ | SDK 字段 | HTTP 字段 |
206
+ |----------|-----------|
207
+ | `idempotencyKey` | `idempotency_key` |
208
+ | `streamType` | `stream_type` |
209
+ | `iviVersion` | `ivi_version` |
210
+ | `sessionParameters` | `session_parameters` |
211
+ | `prebuiltCharacters` | `prebuilt_characters` |
212
+ | `prebuiltStream` | `prebuilt_stream` |
213
+ | `enableDecoderPublish` | `enable_decoder_publish` |
214
+ | `sessionRecording` | `session_recording` |
215
+
216
+ > 浏览器侧不应依赖 TRTC `secret_key`。SDK 在归一化 TRTC 信息时会丢弃 `secret_key` / `secretKey`,播放器只使用拉流所需的 `app_id`、`room_id`、`user_id`、`user_sig`。
217
+
218
+ ### 1.2)OpenTelemetry 链路观测
219
+
220
+ SDK 只依赖 `@opentelemetry/api` 并创建 spans,不配置上报目的地。业务应用只要在入口处配置自己的 OpenTelemetry provider/exporter,随后把 `telemetry` 透传给 SDK 即可;未配置 provider 时这些调用会自动 no-op。
221
+
222
+ ```ts
223
+ import { context, trace } from "@opentelemetry/api";
224
+ import { createIVISessionRuntime } from "@vivix-ai/ivi-frontend-sdk";
225
+
226
+ const telemetry = {
227
+ tracer: trace.getTracer("my-live-page"),
228
+ context: context.active(), // 可接上按钮点击、页面路由等外部父链路
229
+ attributes: {
230
+ "app.feature": "ivi-live"
231
+ }
232
+ };
233
+
234
+ const { runtime } = await createIVISessionRuntime(request, {
235
+ http: {
236
+ baseUrl: "https://api.example.com",
237
+ headers: { Authorization: `Bearer ${token}` }
238
+ },
239
+ telemetry,
240
+ fastStart: true,
241
+ bootstrapSlot: "main"
242
+ });
243
+
244
+ await runtime.start();
245
+ ```
246
+
247
+ 会被串联的关键 spans 包括:
248
+
249
+ - `ivi.session.create`:HTTP 创建 IVI Session
250
+ - `ivi.runtime.create` / `ivi.runtime.start` / `ivi.runtime.stop`
251
+ - `ivi.runtime.state_change`
252
+ - `ivi.client.*`:底层 `@vivix-ai/ivi-sdk-ts` WebSocket 连接、发送、接收等 spans
253
+ - `ivi.media.trtc.*` / `ivi.media.livekit.*`:远端视频可用、开始渲染、渲染完成等首屏关键点
254
+
255
+ SDK span 不会写入 token、`user_sig`、TRTC `secret_key` 或完整业务 payload。低基数字段可以放在 `telemetry.attributes` 中统一附加。
256
+
114
257
  **使用自定义 WebSocket 运行时**(Node.js / 自定义环境):
115
258
 
116
259
  ```ts
@@ -141,6 +284,7 @@ await runtime.start();
141
284
  | `transport` | `IviRealtimeTransport` | 通用 transport,直接透传给 `@vivix-ai/ivi-sdk-ts`;浏览器 LiveKit 场景可传 `LiveKitBrowserTransport` |
142
285
  | `onParseError` | `(error, rawMessage) => void` | 事件解析失败回调 |
143
286
  | `onLog` | `(entry) => void` | `IviClient` 链路日志回调,包含发送、transport 状态和重连链路 |
287
+ | `telemetry` | `IviClientTelemetryOptions` | OpenTelemetry 配置;通常由上层 SDK 透传 |
144
288
  | `reconnect` | `IviClientReconnectOptions` | 自动重连配置;默认启用,指数退避 |
145
289
  | `sendWaitTimeoutMs` | `number` | 发送时等待连接恢复的超时,默认 `30000` ms,`<=0` 表示无限等待 |
146
290
 
@@ -219,6 +363,7 @@ runtime.sendSessionSourcePlaybackCompleted("source_001", "track_001");
219
363
  | `sources` | `Map<string, IviRuntimeSource>` | 所有 source(含 `status: created \| ready \| failed`) |
220
364
  | `conversationItems` | `Map<string, IviRuntimeConversationItem>` | 对话条目映射 |
221
365
  | `conversations` | `IviRuntimeConversationItem[]` | 对话有序列表 |
366
+ | `bootstrap` | `IviRuntimeBootstrapViewState \| null` | prebuild 快速开播的临时 slot/track/source 绑定状态 |
222
367
 
223
368
  ---
224
369
 
@@ -298,6 +443,59 @@ export function AutoStagePage({ livekitToken }: { livekitToken: string }) {
298
443
  3. 浏览器 LiveKit 场景可传 `LiveKitBrowserTransport`
299
444
  4. WebSocket、测试 fake transport 或其它 transport 也通过同一个 `transport` 字段传入
300
445
 
446
+ ### 方式 C:使用 `useIviSessionRuntime` 创建会话并管理 runtime
447
+
448
+ 当希望把 `createIVISession` 也放进 SDK 接入流程时,可以使用 `useIviSessionRuntime`。它会在挂载后创建 IVI Session、构造 WebSocket runtime,并在 `autoStart` 为 `true` 时自动启动。
449
+
450
+ ```tsx
451
+ import {
452
+ IVIStageView,
453
+ IVITrackSlot,
454
+ useIviSessionRuntime,
455
+ type IviCreateIVISessionRequest
456
+ } from "@vivix-ai/ivi-frontend-sdk";
457
+
458
+ export function FastStartStagePage({
459
+ request,
460
+ token,
461
+ authJwt
462
+ }: {
463
+ request: IviCreateIVISessionRequest;
464
+ token: string;
465
+ authJwt?: string;
466
+ }) {
467
+ const { runtime, session, status, error } = useIviSessionRuntime({
468
+ request,
469
+ http: {
470
+ baseUrl: "https://api.example.com",
471
+ headers: {
472
+ Authorization: `Bearer ${token}`
473
+ }
474
+ },
475
+ fastStart: true,
476
+ bootstrapSlot: "main",
477
+ websocket: {
478
+ query: {
479
+ x_auth_jwt: authJwt
480
+ },
481
+ protocols: authJwt ? ["ivi", authJwt] : undefined
482
+ }
483
+ });
484
+
485
+ if (error) return <div>{error.message}</div>;
486
+
487
+ return (
488
+ <IVIStageView runtime={runtime}>
489
+ <IVITrackSlot slot="main" showVolumeControl showSubtitle />
490
+ <span>{status}</span>
491
+ <span>{session?.iviSessionId}</span>
492
+ </IVIStageView>
493
+ );
494
+ }
495
+ ```
496
+
497
+ `request` 变化会重新创建 session/runtime;业务侧应使用 `useMemo` 或稳定引用控制重启时机。
498
+
301
499
  ---
302
500
 
303
501
  ## React Hooks
@@ -323,6 +521,7 @@ function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRuntimeCoordi
323
521
  | `clientConfig` | `Partial<IviFrontendClientConfig>` | — | `IviClient` 配置;`transport` 为空时不创建 runtime |
324
522
  | `autoStart` | `boolean` | `true` | 是否自动启动 runtime |
325
523
  | `runtimeConfig` | `IviRuntimeCoordinatorConfig` | — | 透传给 `IviRuntimeCoordinator` |
524
+ | `clientConfig.telemetry` / `runtimeConfig.telemetry` | `IviFrontendTelemetryOptions` | — | OpenTelemetry 透传;两处使用同一个配置即可串联 |
326
525
  | `onRuntimeInitError` | `(error) => void` | — | 初始化或启动失败回调 |
327
526
  | `onLog` | `(entry) => void` | — | 统一日志回调,覆盖 `[IVI-SEND]`、`[IVI-TRANSPORT]`、`[IVI-RECONNECT]`、`[IVI-EVT]`、`[IVI-STATE]`、`[IVI-TRTC]`、`[IVI-LIVEKIT]` |
328
527
 
@@ -339,6 +538,43 @@ interface IviManagedRuntimeLogEntry {
339
538
  }
340
539
  ```
341
540
 
541
+ ### `useIviSessionRuntime`
542
+
543
+ ```ts
544
+ function useIviSessionRuntime(config: UseIviSessionRuntimeConfig): UseIviSessionRuntimeResult;
545
+ ```
546
+
547
+ 负责把 `createIVISession`、WebSocket transport 和 `IviRuntimeCoordinator` 组合起来。适合希望通过 API 网关创建会话,并在 prebuild 成功时自动快速开播的 React 接入。
548
+
549
+ `UseIviSessionRuntimeConfig` 关键字段:
550
+
551
+ | 字段 | 类型 | 默认值 | 说明 |
552
+ |------|------|--------|------|
553
+ | `request` | `IviCreateIVISessionRequest \| null \| undefined` | — | 创建会话请求;为空时不创建 runtime |
554
+ | `http` | `IviCreateIVISessionHttpOptions` | — | HTTP 网关配置,包含 `baseUrl` / `url` / `headers` / `fetch` |
555
+ | `fastStart` | `boolean` | `true` | 是否启用 prebuild bootstrap source |
556
+ | `bootstrapSlot` | `string` | `"main"` | 快速开播临时绑定的 slot |
557
+ | `bootstrapTrackId` | `string` | `"__ivi_bootstrap_track"` | 快速开播临时 track id |
558
+ | `websocket` | `IviRuntimeWebSocketOptions` | — | websocket 地址、query、protocols、socketFactory |
559
+ | `runtimeConfig` | `IviRuntimeCoordinatorConfig` | — | 透传给 runtime |
560
+ | `clientConfig` | `Omit<IviClientConfig, "transport">` | — | 透传给 `IviClient` 的非 transport 配置 |
561
+ | `telemetry` | `IviFrontendTelemetryOptions` | — | 同时串联创建 session、runtime 和底层 WebSocket spans |
562
+ | `enabled` | `boolean` | `true` | 是否启用 hook |
563
+ | `autoStart` | `boolean` | `true` | 是否创建后自动调用 `runtime.start()` |
564
+ | `onCreated` | `(session) => void` | — | HTTP 创建会话成功回调 |
565
+ | `onRuntimeReady` | `(runtime, client) => void` | — | runtime 构造完成回调 |
566
+ | `onError` | `(error) => void` | — | 创建或启动失败回调 |
567
+
568
+ 返回值:
569
+
570
+ | 字段 | 类型 | 说明 |
571
+ |------|------|------|
572
+ | `status` | `"idle" \| "creating" \| "connecting" \| "running" \| "error" \| "stopped"` | hook 生命周期状态 |
573
+ | `session` | `IviCreateIVISessionResult \| null` | 创建会话结果 |
574
+ | `runtime` | `IviRuntimeCoordinator \| null` | runtime 实例 |
575
+ | `client` | `IviClient \| null` | 底层 realtime client |
576
+ | `error` | `Error \| null` | 最近一次错误 |
577
+
342
578
  ### `useIviStageView`
343
579
 
344
580
  ```ts
@@ -440,7 +676,7 @@ function useApplyVolumeToSlot(
440
676
 
441
677
  ## React 组件
442
678
 
443
- 当前公开导出的 React 组件包括 `IVIStageView`、`IVITrackSlot`、`IVITrtcPlayer`、`IVILivekitPlayer` 与 `IVISubtitleOverlay`;当前公开导出的 React hooks 包括 `useManagedIviRuntime`、`useRuntimeState`、`useIviStageView` 与 `useIviSubtitles`。
679
+ 当前公开导出的 React 组件包括 `IVIStageView`、`IVITrackSlot`、`IVITrtcPlayer`、`IVILivekitPlayer` 与 `IVISubtitleOverlay`;当前公开导出的 React hooks 包括 `useManagedIviRuntime`、`useIviSessionRuntime`、`useRuntimeState`、`useIviStageView` 与 `useIviSubtitles`。
444
680
 
445
681
  ### `IVIStageView`
446
682