@vivix-ai/ivi-frontend-sdk 0.2.2

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.
@@ -0,0 +1,549 @@
1
+ import { IviRealtimeSession, IviStage, IviTrack, IviSource, IviSourcePlayback, IviSessionSourceFailedPayload, IviStream, IviStreamStatus, IviConversationItemRole, IviConversationItem, IviConversationItemContent, ReceiveSessionEndedEvent, ParsedIviEvent, IviRealtimeResponseCreateParams, ReceiveConversationItemAddedEvent, ReceiveConversationItemDoneEvent, ReceiveResponseCreatedEvent, IviSourcePlaybackTrtc, IviClient, IviClientConfig } from '@vivix/ivi-sdk-ts';
2
+ import { ReactNode, CSSProperties, ReactElement, VideoHTMLAttributes, ImgHTMLAttributes } from 'react';
3
+ import { IviClientLogEntry } from '@vivix/ivi-sdk-ts/client';
4
+
5
+ type IviRuntimeStatus = "idle" | "connecting" | "syncing" | "running" | "stopped";
6
+ interface IviRuntimeState {
7
+ status: IviRuntimeStatus;
8
+ session: IviRealtimeSession | null;
9
+ stage: IviStage | null;
10
+ tracks: Map<string, IviTrack>;
11
+ sources: Map<string, IviRuntimeSource>;
12
+ streams: Map<string, IviRuntimeStream>;
13
+ conversationItems: Map<string, IviRuntimeConversationItem>;
14
+ conversations: IviRuntimeConversationItem[];
15
+ }
16
+ /**
17
+ * Runtime 层归一化后的 stream 视图。
18
+ */
19
+ interface IviRuntimeStream {
20
+ stream: IviStream;
21
+ status: IviStreamStatus;
22
+ /** stream.started 事件携带的关联 track ID。 */
23
+ trackId?: string;
24
+ error?: unknown;
25
+ }
26
+ interface IviRuntimeSourcePreloadState {
27
+ /**
28
+ * 当 source 离开 track(不再被任何 track 的 active/next 引用)时是否自动清除预加载。
29
+ * - 由服务端 `session.source.preload` 事件携带;
30
+ * - 也包括 SDK 内部因 track 的 next_source 而合成的预加载(默认 true)。
31
+ */
32
+ autoclearAfterPlay: boolean;
33
+ }
34
+ interface IviRuntimeSource {
35
+ source: IviSource;
36
+ status: "created" | "ready" | "failed";
37
+ playback?: IviSourcePlayback;
38
+ width?: number;
39
+ height?: number;
40
+ durationMs?: number;
41
+ hasAudio?: boolean;
42
+ error?: IviSessionSourceFailedPayload["error"];
43
+ /**
44
+ * 预加载状态:
45
+ * - 存在:渲染层应对该 source 进行预加载;
46
+ * - 不存在:不进行预加载(active source 由上层独立决定是否渲染)。
47
+ */
48
+ preload?: IviRuntimeSourcePreloadState;
49
+ }
50
+ type IviRuntimeLogLevel = "info" | "warn" | "error";
51
+ interface IviRuntimeLogEntry {
52
+ level: IviRuntimeLogLevel;
53
+ tag: string;
54
+ message: string;
55
+ args: unknown[];
56
+ data?: unknown;
57
+ }
58
+ type IviRuntimeLogCallback = (entry: IviRuntimeLogEntry) => void;
59
+ type IviRuntimeConversationLifecycle = "added" | "done";
60
+ type IviRuntimeConversationStatus = "in_progress" | "completed" | "incomplete";
61
+ interface IviRuntimeConversationItem {
62
+ id: string;
63
+ role: IviConversationItemRole;
64
+ lifecycle: IviRuntimeConversationLifecycle;
65
+ status: IviRuntimeConversationStatus;
66
+ item: IviConversationItem;
67
+ text: string;
68
+ transcript: string;
69
+ content: IviConversationItemContent[];
70
+ }
71
+ interface IviRuntimeCoordinatorConfig {
72
+ /**
73
+ * session.created 后是否自动请求 stage 同步。
74
+ * - true(默认):先进入 syncing,再在 stage 回来后进入 running。
75
+ * - false:跳过 stage 首次同步,直接进入 running。
76
+ */
77
+ syncStageOnSessionCreated?: boolean;
78
+ /**
79
+ * 收到 `session.ended` 且 runtime 已执行内部清理(进入 `stopped`、清空会话态)后调用。
80
+ */
81
+ onSessionEnded?: (event: ReceiveSessionEndedEvent) => void;
82
+ /**
83
+ * Runtime 内部链路日志回调;未传入时仍仅输出原有 console 日志。
84
+ */
85
+ onLog?: IviRuntimeLogCallback;
86
+ }
87
+ /**
88
+ * 用户输入触发回复链路配置。
89
+ */
90
+ interface IviRuntimeUserTextToResponseOptions {
91
+ /**
92
+ * 目标 stream ID,用于发送 response.create。
93
+ * 可选:省略时使用 session 级配置(无 stream 绑定)。
94
+ */
95
+ streamId?: string;
96
+ /**
97
+ * 用户输入文本。
98
+ */
99
+ text: string;
100
+ /**
101
+ * 可选会话条目 ID;未传则由 SDK 自动生成。
102
+ */
103
+ itemId?: string;
104
+ /**
105
+ * 透传给 response.create 的响应参数(不含 input)。
106
+ */
107
+ response?: Omit<IviRealtimeResponseCreateParams, "input">;
108
+ /**
109
+ * 关键节点回调。
110
+ */
111
+ callbacks?: IviRuntimeUserTextToResponseCallbacks;
112
+ }
113
+ /**
114
+ * 用户输入触发回复链路关键节点回调集合。
115
+ */
116
+ interface IviRuntimeUserTextToResponseCallbacks {
117
+ onConversationItemAdded?: (event: ReceiveConversationItemAddedEvent) => void;
118
+ onConversationItemDone?: (event: ReceiveConversationItemDoneEvent) => void;
119
+ /**
120
+ * 收到 added + done,表示用户条目创建完成。
121
+ */
122
+ onConversationItemReady?: (input: {
123
+ itemId: string;
124
+ addedEvent: ReceiveConversationItemAddedEvent;
125
+ doneEvent: ReceiveConversationItemDoneEvent;
126
+ }) => void;
127
+ /**
128
+ * 收到 response.created,表示触发模型回复成功。
129
+ */
130
+ onResponseCreated?: (event: ReceiveResponseCreatedEvent) => void;
131
+ }
132
+ /**
133
+ * 用户输入触发回复链路完成结果。
134
+ */
135
+ interface IviRuntimeUserTextToResponseResult {
136
+ itemId: string;
137
+ streamId?: string;
138
+ responseCreatedEvent: ReceiveResponseCreatedEvent;
139
+ }
140
+ type IviRuntimeDispatcherConfig = IviRuntimeCoordinatorConfig;
141
+ type IviRuntimeConnectionListener = (connected: boolean) => void;
142
+ type IviRuntimeEventListener = (event: ParsedIviEvent, state: IviRuntimeState) => void;
143
+
144
+ type TrtcSourceConnectionStatus = "idle" | "connecting" | "connected" | "error";
145
+ interface TrtcSourceSnapshot {
146
+ status: TrtcSourceConnectionStatus;
147
+ error?: string;
148
+ }
149
+ type TrtcSourceListener = (snapshot: TrtcSourceSnapshot) => void;
150
+ declare class TrtcSourceManager {
151
+ private readonly onLog?;
152
+ private readonly sessions;
153
+ private readonly listeners;
154
+ constructor(onLog?: IviRuntimeLogCallback | undefined);
155
+ /**
156
+ * 将 runtime 当前 sources 与 TRTC 会话池对齐:
157
+ * - 对 ready + trtc 的 source 进行 upsert(必要时建立连接)
158
+ * - 清理已不在 runtime 中的会话(释放资源)
159
+ */
160
+ syncRuntimeSources(sources: Map<string, IviRuntimeSource>): void;
161
+ /**
162
+ * 按 sourceId 注册/更新 TRTC 配置。
163
+ * 若配置发生变化,会先销毁旧会话再按新参数重建连接。
164
+ */
165
+ upsertSource(sourceId: string, trtc: IviSourcePlaybackTrtc): void;
166
+ /**
167
+ * 删除指定 source 的 TRTC 会话并释放连接资源。
168
+ * 该操作通常由 source.deleted 或会话重置触发。
169
+ */
170
+ removeSource(sourceId: string): void;
171
+ reset(): void;
172
+ subscribe(sourceId: string, listener: TrtcSourceListener): () => void;
173
+ getSnapshot(sourceId: string): TrtcSourceSnapshot;
174
+ /**
175
+ * 检查指定 source 的 TRTC 会话是否曾收到过 REMOTE_VIDEO_AVAILABLE 事件。
176
+ */
177
+ hasRemoteVideoAvailable(sourceId: string): boolean;
178
+ /**
179
+ * 等待指定 source 的 TRTC 会话首次收到 REMOTE_VIDEO_AVAILABLE。
180
+ * - 若已收到过,立即返回 true。
181
+ * - 若会话被销毁或超时,返回 false。
182
+ */
183
+ waitForRemoteVideoAvailable(sourceId: string, timeoutMs?: number): Promise<boolean>;
184
+ /**
185
+ * 将一个渲染容器绑定到 source 会话:
186
+ * - 确保连接已建立
187
+ * - 回放历史已知远端视频轨道到该容器
188
+ * - 应用全局音频策略(根据所有 view 的 muted 汇总)
189
+ */
190
+ attachView(sourceId: string, viewId: string, container: HTMLElement, muted: boolean): Promise<void>;
191
+ detachView(sourceId: string, viewId: string): void;
192
+ updateViewMuted(sourceId: string, viewId: string, muted: boolean): void;
193
+ private createSession;
194
+ /**
195
+ * 懒连接入口:同一会话只允许一次并发 connectPromise。
196
+ * 建连后统一注册远端音视频事件,并持续向所有已绑定 view 分发渲染。
197
+ */
198
+ private ensureConnected;
199
+ private renderKnownRemoteVideosToView;
200
+ private startRemoteVideoForBinding;
201
+ /**
202
+ * 统一音频策略:
203
+ * - 所有 view 都 muted -> 全局静音
204
+ * - 至少一个 view 需出声 -> 对可用远端用户解除静音
205
+ */
206
+ private applyAudioPolicy;
207
+ /**
208
+ * 销毁单个 source 会话:
209
+ * 解绑事件、停止远端视频、退出房间并销毁客户端。
210
+ */
211
+ private disposeSession;
212
+ private emitSnapshot;
213
+ private log;
214
+ }
215
+
216
+ /**
217
+ * 协调者负责 runtime 生命周期、状态机和跨域补偿,不参与事件类型分发。
218
+ *
219
+ * 状态转移过程:
220
+ * 1) 初始态
221
+ * - 实例创建后默认状态为 `idle`。
222
+ *
223
+ * 2) 启动阶段
224
+ * - 调用 `start()` 后立即进入 `connecting`,并启动 dispatcher 与底层 WebSocket 连接。
225
+ * - 若连接失败,会执行 `stop()`,最终进入 `stopped`。
226
+ *
227
+ * 3) 会话建立后
228
+ * - 收到 `session.created` 后:
229
+ * - `syncStageOnSessionCreated !== false`(默认)时进入 `syncing`,并主动请求 `session.stage.get`。
230
+ * - `syncStageOnSessionCreated === false` 时直接进入 `running`。
231
+ *
232
+ * 4) 同步完成
233
+ * - 在 `syncing` 状态下收到由 `session.stage.get.response` 触发的 stage 变更后,切换为 `running`。
234
+ * - 若 stage 引用了本地缺失的 track/source,会触发 `session.tracks.list` / `session.sources.list` 补偿拉取;
235
+ * 拉取完成后进行一致性校验,缺失仍存在则抛错。
236
+ *
237
+ * 5) 运行中断开
238
+ * - 非 `idle` 状态下连接断开(`onConnectionChange(false)`)会重置运行态并进入 `stopped`。
239
+ *
240
+ * 6) 服务端结束会话
241
+ * - 收到 `session.ended` 时与连接断开类似:清空 managers、拒绝未完成的用户文本链路,并进入 `stopped`(不主动调用底层 `disconnect`,由连接自然关闭或业务方 `stop()`)。
242
+ * - 常见实现下 WebSocket 会先处理完已到达的文本消息再触发 `close`,故 `session.ended` 通常先于断连回调;若已进入 `stopped`,紧随的断连不会再次 reset,避免重复状态通知。
243
+ * - 若因网络等原因未收到 `session.ended` 仅断连,仍会通过 `onConnectionChange(false)` 进入 `stopped`,但 `config.onSessionEnded` 不会触发(需依赖 `onEvent` / 状态订阅区分)。
244
+ *
245
+ * 7) 主动停止
246
+ * - 调用 `stop()` 会停止 dispatcher、断开连接、清空运行态,并进入 `stopped`。
247
+ *
248
+ * 说明:
249
+ * - 当前实现中 `stopped` 为终止态语义;再次调用 `start()` 可重新进入新一轮生命周期(若连接已断需先保证 client 可再次 connect)。
250
+ */
251
+ declare class IviRuntimeCoordinator {
252
+ private readonly client;
253
+ private readonly config;
254
+ private readonly dispatcher;
255
+ private readonly sessionManager;
256
+ private readonly stageManager;
257
+ private readonly trackManager;
258
+ private readonly sourceManager;
259
+ private readonly streamManager;
260
+ private readonly trtcSourceManager;
261
+ private readonly conversationManager;
262
+ private readonly sessionHandler;
263
+ private readonly stageHandler;
264
+ private readonly trackHandler;
265
+ private readonly sourceHandler;
266
+ private readonly streamHandler;
267
+ private readonly conversationHandler;
268
+ private readonly stateListeners;
269
+ private readonly eventListeners;
270
+ private readonly pendingUserTextToResponseFlows;
271
+ private userTextFlowCounter;
272
+ private waitingTracksListValidation;
273
+ private waitingSourcesListValidation;
274
+ private state;
275
+ /**
276
+ * @param client 底层实时客户端,负责实际事件收发。
277
+ * @param config 协调行为配置(例如会话建立后的同步策略)。
278
+ */
279
+ constructor(client: IviClient, config?: IviRuntimeCoordinatorConfig);
280
+ /**
281
+ * 启动协调器并建立实时连接。
282
+ * 启动后状态会从 idle/stopped 进入 connecting,连接成功后由事件驱动进入后续状态。
283
+ */
284
+ start(): Promise<void>;
285
+ /**
286
+ * 停止协调器并断开实时连接,同时重置运行态数据为 stopped。
287
+ */
288
+ stop(): void;
289
+ getState(): IviRuntimeState;
290
+ onStateChange(listener: (state: IviRuntimeState) => void): () => void;
291
+ onEvent(listener: IviRuntimeEventListener): () => void;
292
+ /**
293
+ * 编排一次"用户文本输入 -> 触发模型回复"链路。
294
+ *
295
+ * 流程:
296
+ * 1) 发送 conversation.item.create(可指定 itemId);
297
+ * 2) 等待 conversation.item.added + conversation.item.done;
298
+ * 3) 发送 response.create(携带 item_reference,可选绑定 stream);
299
+ * 4) 等待 response.created 并结束。
300
+ */
301
+ sendUserTextAndTriggerResponse(options: IviRuntimeUserTextToResponseOptions): Promise<IviRuntimeUserTextToResponseResult>;
302
+ /**
303
+ * 上报某个 source 在指定 track 上播放完成。
304
+ *
305
+ * - 若 next 槽位为空,只发送 complete。
306
+ * - 若 next 槽位已有 source,立即将 next 提升为 active,并发送 complete 与 take。
307
+ * - 当前为普通视频/m3u8 且 next 为 TRTC source 时,等待 TRTC 远端视频可用后再切换并发送 complete/take。
308
+ */
309
+ sendSessionSourcePlaybackCompleted(sourceId: string, trackId?: string): void;
310
+ getTrtcSourceManager(): TrtcSourceManager;
311
+ private onConnectionChange;
312
+ private validateStageTracks;
313
+ private validateTracksListRefreshed;
314
+ reset(): void;
315
+ private onSessionCreated;
316
+ private onSessionEnded;
317
+ private onStageChanged;
318
+ private onTracksChanged;
319
+ private applyLocalTrackTake;
320
+ private deferredTrtcTakeCompleteAndTake;
321
+ private sendSessionTrackTake;
322
+ private onSourcesChanged;
323
+ private onStreamsChanged;
324
+ private onConversationsChanged;
325
+ private setState;
326
+ private emitEvent;
327
+ private resetStoppedState;
328
+ private ensureSourcesSyncedForTracks;
329
+ private validateSourcesListRefreshed;
330
+ private getMissingTrackIds;
331
+ private getMissingSourceIds;
332
+ private hasPendingResponseFlow;
333
+ private rejectPendingUserTextToResponseFlows;
334
+ private progressUserTextToResponseFlows;
335
+ private tryTriggerResponseCreate;
336
+ private buildUserTextItemId;
337
+ }
338
+
339
+ interface IviRuntimeEventHandler {
340
+ handle(event: ParsedIviEvent): void;
341
+ }
342
+ interface IviRuntimeDispatcherCallbacks {
343
+ sessionHandler: IviRuntimeEventHandler;
344
+ stageHandler: IviRuntimeEventHandler;
345
+ trackHandler: IviRuntimeEventHandler;
346
+ sourceHandler: IviRuntimeEventHandler;
347
+ streamHandler: IviRuntimeEventHandler;
348
+ conversationHandler: IviRuntimeEventHandler;
349
+ onConnectionChange: IviRuntimeConnectionListener;
350
+ onEvent?: (event: ParsedIviEvent) => void;
351
+ onLog?: IviRuntimeLogCallback;
352
+ }
353
+ declare class IviRuntimeDispatcher {
354
+ private readonly client;
355
+ private readonly callbacks;
356
+ private unsubscribeEvent;
357
+ private unsubscribeConnection;
358
+ constructor(client: IviClient, callbacks: IviRuntimeDispatcherCallbacks);
359
+ start(): void;
360
+ stop(): void;
361
+ private dispatchEvent;
362
+ }
363
+
364
+ declare class IviFrontendSdk {
365
+ createClient(config: IviClientConfig): IviClient;
366
+ createRuntimeCoordinator(clientConfig: IviClientConfig, runtimeConfig?: IviRuntimeCoordinatorConfig): IviRuntimeCoordinator;
367
+ }
368
+
369
+ interface IviStageSlotBinding {
370
+ slot: string;
371
+ trackId: string;
372
+ track?: IviTrack;
373
+ sourceId: string | null;
374
+ source?: IviRuntimeSource;
375
+ }
376
+ interface IviStageViewContextValue {
377
+ runtime: IviRuntimeCoordinator | null;
378
+ state: IviRuntimeState;
379
+ slotTrackMap: Map<string, string>;
380
+ slotBindings: IviStageSlotBinding[];
381
+ }
382
+
383
+ type IVIStageViewRenderChildren = (context: {
384
+ runtime: IviRuntimeCoordinator | null;
385
+ slotTrackMap: Map<string, string>;
386
+ slotBindings: IviStageSlotBinding[];
387
+ }) => ReactNode;
388
+ interface IVIStageViewProps {
389
+ children?: ReactNode | IVIStageViewRenderChildren;
390
+ className?: string;
391
+ style?: CSSProperties;
392
+ runtime: IviRuntimeCoordinator | null;
393
+ onBindingsChange?: (bindings: IviStageSlotBinding[]) => void;
394
+ onRuntimeEvent?: (event: ParsedIviEvent) => void;
395
+ }
396
+ /**
397
+ * 顶层舞台容器:负责把 runtime state 注入到内部 TrackSlot。
398
+ */
399
+ declare function IVIStageView(props: IVIStageViewProps): ReactElement;
400
+
401
+ declare const EMPTY_RUNTIME_STATE: IviRuntimeState;
402
+ declare function useRuntimeState(runtime: IviRuntimeCoordinator | null): IviRuntimeState;
403
+
404
+ interface IVITrtcPlayerProps {
405
+ trtc: IviSourcePlaybackTrtc;
406
+ sourceId?: string;
407
+ runtime?: IviRuntimeCoordinator | null;
408
+ className?: string;
409
+ style?: CSSProperties;
410
+ loadingFallback?: ReactNode;
411
+ errorFallback?: ReactNode;
412
+ muted?: boolean;
413
+ }
414
+
415
+ interface IVIVolumeControlColors {
416
+ /** 容器背景色,默认 rgba(0, 0, 0, 0.55) */
417
+ background?: string;
418
+ /** 前景色(图标、文字、滑块填充),默认 #fff */
419
+ foreground?: string;
420
+ /** 滑轨底色,默认 rgba(255, 255, 255, 0.25) */
421
+ trackBackground?: string;
422
+ /** 滑轨已填充部分颜色,默认同 foreground */
423
+ trackFill?: string;
424
+ }
425
+ interface IVIVolumeControlProps {
426
+ /** 当前音量 0-100 */
427
+ volume: number;
428
+ /** 音量变化回调 */
429
+ onVolumeChange: (volume: number) => void;
430
+ /** 自定义喇叭图标渲染,接收当前音量以决定显示状态 */
431
+ renderSpeakerIcon?: (volume: number) => ReactNode;
432
+ /** 颜色配置 */
433
+ colors?: IVIVolumeControlColors;
434
+ /** 自定义类名 */
435
+ className?: string;
436
+ /** 自定义样式 */
437
+ style?: CSSProperties;
438
+ }
439
+
440
+ interface IVISubtitleOverlayStyle {
441
+ /** 字体,默认 system-ui */
442
+ fontFamily?: string;
443
+ /** 字体大小,默认 14px */
444
+ fontSize?: number | string;
445
+ /** 字体颜色,默认 #fff */
446
+ color?: string;
447
+ /** 胶囊背景色,默认 rgba(0, 0, 0, 0.6) */
448
+ background?: string;
449
+ }
450
+ interface IVISubtitleOverlayProps {
451
+ /** 会话条目列表(由 runtime state 提供) */
452
+ conversations: IviRuntimeConversationItem[];
453
+ /** 要显示的发言人角色,默认 ["user"]。传单个字符串或数组均可。 */
454
+ roles?: IviConversationItemRole | IviConversationItemRole[];
455
+ /** 同时可见的最大条目数,默认 2 */
456
+ maxVisible?: number;
457
+ /** lifecycle 变为 done 后自动消失的毫秒数,默认 5000 */
458
+ dismissAfterMs?: number;
459
+ /** 样式配置 */
460
+ subtitleStyle?: IVISubtitleOverlayStyle;
461
+ /** 自定义类名 */
462
+ className?: string;
463
+ /** 自定义样式 */
464
+ style?: CSSProperties;
465
+ }
466
+
467
+ interface IviTrackSlotRenderContext {
468
+ slot: string;
469
+ track: IviTrack;
470
+ source: IviRuntimeSource;
471
+ /** 当前正在 standby 槽位预加载(不可见、已静音) */
472
+ isPreloading?: boolean;
473
+ }
474
+ /**
475
+ * 媒体空白区域(letterbox / pillarbox)背景模式。
476
+ * - `"black"` / `"white"` / `"transparent"`:纯色填充
477
+ * - `{ color: string }`:用户自定义 CSS 颜色
478
+ * - `"blur"`:实时高斯模糊(等同 `{ blur: "live" }`)
479
+ * - `{ blur: "live" }`:实时模糊,背景跟随媒体画面持续更新
480
+ * - `{ blur: "static" }`:静态模糊,仅取首帧进行模糊,性能开销极低
481
+ */
482
+ type IviTrackSlotBackground = "black" | "white" | "transparent" | {
483
+ color: string;
484
+ } | "blur" | {
485
+ blur: "live" | "static";
486
+ };
487
+ interface IVITrackSlotProps {
488
+ slot?: string;
489
+ trackId?: string;
490
+ className?: string;
491
+ style?: CSSProperties;
492
+ emptyFallback?: ReactNode;
493
+ renderTrtc?: (context: IviTrackSlotRenderContext) => ReactNode;
494
+ renderMedia?: (context: IviTrackSlotRenderContext) => ReactNode;
495
+ videoProps?: Omit<VideoHTMLAttributes<HTMLVideoElement>, "src">;
496
+ imageProps?: Omit<ImgHTMLAttributes<HTMLImageElement>, "src">;
497
+ adaptToSourceSize?: boolean;
498
+ fitStrategy?: "contain" | "cover" | "auto";
499
+ trtcPlayerProps?: Omit<IVITrtcPlayerProps, "trtc" | "sourceId" | "runtime">;
500
+ /** 是否显示音量控制浮层(仅在播放音视频媒体时生效,图片无音量) */
501
+ showVolumeControl?: boolean;
502
+ /** 音量控制组件的自定义配置(图标、颜色、样式等) */
503
+ volumeControlProps?: Omit<IVIVolumeControlProps, "volume" | "onVolumeChange">;
504
+ /** 是否显示字幕浮层(仅在支持字幕的播放源上生效) */
505
+ showSubtitle?: boolean;
506
+ /** 字幕组件的自定义配置(字体、颜色、消失延时等) */
507
+ subtitleProps?: Omit<IVISubtitleOverlayProps, "conversations">;
508
+ /** 媒体空白区域(letterbox/pillarbox)的背景模式,默认 "black" */
509
+ background?: IviTrackSlotBackground;
510
+ }
511
+ /**
512
+ * Track 窗口组件:基于多重预加载策略渲染所有 ready 的 Source。
513
+ * 每个 ready 且拥有合法 playback 的 Source 都会挂载为不可见元素提前预加载,
514
+ * active Source 通过 CSS 可见性切换显示,切换时无 DOM 重建。
515
+ * 每个 Source 以 sourceId 为 React key,保证增删其他 Source 不影响已有预加载。
516
+ */
517
+ declare function IVITrackSlot(props: IVITrackSlotProps): ReactNode;
518
+
519
+ type IviManagedRuntimeLogLevel = "info" | "warn" | "error";
520
+ type IviManagedRuntimeLogSource = "client" | "runtime";
521
+ interface IviManagedRuntimeLogEntry {
522
+ level: IviManagedRuntimeLogLevel;
523
+ source: IviManagedRuntimeLogSource;
524
+ tag: string;
525
+ message: string;
526
+ args: unknown[];
527
+ data?: unknown;
528
+ clientLog?: IviClientLogEntry;
529
+ runtimeLog?: IviRuntimeLogEntry;
530
+ }
531
+ type IviManagedRuntimeLogCallback = (entry: IviManagedRuntimeLogEntry) => void;
532
+ interface IviManagedRuntimeConfig {
533
+ clientConfig: IviClientConfig;
534
+ autoStart?: boolean;
535
+ runtimeConfig?: IviRuntimeCoordinatorConfig;
536
+ onRuntimeInitError?: (error: unknown) => void;
537
+ /**
538
+ * 统一收集 SDK 内部带 IVI 标记的日志。
539
+ *
540
+ * - IviClient 的 onLog 会被转换为 `[IVI-SEND]`、`[IVI-WS]`、`[IVI-RECONNECT]`
541
+ * - runtime / TRTC 等日志会通过 runtime onLog 回调上报,不会通过 patch console 收集
542
+ */
543
+ onLog?: IviManagedRuntimeLogCallback;
544
+ }
545
+ declare function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRuntimeCoordinator | null;
546
+
547
+ declare function useIviStageView(): IviStageViewContextValue;
548
+
549
+ export { EMPTY_RUNTIME_STATE, IVIStageView, type IVIStageViewProps, IVITrackSlot, type IVITrackSlotProps, IviFrontendSdk, type IviManagedRuntimeConfig, type IviManagedRuntimeLogCallback, type IviManagedRuntimeLogEntry, type IviManagedRuntimeLogLevel, type IviManagedRuntimeLogSource, type IviRuntimeConversationItem, type IviRuntimeConversationLifecycle, type IviRuntimeConversationStatus, IviRuntimeCoordinator, type IviRuntimeCoordinatorConfig, IviRuntimeDispatcher, type IviRuntimeDispatcherConfig, type IviRuntimeEventListener, type IviRuntimeLogCallback, type IviRuntimeLogEntry, type IviRuntimeLogLevel, type IviRuntimeSource, type IviRuntimeSourcePreloadState, type IviRuntimeState, type IviRuntimeStatus, type IviRuntimeStream, type IviRuntimeUserTextToResponseCallbacks, type IviRuntimeUserTextToResponseOptions, type IviRuntimeUserTextToResponseResult, type IviStageSlotBinding, type IviStageViewContextValue, type IviTrackSlotBackground, useIviStageView, useManagedIviRuntime, useRuntimeState };