type XmaxTelemetryParams = Record; type XmaxReportSource = 'open_platform' | 'external_developer'; type XmaxTelemetryEventName = 'sdk_api_request' | 'sdk_capture_get_user_media_start' | 'sdk_capture_get_user_media_end' | 'sdk_asset_sts_request' | 'sdk_asset_sts_response' | 'sdk_asset_upload_start' | 'sdk_asset_upload_end' | 'sdk_api_session_request' | 'sdk_api_session_response' | 'sdk_rtc_join_request' | 'sdk_rtc_join_response' | 'sdk_rtc_publish_local_track' | 'sdk_generation_request_sent' | 'sdk_generation_ack_received' | 'sdk_rtc_subscribe_remote_track' | 'sdk_render_output_first_frame' | 'sdk_context_set_request' | 'sdk_context_set_response' | 'sdk_session_connect' | 'sdk_session_state_change' | 'sdk_session_error' | 'sdk_session_disconnect' | 'sdk_rtc_stats_snapshot' | 'sdk_rtc_remote_state_change' | 'sdk_rtc_connection_state_change' | 'sdk_rtc_token_state_change' | 'sdk_rtc_teardown' | 'sdk_probe_degraded' | 'sdk_probe_health' | 'sdk_probe_buffer_overflow'; type XmaxTelemetryEvent = { name: XmaxTelemetryEventName; params: XmaxTelemetryParams; }; type XmaxTelemetryOptions = { /** Override the region-specific Xmax ingestion endpoint. */ endpoint?: string; /** Override the region-specific remote probe configuration endpoint, or disable remote config. */ configEndpoint?: string | false; /** Optional extra public fields. Never pass credentials or media/prompt content. */ commonParams?: XmaxTelemetryParams; /** @internal Test/custom transport hook. It runs outside the business request path. */ reporter?: (events: readonly XmaxTelemetryEvent[]) => void | Promise; }; /** Configure once before creating clients; false opts out and drops pending diagnostics. */ declare function configureXmaxTelemetry(options: XmaxTelemetryOptions | false): void; /** Deployment region baked into each published SDK package by tsup. */ type XmaxSdkRegion = 'cn' | 'global'; /** Default UI/error language associated with the published package. */ declare const XMAX_SDK_DEFAULT_LOCALE: 'zh-CN' | 'en-US'; type XmaxProbeOptions = { /** Healthy-session sampling rate. Abnormal sessions are always retained. @default 1 */ samplingRate?: number; /** Sliding RTC statistics window. @default 10000 */ windowDurationMs?: number; /** Promote a slow first-frame session to full retention. Omit until the first P95 is known. */ e2eThresholdMs?: number; /** Enable passive RTC statistics collection. @default true */ rtcStatsEnabled?: boolean; }; type ResolvedXmaxProbeConfig = { samplingRate: number; windowDurationMs: number; e2eThresholdMs?: number; rtcStatsEnabled: boolean; }; declare const XMAX_TELEMETRY_CONFIG_ENDPOINTS: Record; declare const XMAX_TELEMETRY_DEFAULT_CONFIG_ENDPOINT: string; declare const RTC_METRIC_NAMES: readonly ["up_rtt_ms", "down_rtt_ms", "jitter_ms", "up_loss_rate", "down_loss_rate", "up_bitrate_kbps", "down_bitrate_kbps", "up_fps", "down_decode_fps", "down_render_fps", "down_receive_fps"]; type RtcMetricName = typeof RTC_METRIC_NAMES[number]; type StartupStage = 'media_prepare' | 'session_api' | 'rtc_prepare' | 'camera_capture' | 'camera_audio' | 'rtc_join' | 'camera_ready' | 'publish' | 'outbound_ready' | 'start_send' | 'context_set' | 'remote_bind' | 'wait_first_frame' | 'streaming'; /** Stable values accepted by `session.disconnect.attrs.reason_code`. */ declare const XMAX_DISCONNECT_REASON_CODES: readonly ["client_disconnect", "client_background_timeout", "client_session_replaced", "client_context_disposed", "session_inactive", "heartbeat_error", "remote_output_stalled", "remote_unpublished", "remote_user_left", "remote_first_frame_timeout", "local_outbound_zero_sent_frame_rate", "local_outbound_track_ended", "local_outbound_track_muted", "rtc_async_error", "rtc_reconnect_timeout", "media_prepare_failed", "camera_capture_failed", "audio_capture_failed", "session_api_failed", "rtc_prepare_failed", "rtc_join_failed", "camera_ready_failed", "local_publish_failed", "local_outbound_not_ready", "generation_start_failed", "context_update_failed", "remote_bind_failed", "generation_stop_failed", "local_stream_stop_failed", "rtc_leave_failed", "session_close_failed", "media_cleanup_failed", "connect_failed", "session_error", "pagehide"]; type XmaxDisconnectReasonCode = typeof XMAX_DISCONNECT_REASON_CODES[number]; /** One non-blocking diagnostic trace for the complete realtime connection lifecycle. */ declare class StartupTrace { private readonly context; private readonly localProbe?; readonly traceId: string; /** @deprecated Compatibility alias for the earlier startup-only diagnostics. */ readonly callId: string; readonly startedAt: number; readonly startedAtEpochMs: number; done: boolean; outcome?: string; private readonly times; private readonly stats; private readonly terminalContext; private readonly marks; private readonly rtcStats; private probeConfig; private readonly bufferedEvents; private buffering; private retained; private stage; private stageStartedAt; private seq; private connectedAt?; private firstFrameAt?; private generationSentAt?; private generationAckAt?; private generationId?; private rtcSamples; private periodicTimer?; private snapshotTimer?; private snapshotReason?; private readonly unregisterSnapshot; private bufferedBytes; private bufferedDrops; private criticalFlushes; private errorRecorded; private terminalFailure?; private backgroundSeen; private pageHiding; private readonly onVisibility; private readonly onPageHide; constructor(context: XmaxTelemetryParams, localProbe?: XmaxProbeOptions | undefined); get params(): XmaxTelemetryParams; eventContext(): XmaxTelemetryParams; offset(at?: number): number; get currentStage(): StartupStage; /** @internal Immutable copy for the final public disconnect callback. */ get terminalFailureDetails(): Readonly | undefined; get rtcStatsEnabled(): boolean; rtcEvidence(): XmaxTelemetryParams; private schedulePeriodicSnapshot; setContext(params: XmaxTelemetryParams): void; setTerminalContext(params: XmaxTelemetryParams): void; record(name: XmaxTelemetryEventName, params?: XmaxTelemetryParams): void; private bufferEvent; private retainFullSession; enter(stage: StartupStage): void; complete(stage: StartupStage, startedAt: number): void; measure(stage: StartupStage, operation: () => Promise): Promise; mark(name: string): void; markConnected(): void; setGeneration(generationId: string): void; clearGeneration(generationId?: string | null): void; generationSent(params?: XmaxTelemetryParams): void; generationAckReceived(generationId: string, params?: XmaxTelemetryParams): void; firstFrame(params?: XmaxTelemetryParams): void; updateStats(params: XmaxTelemetryParams): void; recordRtcStats(values: Partial>, stalls?: { count?: number; durationMs?: number; }): void; recordRtcSnapshot(reason: string): void; private snapshotParams; recordError(params: XmaxTelemetryParams): void; private flushCritical; finish(outcome: 'success' | 'error' | 'cancelled' | 'connected' | 'abandoned' | 'unobserved', params?: XmaxTelemetryParams): void; private finishInternal; private disposeAfterProbeFailure; } /** Domestic and overseas ingestion routes baked into each regional SDK build. */ declare const XMAX_TELEMETRY_ENDPOINTS: Record; declare const XMAX_TELEMETRY_DEFAULT_ENDPOINT: string; declare function isTelemetryEndpointConfigured(endpoint: string | undefined): endpoint is string; type XmaxTelemetryNetworkMeta = { api_supported: boolean; online?: boolean; effective_type?: string; connection_type?: string; rtt_ms?: number; downlink_mbps?: number; save_data?: boolean; }; type XmaxTelemetryDeviceMeta = { language?: string; hardware_concurrency?: number; device_memory_gb?: number; max_touch_points?: number; }; type XmaxTelemetryProbeMeta = { sent: number; dropped: number; retried: number; exempted: number; }; type XmaxTelemetryMetricSummary = { avg?: number; min?: number; max?: number; p50: number | null; p90: number | null; sample_count: number; }; type XmaxTelemetryRtcStatsBlock = { duration_ms?: number; sample_count: number; metrics: Record; }; type XmaxTelemetryRtcStats = { snapshot_reason?: string; current_stage?: string; current_stage_elapsed_ms?: number; stats_started_offset_ms?: number; stats_last_offset_ms?: number; up_stats_age_ms?: number; down_stats_age_ms?: number; sampling_source?: string; down_stall_count?: number; down_stall_duration_ms?: number; window: XmaxTelemetryRtcStatsBlock; cumulative: XmaxTelemetryRtcStatsBlock; }; type XmaxTelemetryMeta = { trace_id: string; session_id: string | null; generation_id?: string; page_id: string; sdk_version: string; env: string; report_source: XmaxReportSource; ua: string; t0: number; ts: number; seq: number; probe: XmaxTelemetryProbeMeta; network: XmaxTelemetryNetworkMeta; device: XmaxTelemetryDeviceMeta; api_key_md5?: string; model?: string; auto_start?: boolean; stream?: { width?: number; height?: number; fps?: number; }; [key: string]: unknown; }; type XmaxTelemetryWireEvent = { event: string; offset: number; duration?: number; attrs?: XmaxTelemetryParams; }; /** One document-compatible envelope. */ type XmaxTelemetryEnvelope = { meta: XmaxTelemetryMeta; rtc_stats: XmaxTelemetryRtcStats | null; events: XmaxTelemetryWireEvent[]; }; type XmaxTelemetryPayload = XmaxTelemetryEnvelope; /** * Open API business error codes (46xxx) mapped to user-facing messages. * Source: Open API v1 error code tables. Codes not listed here fall back to the * backend `message` when present, otherwise a generic retry message for Open * API endpoints (see `errors.requestRetry`). */ type LocalizedMessage = Record; declare const API_ERROR_MESSAGES: Record; /** Resolve a business error code to a localized message, or `undefined` if unmapped. */ declare function resolveApiErrorMessage(code: string | number | null | undefined, locale: SDKLocale): string | undefined; type SDKLocale = 'en-US' | 'zh-CN'; type SDKMessages = Record; type SDKI18n = { locale: SDKLocale; t: (key: string, params?: Record) => string; }; declare function getDefaultMessages(locale: SDKLocale): SDKMessages; declare function createSDKI18n(input?: { locale?: SDKLocale; messages?: Record; t?: SDKI18n['t']; }): SDKI18n; /** Optional, privacy-safe evidence. A disconnect trigger is not a confirmed root cause. */ type XmaxErrorDetails = Readonly<{ reason_code?: XmaxDisconnectReasonCode; failure_stage?: string; trace_id?: string; session_id?: string; generation_id?: string; failure_type?: 'business_error' | 'http_error' | 'timeout' | 'network_error' | 'invalid_response' | 'cancelled'; http_status?: number; business_code?: string; rtc_error_code?: string; connection_state?: string; connection_reason?: string; connection_recovered?: boolean; connection_interrupted_at_ms?: number; connection_recovered_at_ms?: number; network_online?: boolean; detection_source?: string; stall_ms?: number; reconnect_timeout_ms?: number; heartbeat_failure_trigger?: string; session_status?: string; server_close_reason?: string; teardown_failure_stages?: string; }>; type XmaxErrorCode = 'INVALID_API_KEY' | 'INVALID_MODEL' | 'INVALID_INPUT' | 'UNSUPPORTED_MEDIA' | 'MEDIA_PROCESSING_ERROR' | 'CAMERA_ERROR' | 'NETWORK_ERROR' | 'API_ERROR' | 'WEB_RTC_ERROR' | 'SESSION_ERROR' | 'OFFLINE_TASK_TIMEOUT' | 'UNKNOWN_ERROR'; /** Public SDK error contract: stable code/message plus optional immutable diagnostic details. */ declare class XmaxSdkError extends Error { readonly code: XmaxErrorCode; readonly details?: XmaxErrorDetails; constructor(code: XmaxErrorCode, message: string); } declare function isXmaxSdkError(error: unknown): error is XmaxSdkError; /** SDK error callback. The first message argument preserves existing integrations. */ type XmaxErrorNotifier = (message: string, error: XmaxSdkError) => void; /** Region → official Open API v1 production base URL. */ declare const XMAX_OPEN_API_BASE_URLS: Record; /** * Official Xmax Open Platform production API base URL (Open API v1) for the * region this package was built for: * - `@xmaxai/sdk` (cn): https://api.xmaxai.com/open/api/v1 * - `@xmaxai/sdk-global`: https://api.xmax.ai/open/api/v1 */ declare const XMAX_OPEN_API_PRODUCTION_BASE_URL: string; declare const ACTIVE_STATUS = "ACTIVE"; interface ModelExtra { room_id?: string; bot_name?: string; user_id?: string; rtc_app_id?: string; room_token?: string; } interface Session { sessionUid: string; userUid?: string; modelTypeUid?: string; modelTypeName?: string; modelUid?: string; modelExtra?: ModelExtra; status?: string; lastHeartbeatTimestamp?: string; closeTimestamp?: string | null; closeReason?: string | null; createTimestamp?: string; updateTimestamp?: string; } interface StsCredentials { accessKeyId: string; secretAccessKey: string; sessionToken: string; } interface CosSts { type: string; bucket: string; region: string; /** Overseas upload host (optional HTTP(S) scheme); also used as a returned URL fallback. */ endpoint: string; prefix: string; credentials: StsCredentials; } interface UploadImageResult { key: string; url: string; raw: unknown; sts: CosSts; } interface UploadVideoResult { key: string; url: string; raw: unknown; sts: CosSts; } interface RtcJoinInfo { appId: string; roomId: string; userId: string; token: string; botName?: string; } interface XmaxLogEntry { id: string; level: "info" | "success" | "warn" | "error"; message: string; data?: unknown; timestamp: string; } interface ClientOptions { apiKey?: string; /** Open API base URL, e.g. {@link XMAX_OPEN_API_PRODUCTION_BASE_URL}. */ baseUrl: string; authToken?: string; timeoutMs?: number; locale?: SDKLocale; i18n?: SDKI18n; /** Receives asynchronous errors as `(message, XmaxSdkError)`. */ onError?: XmaxErrorNotifier; /** Set false to disable SDK diagnostics for this client. */ telemetry?: boolean; reportSource?: XmaxReportSource; /** @internal Correlates requests with a realtime startup. */ telemetryContext?: () => XmaxTelemetryParams | undefined; /** @internal Records into a realtime trace so event ordering remains exact. */ telemetryRecord?: (name: XmaxTelemetryEventName, params: XmaxTelemetryParams) => void; } type RequestOptions = { signal?: AbortSignal; }; declare class XmaxOpenClient { private readonly apiKey; private readonly authToken; private readonly baseUrl; private readonly timeoutMs; private readonly telemetry; private readonly telemetryContext; private readonly telemetryRecord; private readonly telemetryBase; private readonly i18n; private readonly onError; private stsCache; private heartbeatIntervalId; private heartbeatGeneration; private suppressErrorNotification; private teardownAbortController; private readonly pendingRequestControllers; constructor(options: ClientOptions); private throwError; /** Stop heartbeat, abort in-flight API requests, and suppress error notifications during teardown. */ beginTeardown(): void; endTeardown(): void; /** Normalize browser-specific fetch failures (Chrome, Safari, Firefox). */ private isNetworkError; request(method: string, path: string, body?: unknown, options?: RequestOptions, telemetryParams?: XmaxTelemetryParams): Promise; createSession(model: string): Promise; getSession(sessionUid: string): Promise; heartbeatSession(sessionUid: string): Promise; closeSession(sessionUid: string): Promise; getCosSts(forceRefresh?: boolean, options?: RequestOptions, telemetryParams?: XmaxTelemetryParams): Promise; /** Only overseas builds use the upload endpoint supplied by the STS service. */ private resolveCosUploadEndpoint; private uploadObject; uploadImage(file: File, options?: RequestOptions): Promise; uploadVideo(file: File, options?: RequestOptions): Promise; /** * Upload an image then run `/cos/image/check`. * Returns the same upload metadata as {@link uploadImage}, with the checked URL. */ uploadAndCheckImage(file: File, options?: RequestOptions): Promise; startHeartbeat(sessionUid: string, intervalMs?: number, onHeartbeat?: (session: Session, diagnostics?: XmaxTelemetryParams) => void, onError?: (error: XmaxSdkError, diagnostics?: XmaxTelemetryParams) => void): void; stopHeartbeat(): void; getRtcJoinInfo(session: Session): RtcJoinInfo; } type StartRtcRoomEvent = { event: "start"; user_id?: string; uid?: string; session_uid?: string; params: { model: string; size: [number, number]; prompt: string; ref_image_path?: string; ref_image?: string; static_generate?: boolean; /** COS URL for `static_image_path` on this start; omit when unused. */ static_image_path?: string; /** Whether the backend should horizontally flip the camera input. */ mirror: boolean; } & Record; }; type ChangeConditionRtcRoomEvent = { event: "change_condition"; user_id?: string; session_uid?: string; params: { model: string; size: [number, number]; prompt: string; ref_image_path?: string; ref_image?: string; static_generate?: boolean; /** COS URL for `static_image_path` on this start; omit when unused. */ static_image_path?: string; } & Record; }; type StopRtcRoomEvent = { event: "stop"; user_id?: string; session_uid?: string; }; type TracksRtcRoomEvent = { event: "tracks"; user_id?: string; uid?: string; session_uid?: string; tracks: Array<[number, number]>; }; type RtcRoomEvent = StartRtcRoomEvent | ChangeConditionRtcRoomEvent | StopRtcRoomEvent | TracksRtcRoomEvent; /** Generation task id sent as `uid` / `session_uid` in RTC room events. */ declare function createTaskUid(): string; declare function createStartRtcRoomEvent(input: { userId?: string; uid?: string; sessionUid?: string; model: string; size: [number, number]; prompt?: string; refImagePath?: string; refImage?: string; /** When `true`, sent as `static_generate` on this start only. */ staticGenerate?: boolean; /** COS URL sent as `static_image_path` on this start only. */ staticImagePath?: string; /** Whether the backend should horizontally flip the camera input. */ mirror: boolean; extraParams?: Record; }): StartRtcRoomEvent; declare function createChangeConditionRtcRoomEvent(input: { userId?: string; sessionUid?: string; model: string; size: [number, number]; prompt?: string; refImagePath?: string; refImage?: string; /** When `true`, sent as `static_generate` on this change only. */ staticGenerate?: boolean; /** COS URL sent as `static_image_path` on this change only. */ staticImagePath?: string; extraParams?: Record; }): ChangeConditionRtcRoomEvent; declare function createStopRtcRoomEvent(input: { userId?: string; sessionUid?: string; }): StopRtcRoomEvent; declare function createTracksRtcRoomEvent(input: { userId?: string; uid?: string; sessionUid?: string; tracks: Array<[number, number]>; }): TracksRtcRoomEvent; type RemoteFailure = 'remote_output_stalled' | 'remote_stats_timeout' | 'remote_unpublished' | 'remote_user_left' | 'rtc_reconnect_timeout'; type RemoteStallInfo = { userId: string; stallMs: number; reason?: RemoteFailure; diagnostics?: XmaxTelemetryParams; }; /** Mobile is below 592px; 592px and above uses Web publishing settings. */ declare const MOBILE_PUBLISH_MAX_WIDTH_PX = 591; declare const RTC_PUBLISH_FPS_WEB = 30; declare const RTC_PUBLISH_FPS_MOBILE = 24; type ResolveRtcPublishFpsOptions = { /** When set, skips viewport detection. */ mobile?: boolean; /** Explicit fps override. */ fps?: number; /** Upload/file publish — use detail encoding and higher max bitrate. */ highQuality?: boolean; }; declare function isMobilePublishEnvironment(): boolean; declare function resolveRtcPublishFps(options?: ResolveRtcPublishFpsOptions): number; declare function resolveRtcPublishFrameIntervalS(options?: ResolveRtcPublishFpsOptions): number; /** Web @ 30fps — use {@link resolveRtcPublishFrameIntervalS} when mobile-aware. */ declare const RTC_PUBLISH_FRAME_INTERVAL_S: number; declare const RTC_PUBLISH_FRAME_INTERVAL_MS: number; /** Tolerance when comparing media-time deltas (seconds). */ declare const MEDIA_TIME_EPSILON_S = 0.001; /** Media time jumped backward beyond this threshold — treat as loop/seek reset. */ declare const MEDIA_TIME_LOOP_JUMP_S = 0.05; type RemoteSeiReceivedPayload = { sei: string; userId: string; }; type SeiGateState = { expectedSei: string | null; sei: string | null; userId: string | null; matched: boolean; }; type RtcSessionSeiOptions = { repeatCount?: number; }; interface RtcLogEntry { level: "info" | "success" | "warn" | "error"; message: string; data?: unknown; } interface RtcStateSnapshot { roomId: string | null; userId: string | null; appId: string | null; botUserId: string | null; joined: boolean; localVideoPublished: boolean; remoteVideoUserId: string | null; users: string[]; } interface RtcManagerOptions { /** @internal Passive startup diagnostics; contains no business callbacks. */ diagnostics?: StartupTrace; /** SDK-managed local/remote media fit from RealtimeRenderSetting. */ renderFit?: "cover" | "contain"; /** Whether to subscribe to and play remote output audio. */ playRemoteAudio?: boolean; onLog?: (entry: RtcLogEntry) => void; onStateChange?: (state: RtcStateSnapshot) => void; onSeiGateChange?: (state: SeiGateState) => void; /** Fired when Volcengine RTC reports an unrecoverable asynchronous engine error. */ onError?: (error: RtcAsyncErrorInfo) => void; /** Fired when the first remote video frame is rendered for the active bot stream. */ onRemoteVideoFirstFrame?: (info: { userId: string; width: number; height: number; }) => void; /** Fired for H.264 SEI received on a remote (non-local) stream. */ onRemoteSeiReceived?: (payload: RemoteSeiReceivedPayload) => void; /** Fired when remote output stops presenting new frames after playback had started. */ onRemoteOutputStalled?: (info: RemoteStallInfo) => void; /** Fired after the remote player is mounted (used to forward MediaStream via onRemoteStream). */ onRemotePlayerMounted?: () => void; /** Fired when an RTC room message is received and parsed. */ onRoomEvent?: (event: Record) => void; /** Fired after a remote user joins the current RTC room. */ onUserJoined?: (userId: string) => void; debug?: boolean; i18n?: SDKI18n; } type RtcAsyncErrorInfo = { errorCode: string; forbiddenTime?: number; cause: unknown; }; type VideoSize = [number, number]; type VideoContentHint = "text" | "motion" | "detail"; type RtcVideoEncoderPreferenceOptions = ResolveRtcPublishFpsOptions & { maxKbps?: number; contentHint?: VideoContentHint; audioTrack?: MediaStreamTrack; }; type ExternalVideoPublishDeadlines = { externalSourceMs: number; encoderMs: number; publishMs: number; timeoutMessage: string; }; /** First-output watchdog: cleared only after a remote frame is actually presented. */ declare const REMOTE_FIRST_OUTPUT_TIMEOUT_MS = 15000; declare const RTC_RECONNECT_TIMEOUT_MS = 60000; type LocalOutboundStallInfo = { reason: "zero-sent-frame-rate" | "track-ended" | "track-muted"; consecutiveZeroStats: number; stallMs: number; lastSentFrameRate: number; }; declare class RtcManager { private engine; private leaveTask; private stopPublishingTask; private readonly users; private currentJoinInfo; private joined; private preserveRemoteDom; private localVideoPublished; private localAudioPublished; private internalVideoCaptureStarted; private internalAudioCaptureStarted; private localVideoSourceType; private externalVideoTrack; private externalAudioTrack; private remoteVideoUserId; private pendingRemoteVideoUserId; private pendingRemoteVideoMediaType; /** Subscribed to RTC media; render may still wait on SEI match. */ private subscribedRemoteUserId; private subscribedRemoteMediaType; private readonly onLog; private readonly onStateChange; private readonly onSeiGateChange; private onError; private onRemoteVideoFirstFrame; private readonly onRemoteSeiReceived; private onRemoteOutputStalled; private onRemotePlayerMounted; private onRoomEvent; private onUserJoined; private remoteFirstOutputTimer; private onRemoteFirstOutputTimeout; private localVideoContainer; private remoteVideoContainer; private activeGenerationId; private expectedRemoteSei; private lastRemoteSei; private lastRemoteSeiUserId; private localVideoFrameRate; private readonly seiSender; private seiSupport; private hasLoggedSeiUnsupported; private readonly debug; private lastDebugSeiMatched; private lastDebugRemoteSei; private remoteFrameWatchStop; private uploadPreviewLayoutObserverStop; private remoteOutputRecoveryCooldownUntil; private readonly i18n; private readonly renderFit; private readonly playRemoteAudio; private joinedAtMs; private publishStartedAtMs; private lastRoomStartEventAtMs; private localStreamStatsCount; private firstNonZeroSentFrameRateAtMs; private lastObservedSentFrameRate; private localVideoDegradationPreference; private localOutboundWatch; private readonly localOutboundReadyWaiters; private seiGateFallbackTimer; private seiMatchedDelayTimer; private lastSentResolution; private lastReceivedResolution; private diagnostics?; private nativeSampler?; private readonly nativeMetricAt; private readonly diagnosticSampleAt; private readonly remoteQuality; private qualityTimer?; private qualityHadFrame; private qualityUserId?; private qualityWasHidden; private readonly onQualityVisibility; private diagnosticConnectionChanges; private connectionState?; private connectionReason?; private reconnectStartedAt?; private reconnectTimer?; private connectionRecoveredAt; private connectionInterruptedAtEpoch?; private connectionRecoveredAtEpoch?; private tearingDown; private static readonly SEI_GATE_FALLBACK_MS; private static readonly SEI_MATCHED_DISPLAY_DELAY_MS; constructor(options?: RtcManagerOptions); private isSignalingConnected; beginTeardown(): void; /** @internal Read cached connection evidence; never poll RTC or perform I/O here. */ getConnectionDiagnostics(): Record; private handleConnectionStateChange; private teardownOperation; /** @internal Allows an explicit manual start to have its own startup trace. */ setDiagnostics(trace?: StartupTrace): void; private startNativeSampler; stopRemoteQualityWatch(): void; private startRemoteQualityWatch; private recordRemoteState; private recordDiagnosticStats; private recordDiagnosticStatsInternal; private emitSeiGateState; setOnError(handler: RtcManagerOptions["onError"]): void; setOnRemoteOutputStalled(handler: RtcManagerOptions["onRemoteOutputStalled"]): void; setOnRemoteVideoFirstFrame(handler: RtcManagerOptions["onRemoteVideoFirstFrame"]): void; private emitRemoteVideoFirstFrame; /** * Arm first-output deadline immediately after the RTC `start` event is sent. */ armRemoteFirstOutputWatch(options: { timeoutMs?: number; onTimeout: () => void; }): void; clearRemoteFirstOutputWatch(): void; /** * Last-chance synchronous verification for a missed vendor/browser frame event. * Reading media readiness is non-blocking and does not force layout. */ confirmRemoteVideoFirstFrame(): boolean; /** * Passively watch RTC outbound stats after start. It never touches the source track, * canvas, or encoder; only sustained zero fps (or an ended track) triggers failure. */ armLocalOutboundWatch(options: { onStalled: (info: LocalOutboundStallInfo) => void; minZeroSamples?: number; minStallMs?: number; startGraceMs?: number; resumeGraceMs?: number; }): void; clearLocalOutboundWatch(): void; setPreserveRemoteDom(preserve: boolean): void; setOnRemotePlayerMounted(callback: RtcManagerOptions["onRemotePlayerMounted"]): void; setOnRoomEvent(callback: RtcManagerOptions["onRoomEvent"]): void; setOnUserJoined(callback: RtcManagerOptions["onUserJoined"]): void; setLocalVideoContainer(container: HTMLElement | null): void; setRemoteVideoContainer(container: HTMLElement | null): void; /** Tag every local encoded frame with the task id and gate display on matching remote SEI. */ configureSessionSei(sessionId: string | null, options?: RtcSessionSeiOptions): void; private clearSeiGateFallbackTimer; private clearSeiMatchedDelayTimer; /** Mark SEI matched if remote SEI never arrives — display gate only; RTC bind is not blocked. */ private scheduleSeiGateFallback; get snapshot(): RtcStateSnapshot; getLocalVideoSize(): { width: number; height: number; } | null; getInternalVideoTrack(): MediaStreamTrack | null; prepareEngine(joinInfo: RtcJoinInfo): Promise; joinPreparedRoom(): Promise; join(joinInfo: RtcJoinInfo): Promise; startInternalVideoCapture(options?: { encoderSize?: VideoSize; encoderFps?: number; encoderMaxKbps?: number; encoderContentHint?: VideoContentHint; facingMode?: 'user' | 'environment'; }): Promise; publishInternalVideo(): Promise; startInternalAudioCapture(): Promise; startExternalVideoPublishing(track: MediaStreamTrack, encoderSize: VideoSize, publishOptions: RtcVideoEncoderPreferenceOptions, deadlines?: ExternalVideoPublishDeadlines): Promise; private runExternalPublishStage; stopVideoPublishing(options?: { preserveExternalTrack?: boolean; preserveRemote?: boolean; }): Promise; private stopVideoPublishingInternal; leave(options?: { preserveExternalTrack?: boolean; }): Promise; /** Subscribe to the remote output stream before start. */ prepareRemoteVideoForGeneration(): Promise; sendRoomEvent(event: unknown): Promise; /** Send a control event directly to one user in the current RTC room. */ sendUserEvent(userId: string, event: unknown): Promise; /** Best-effort room control message. Returns false instead of throwing or blocking callers. */ trySendRoomEvent(event: unknown): Promise; /** Best-effort direct control message. Returns false instead of throwing or blocking callers. */ trySendUserEvent(userId: string, event: unknown): Promise; clearRemoteVideo(options?: { preserveDom?: boolean; }): void; refreshRemoteVideoBinding(options?: { force?: boolean; }): Promise; private refreshRemoteVideoBindingBestEffort; private attachRemoteVideoBestEffort; private bindEngineEvents; private emitState; private ensureReadyForMessaging; private bindLocalVideoPlayer; private bindUploadPreviewLayout; private clearUploadPreviewLayoutObserver; /** Re-bind local preview after the container becomes visible or is resized. */ refreshLocalVideoPreview(options?: { force?: boolean; }): void; getLastObservedSentFrameRate(): number; waitForLocalOutboundVideoReady(options?: { timeoutMs?: number; minPositiveSamples?: number; timeoutMessage?: string; }): Promise; private rejectLocalOutboundReadyWaiters; /** Immediately abandon a wedged engine without awaiting unpublish/leave promises. */ forceDestroy(options?: { preserveExternalTrack?: boolean; }): void; private switchToExternalVideoSource; private switchToExternalAudioSource; private switchToInternalAudioSource; private switchToInternalVideoSource; private applyVideoEncoderPreference; /** Explicitly apply the content-hint degradation preference to the active WebRTC sender. */ private applyLocalVideoDegradationPreference; private attachRemoteVideo; private ensureRemoteStreamSubscribed; private bindRemoteVideoPlayerToContainer; private mountRemoteVideoPlayer; private startRemoteFrameWatch; private stopRemoteFrameWatch; private isRemoteSeiUser; /** Always mount remote player — SEI gate only affects display matching, not subscription. */ private canRenderRemoteVideo; /** Whether remote SEI matches the active task (display gate). */ private isSeiMatched; /** Detect whether the browser can send and receive H.264 SEI messages. */ private ensureSeiSupport; private supportsVideo; private supportsAudio; private resolveRemoteSubscriptionMediaType; private isSubscriptionCovered; private clearVideoContainers; private clearContainer; private getRequiredContainer; private emitRemotePlayerMounted; private parseRoomEventPayload; private recordGenerationAckFromRoomEvent; private log; private logTiming; /** RTC stream stats are emitted about every two seconds, so this does not log per frame. */ private logVideoFrameDiagnostics; private logLocalStreamStats; private evaluateLocalOutboundWatch; private triggerLocalOutboundStall; private debugLog; } type CanvasPosterOptions = { type?: 'image/png' | 'image/jpeg' | 'image/webp'; quality?: number; /** Maximum time to wait for browsers that never invoke canvas.toBlob. */ timeoutMs?: number; }; type VideoInputHealth = { currentTime: number; duration: number; paused: boolean; ended: boolean; readyState: number; trackReadyState: string; trackMuted: boolean; stalled: boolean; timeSinceAdvanceMs: number; }; type VideoFileStreamOptions = { muted?: boolean; playbackRate?: number; /** Optional fps override; when omitted, fps is measured from the source file. */ fps?: number; /** Optional hint; publish fps is still derived from the uploaded file when applicable. */ mobile?: boolean; targetSize?: [number, number]; /** Canvas background used for transparent source pixels. @default '#000000' */ backgroundColor?: string; /** Still-image poster encoding. Defaults to PNG. */ poster?: CanvasPosterOptions; i18n?: SDKI18n; onHealthReport?: (health: VideoInputHealth) => void; healthIntervalMs?: number; }; type VideoFileStream = { url: string; /** Still image matching the composited publish Canvas; available for image sources. */ posterUrl?: string; /** Same MediaStream pushed to RTC; bind to preview via srcObject. */ previewStream: MediaStream; /** Capture-only element; pinned off-screen. */ videoEl: HTMLVideoElement; videoTrack: MediaStreamTrack; audioTrack?: MediaStreamTrack; /** Measured source fps — encoder ceiling hint only. */ fps: number; /** Session publish dimensions (native source size by default). */ width: number; height: number; /** Original media dimensions before scale. */ sourceWidth: number; sourceHeight: number; destroy: () => void; }; declare function shouldSampleAtMediaTime(lastMediaTimeS: number, mediaTimeS: number, frameIntervalS: number): boolean; declare function createVideoFileStream(fileOrUrl: Blob | string, options?: VideoFileStreamOptions): Promise; type ImageFileStreamOptions = VideoFileStreamOptions; declare function createImageFileStream(fileOrUrl: Blob | string, options?: ImageFileStreamOptions): Promise; /** Detect HEIC/HEIF even when a browser supplies an empty or generic MIME type. */ declare function isHeicImageFile(file: File): Promise; type NormalizeHeicImageOptions = { /** JPEG quality used for browser-compatible output. Defaults to 0.9. */ quality?: number; }; /** * Convert HEIC/HEIF to JPEG before browser preview, Canvas, RTC, or upload. * Every other file is returned unchanged and does not load the WASM decoder. */ declare function normalizeHeicImageFile(file: File, options?: NormalizeHeicImageOptions): Promise; declare function isImageMediaFile(file: Blob | string): boolean; declare function isVideoMediaFile(file: Blob | string): boolean; declare function createMediaFileStream(fileOrUrl: Blob | string, options?: ImageFileStreamOptions): Promise; /** Preview frames default to 16:9; session `size` is separate (see resolveUploadVideoSize). */ declare const PREVIEW_CONTAINER_ASPECT_RATIO: number; /** CSS `aspect-ratio` string for a session target size — keeps preview layout aligned with passed `size`. */ declare function resolvePreviewAspectRatio(size: [number, number]): string; /** Default landscape session size under the 832 rule (16:9). */ declare const DEFAULT_SESSION_TARGET_SIZE: [number, number]; declare const MIN_UPLOAD_VIDEO_PIXELS = 600000; declare const MAX_UPLOAD_VIDEO_PIXELS = 1280000; /** * Upload publish size — keep source resolution (even dimensions for H.264). * Avoids canvas downscale blur. */ declare function resolveUploadPublishSize(sourceWidth: number, sourceHeight: number): [number, number]; /** * Adaptive RTC encode/session size. * Keeps the base width and scales height for wide sources; tall sources use the full base size. */ declare function resolveAdaptiveRtcVideoSize(sourceWidth: number, sourceHeight: number, baseSize?: [number, number]): [number, number]; /** * Upload session size: * - below 600k pixels: use the smallest proportional upscale above 600k; * - above 1.28m pixels: use the largest proportional downscale below 1.28m; * - inside the range: keep native scale. * Width and height are aligned to multiples of 32 in the scale direction. */ declare function resolveUploadVideoSize(sourceWidth: number, sourceHeight: number): [number, number]; declare function resolveSessionTargetSize(input: { localVideoSize?: { width: number; height: number; } | null; overrideSize?: [number, number]; }): [number, number]; type CameraEnvironmentIssue = 'insecure-context' | 'api-unavailable'; /** Detect browser conditions that prevent RTC from opening the camera. */ declare function getCameraEnvironmentIssue(): CameraEnvironmentIssue | null; type CameraAccessErrorKind = 'not-found' | 'not-allowed' | 'permission-denied' | 'in-use' | 'overconstrained' | 'unsupported' | 'capture-unsupported' | 'generic'; /** True for camera failures that should prompt the user to open or allow the device camera. */ declare function isCameraAccessError(error: unknown): boolean; /** Map browser or RTC camera failures to a stable category for user-facing copy. */ declare function classifyCameraAccessError(error: unknown): CameraAccessErrorKind | null; declare function resolveRefImageUrl(client: XmaxOpenClient, input: File | string): Promise; type DownloadRemoteFileOptions = { filename?: string; /** @deprecated Direct attachment downloads do not use the system share sheet. */ preferShare?: boolean; }; /** * @deprecated Direct attachment downloads need no browser-side prefetch. * Kept as a compatibility no-op for existing SDK consumers. */ declare function prefetchRemoteFile(url: string): Promise; /** @deprecated Direct attachment downloads are ready as soon as their URL exists. */ declare function isRemoteFilePrefetched(url: string): boolean; /** @deprecated Direct attachment downloads keep no browser-side cache. */ declare function clearPrefetchedRemoteFile(_url?: string): void; /** * Navigate directly to a remote download URL. The remote server must return * `Content-Disposition: attachment`; this keeps large files out of page memory * and lets the browser or operating-system download manager stream the response. */ declare function downloadRemoteFile(url: string, options?: DownloadRemoteFileOptions): Promise; declare const PREVIEW_UPLOAD_LAYOUT_ATTR = "data-preview-upload-layout"; /** Legacy upload orientation marker; retained for render-mode compatibility. */ declare const PREVIEW_UPLOAD_FIT_ATTR = "data-preview-upload-fit"; declare const PREVIEW_OUTPUT_LAYOUT_ATTR = "data-preview-output-layout"; declare const PREVIEW_CONTAIN_ATTR = "data-preview-contain"; declare const PREVIEW_COVER_ATTR = "data-preview-cover"; /** Apply true contain rendering for every uploaded-media aspect ratio. */ declare function applyUploadPreviewMediaLayout(container: HTMLElement): void; declare function observeUploadPreviewMediaLayout(container: HTMLElement): () => void; declare const XMAX_MIN_RECOMMENDED_INPUT_SHORT_EDGE: 480; type XmaxNoticeCode = 'LOW_INPUT_RESOLUTION'; type XmaxNoticeInputKind = 'camera' | 'image' | 'video' | 'stream'; type XmaxLowInputResolutionNotice = { readonly code: 'LOW_INPUT_RESOLUTION'; readonly message: string; readonly details: { readonly inputKind: XmaxNoticeInputKind; readonly width: number; readonly height: number; readonly shortEdge: number; readonly minimumShortEdge: typeof XMAX_MIN_RECOMMENDED_INPUT_SHORT_EDGE; }; }; type XmaxSdkNotice = XmaxLowInputResolutionNotice; /** Non-fatal SDK notice callback. The notice never interrupts the active operation. */ type XmaxNoticeNotifier = (notice: XmaxSdkNotice) => void; /** * A model selected from the public Xmax model catalog. * * The model identity is shared across realtime and offline execution. The * client method that receives this definition determines how the model runs. */ type ModelDefinition = { /** Public model name, for example `x2.0`. */ name: string; }; type FileClient = { /** Upload an image file and return its remote URL metadata. Accepts an optional abort signal. */ uploadImage: (file: File, options?: RequestOptions) => Promise; /** Upload a video file and return its remote URL metadata. Accepts an optional abort signal. */ uploadVideo: (file: File, options?: RequestOptions) => Promise; /** Alias of `uploadImage()` retained by the file client. */ upload: (file: File, options?: RequestOptions) => Promise; /** * Upload then run `/cos/image/check`. * Returns the upload metadata with the checked image URL. * * @example * ```ts * const result = await client.files.uploadAndCheckImage(file) * await session.set({ * prompt: session.context.prompt, * refImageUrl: result.url, * }) * ``` */ uploadAndCheckImage: (file: File, options?: RequestOptions) => Promise; }; /** Status values returned by the Offline Task API. */ type OfflineTaskStatus = 'submitted' | 'processing' | 'completed' | 'error'; /** Output quality accepted by the Offline Task API. */ type OfflineTaskQuality = 'sd' | 'hd'; /** Frame rates accepted by the Offline Task API. */ declare const OFFLINE_TASK_SUPPORTED_FPS: readonly [8, 10, 12, 15, 16, 18, 20, 22, 24, 25, 30, 45, 48, 50, 60, 72, 90, 100, 120]; type OfflineTaskFps = (typeof OFFLINE_TASK_SUPPORTED_FPS)[number]; /** @deprecated Use {@link ModelDefinition}. */ type OfflineModel = ModelDefinition; /** Model factory exposed through the shared `models` entry point. */ interface OfflineModels { /** Select a model for offline generation. */ offline(name: string): ModelDefinition; } type OfflineTaskResult = { result_url?: string | null; upload_error?: string | null; finalize_duration_ms?: number; compression_level?: string | null; frame_count?: number; fps?: number; result_duration_ms?: number; file_size_bytes?: number; upload_status?: string | null; dropped_frame_count?: number; original_file_size_bytes?: number; } & Record; /** Complete task object returned by create, query, batch query, and list calls. */ type OfflineTask = { uid: string; userUid?: string; prompt: string; refImagePath: string | null; refVideoPath: string; processorId?: string | null; quality: OfflineTaskQuality; requestedFps?: number | null; retryCount?: number; resolvedFps?: number; videoDurationSeconds?: number; billableDurationSeconds?: number; chargePoints?: number; status: OfflineTaskStatus; result: OfflineTaskResult | null; processStartTime?: string | null; createTimestamp?: string; updateTimestamp?: string; } & Record; /** A local browser File is uploaded automatically; strings must be Xmax upload URLs. */ type OfflineMediaInput = File | string; /** Generation context for one offline video task. */ type OfflineContext = { /** Generation instructions. Leading/trailing whitespace is removed. */ prompt: string; /** * Optional reference image. Local Files are uploaded automatically; strings * must be URLs previously returned by `client.files.uploadImage()`. */ refImageUrl?: OfflineMediaInput | null; }; type OfflineSubmitOptions = { /** Model definition; this client method runs it as an offline task. */ model: ModelDefinition; /** Source video File or a URL previously returned by `client.files.uploadVideo()`. */ source: OfflineMediaInput; /** Generation prompt and optional reference image. */ context: OfflineContext; /** @default 'hd' */ quality?: OfflineTaskQuality; /** Omit to use the source video's detected frame rate. */ fps?: OfflineTaskFps; /** Cancels local upload, request, and polling work. It does not cancel an accepted server task. */ signal?: AbortSignal; }; type OfflineGenerateOptions = OfflineSubmitOptions & { /** Called for the submitted task and whenever its status changes. */ onStatusChange?: (task: OfflineTask) => void; /** Delay between status requests. @default 2000 */ pollIntervalMs?: number; /** Maximum time for submit plus polling. @default 1800000 (30 minutes) */ timeoutMs?: number; }; type OfflineRequestOptions = { signal?: AbortSignal; }; type OfflineBatchQueryResult = { list: OfflineTask[]; }; type OfflineListOptions = OfflineRequestOptions & { /** @default 1 */ pageNumber?: number; /** @default 10; maximum 100 */ pageSize?: number; status?: OfflineTaskStatus; }; type OfflineTaskPage = { pageNumber: number; pageSize: number; total: number; list: OfflineTask[]; }; type OfflineClient = { /** Submit a task and poll it until `completed` or `error`. */ generate: (options: OfflineGenerateOptions) => Promise; /** Submit an asynchronous offline video task. Local Files are uploaded first. */ submit: (options: OfflineSubmitOptions) => Promise; /** Retrieve one task by UID. */ status: (taskUid: string, options?: OfflineRequestOptions) => Promise; /** Retrieve up to 100 tasks in one request. */ batchQuery: (taskUids: readonly string[], options?: OfflineRequestOptions) => Promise; /** List the current user's tasks. */ list: (options?: OfflineListOptions) => Promise; }; /** * @brief 实时输入媒体的来源类型。 */ type RealtimeMediaKind = /** 浏览器摄像头媒体。 */ 'camera' /** 视频文件媒体。 */ | 'video' /** 图片媒体。 */ | 'image' /** 调用方传入的 MediaStream。 */ | 'stream'; /** * @brief 视频内容类型。 * RTC 编码器根据内容类型在画面清晰度和运动流畅度之间选择更合适的编码策略。 */ type RealtimeContentHint = /** 文本清晰度优先,适用于包含大量文字的画面。 */ 'text' /** 运动流畅度优先,适用于摄像头、电影、视频和游戏画面。 */ | 'motion' /** 细节清晰度优先,适用于图片、文字和复杂纹理混合的画面。 */ | 'detail'; /** * @brief 实时会话状态。 */ type RealtimeSessionState = /** 已连接,但当前没有生成任务。 */ 'idle' /** 当前正在生成。 */ | 'running' /** 会话已彻底断开,不能继续使用。 */ | 'disconnected'; /** * @brief 已成功建立的实时会话发生断开的原因。 * 该原因通过 {@link RealtimeConnectOptions.onDisconnect} 返回;连接建立前的失败不会触发该回调。 */ type RealtimeDisconnectReason = /** 调用方主动执行 disconnect。 */ 'client' /** 服务端报告会话已失效。 */ | 'session_inactive' /** 心跳请求失败。 */ | 'heartbeat_error' /** 本地发布或首个远端输出未在规定时间内就绪。 */ | 'overloaded' /** Start 或输出链路发生不可恢复错误。 */ | 'error'; /** @deprecated Use {@link ModelDefinition}. */ type RealtimeModel = ModelDefinition; /** * @brief 实时生成模型入口。 * 用于按公开模型名称创建 {@link ModelDefinition},不会在本地校验模型是否已开通。 */ interface RealtimeModels { /** * @brief 选择一个实时生成模型。 * @param name 模型的公开名称。 * @returns 可传给实时连接接口的统一模型定义。 */ realtime(name: string): ModelDefinition; } /** * @brief 实时生成上下文。 * 上下文用于描述当前生成任务的提示词和参考图;调用 `session.set()` * 后,运行中的会话会平滑切换条件,空闲会话会以新上下文开始生成。 */ type RealtimeContext = { /** 文本提示词。必填;首尾空白会被去除。 */ prompt: string; /** 参考图 URL。省略时保留当前值;传入 `null` 可清除当前参考图。 */ refImageUrl?: string | null; }; /** SDK display state; custom renderers apply this state without their own restart timers. */ type RealtimePresentationState = { instant: boolean; /** Session-owned URL; do not revoke it. Null when Instant is inactive. */ inputImageUrl: string | null; showInputImage: boolean; /** Suppress restart loading after the first drag; initial loading is unchanged. */ suppressLoading: boolean; }; /** * @brief SDK 解析完成后的完整媒体规格。 * `width`、`height` 和 `fps` 均为必填项,用于描述媒体源的实际规格或提交给 RTC 的完整编码目标。 * `maxKbps` 和 `contentHint` 仅作用于 RTC 编码;媒体源不提供对应信息时可以省略。 * 作为连接配置使用时,通过 `Partial` 选择性传入字段;SDK 会将其补齐为编码目标。 */ type RealtimeMediaSetting = { /** 视频宽度,单位为 px。 */ width: number; /** 视频高度,单位为 px。 */ height: number; /** 视频帧率,单位为 fps。 */ fps: number; /** * RTC 最大编码码率,单位为 Kbps。 * RTC 会根据网络和设备状态在该上限内动态调整实际发送码率。@default 1200 */ maxKbps?: number; /** * RTC 视频内容类型,用于选择清晰度或流畅度优先的编码策略。 * @default 'detail' */ contentHint?: RealtimeContentHint; }; /** * @brief 图片或视频文件的播放设置。 * 仅用于 `realtime.connectMedia()` 创建的 SDK 托管媒体源。 */ type RealtimePlaybackSetting = { /** 播放速率,`1` 表示正常速度。@default 1 */ playbackRate?: number; }; /** * @brief 实时音频设置。 * 控制输入音频发布和远端输出音频播放,不参与 `start` 房间事件参数。 */ type RealtimeAudioSetting = { /** * 是否发布输入流中的音频轨。 * - `connectCamera()`:为 `true` 时采集并发布麦克风音频。 * - `connectMedia()` / `connect()`:为 `true` 时发布输入流中首条可用音频轨。 * @default true */ publish?: boolean; /** * 是否订阅并播放远端输出音频。 * 省略或设为 `false` 时,SDK 仅订阅远端视频,不播放声音。 * @default false */ subscribe?: boolean; }; /** * @brief 当前实时会话使用的媒体信息。 * 该对象由 SDK 创建并以只读形式暴露;其中的 {@link MediaStream} 仍遵循浏览器原生生命周期。 * @notes 调用方拥有通过 `realtime.connect()` 传入的流,并负责停止其 MediaStreamTrack。 */ type RealtimeMedia = { /** 媒体来源类型。 */ readonly kind: RealtimeMediaKind; /** 发布到 RTC 的浏览器原生 MediaStream。 */ readonly stream: MediaStream; /** 媒体源的实际规格,通常读取自 MediaStreamTrack.getSettings()。 */ readonly sourceSetting: Readonly; /** 提交给 RTC 编码器的完整目标规格;该值不是实时统计数据。 */ readonly streamSetting: Readonly; }; /** * @brief SDK 托管的拖拽交互设置。 * 拖拽坐标以 {@link RealtimeMedia.streamSetting} 的像素坐标系发送给实时生成服务。 */ type RealtimeDragSetting = { /** 是否启用拖拽交互。配置远端容器时默认启用。@default true */ enabled?: boolean; /** 一次拖拽开始时调用;可返回 Promise 执行异步准备。 */ onStart?: () => void | Promise; /** 一次拖拽结束时调用;可返回 Promise 执行异步收尾。 */ onEnd?: () => void | Promise; }; /** * @brief SDK 托管的实时媒体渲染设置。 * 容器均为可选项;省略后 SDK 仍会建立会话,调用方可通过 {@link RealtimeConnectOptions.onRemoteStream} * 获取远端流并自行渲染。 */ type RealtimeRenderSetting = { /** Input image opacity transition; set 0 for an immediate switch. @default 150 */ inputImageTransitionMs?: number; /** 本地输入预览容器。SDK 会在容器内创建或挂载渲染节点。 */ localContainer?: HTMLElement; /** 远端生成结果容器。SDK 会在容器内挂载 RTC 远端视频。 */ remoteContainer?: HTMLElement; /** 是否对 SDK 管理的本地输入预览进行水平翻转;不会修改媒体像素或远端结果。@default false */ mirror?: boolean; /** 远端画面的拖拽交互设置。 */ drag?: RealtimeDragSetting; /** 画面适配方式:`cover` 填满并可能裁切,`contain` 完整显示并可能留边。 */ fit?: 'cover' | 'contain'; /** * SDK 创建图片/视频 Canvas 时使用的背景色,会进入实际发布的视频像素。 * 用于透明区域;仅对 `connectMedia()` 创建的媒体源生效。@default '#000000' */ backgroundColor?: string; }; type RealtimeRoomEventResult = { result_url?: string | null; video_url?: string | null; upload_status?: string | null; upload_error?: string | null; has_audio?: boolean; frame_count?: number; fps?: number; dropped_frame_count?: number; average_output_fps?: number; video_duration_ms?: number; recording_duration_ms?: number; write_video_duration_ms?: number; finalize_duration_ms?: number; duration_ms?: number; result_duration_ms?: number; file_size_bytes?: number; original_file_size_bytes?: number; compression_level?: string | null; close_reason?: string | null; } & Record; type RealtimeRoomEventPayload = { event?: string; uid?: string; session_uid?: string; user_id?: string; result?: RealtimeRoomEventResult; } & Record; /** RTC 已将当前 Session 的首个远端视频帧渲染到播放器。 */ type RealtimeRemoteVideoFirstFrameInfo = { /** 远端视频发布者的用户 ID。 */ userId: string; /** 首帧视频宽度,单位为 px。 */ width: number; /** 首帧视频高度,单位为 px。 */ height: number; }; /** 实时连接日志设置。 */ type RealtimeLogSetting = { /** 是否在控制台输出 RTC 诊断日志。@default false */ rtc?: boolean; }; /** * @brief 实时连接的通用设置。 * 适用于 `realtime.connect()`、`realtime.connectCamera()` 和 `realtime.connectMedia()`。 */ type RealtimeConnectOptions = { /** 需要使用的模型;连接入口决定它以实时方式运行。 */ model: ModelDefinition; /** * RTC 编码目标。可以单独指定 `fps`、`maxKbps` 或 `contentHint`; * `width` 与 `height` 必须同时提供或同时省略。 * `connectCamera` 根据环境默认编码设置补齐;其他连接方式根据媒体源补齐。 * 最终结果通过 `session.media.streamSetting` 暴露。 */ stream?: Partial; /** SDK 托管的本地和远端渲染设置。 */ render?: RealtimeRenderSetting; /** RTC 输入发布和远端输出播放设置。 */ audio?: RealtimeAudioSetting; /** 连接级日志设置。RTC 日志默认关闭。 */ log?: RealtimeLogSetting; /** 远端 MediaStream 可用或重新绑定时调用,适用于调用方自行渲染。 */ onRemoteStream?: (stream: MediaStream) => void; /** * 当前 Session 的首个远端视频帧由 RTC 成功渲染时调用一次。 * 回调在 connect 返回前完成注册,因此不会漏掉快速返回的首帧。 */ onRemoteVideoFirstFrame?: (info: RealtimeRemoteVideoFirstFrameInfo) => void; /** * 连接或会话发生错误时以 `(message, error)` 调用。 * `message` 与 `error.message` 相同;`error.details` 可提供细分原因和诊断快照。 * 连接级回调优先于 Client 全局回调。 */ onError?: XmaxErrorNotifier; /** * 非致命提示以 `(notice)` 调用;提示文案位于 `notice.message`。 * 不会中断连接或生成。 * 连接级回调优先于 Client 全局回调。 */ onNotice?: XmaxNoticeNotifier; /** * 已成功建立的会话断开后调用一次。 * 第二个参数为清理前捕获的诊断详情;第一个参数和单参数回调保持兼容。 * connect 系列方法返回 Session 之前发生的连接失败不会触发该回调。 */ onDisconnect?: (reason: RealtimeDisconnectReason, details: XmaxErrorDetails) => void; /** Session 状态发生变化时调用。 */ onStateChange?: (state: RealtimeSessionState) => void; /** Display changes for both SDK-managed and custom renderers; emitted only when changed. */ onPresentationChange?: (state: Readonly) => void; /** 房间消息事件回调,常用于监听 `video_completed` 等服务端生命周期事件。 */ onRoomEvent?: (event: RealtimeRoomEventPayload) => void; /** 生成上下文。 */ context?: RealtimeContext; /** 连接完成后是否立即开始生成。@default true */ autoStart?: boolean; }; /** * @brief 摄像头实时连接设置。 * 在通用连接设置上增加摄像头方向;SDK 负责申请权限、采集并释放摄像头媒体。 */ type RealtimeConnectCameraOptions = RealtimeConnectOptions & { /** 首选摄像头方向;后置摄像头通过火山 RTC `setVideoCaptureDevice` 选择。 */ facingMode?: 'user' | 'environment'; }; /** * @brief 图片或视频文件实时连接设置。 * 在通用连接设置上增加媒体播放行为;SDK 负责解码、循环播放及释放内部媒体资源。 */ type RealtimeConnectMediaOptions = RealtimeConnectOptions & { /** 图片或视频的播放设置。 */ playback?: RealtimePlaybackSetting; }; /** * @brief 已建立的实时生成会话。 * Session 同时管理生成状态、上下文、媒体输入和 RTC 生命周期。 * {@link RealtimeSession.stopGeneration} 只停止生成并保留 RTC;{@link RealtimeSession.disconnect} 会彻底释放会话。 */ interface RealtimeSession { /** 当前生成生命周期状态。 */ readonly state: RealtimeSessionState; /** 最近一次成功应用的生成上下文。返回对象只读。 */ readonly context: Readonly; /** 当前发布的输入流及其媒体规格。返回对象只读。 */ readonly media: Readonly; /** Current display state, including the input image used by Instant. */ readonly presentation: Readonly; /** Custom drag surfaces call these at stroke boundaries; SDK-managed surfaces call them automatically. */ beginDrag: () => void; endDrag: () => void; /** * @brief 获取服务端会话 ID。 * @returns 活跃会话的 ID;断开后返回 `null`。 */ getSessionUid: () => string | null; /** * @brief 应用生成上下文。 * @param context 生成上下文;`prompt` 必填,`refImageUrl: null` 表示清除参考图。 * @returns 应用完成后 resolve。 * @notes 运行中发送 `change_condition`;进入、退出或更新 Instant 时发送 `start`,以应用静态图片参数。 */ set: (context: RealtimeContext) => Promise; /** * @brief 强制创建新的生成任务。 * @param context 可选的生成上下文;传入时 `prompt` 必填,并与当前上下文合并。 * @returns Start 事件发送并完成本地启动流程后 resolve。 * @notes 无论当前是否正在运行,每次调用都会发送 `start`。 */ start: (context?: RealtimeContext) => Promise; /** * @brief 发送一组拖拽轨迹点。 * @param tracks 轨迹点数组,每个点为 `[x, y]`,坐标基于 `media.streamSetting` 的像素坐标系。 * @returns 轨迹消息提交后 resolve;当前没有活动任务时直接 resolve。 */ sendTracks: (tracks: Array<[number, number]>) => Promise; /** * @brief 停止当前生成任务。 * @returns Stop 事件处理完成后 resolve。 * @notes RTC 房间和输入流保持连接,可再次调用 start。 */ stopGeneration: () => Promise; /** * @brief 停止当前会话的本地输入流,同时保持 RTC 房间连接。 * @returns 本地采集、预览与发布停止后 resolve。 * @notes 当前用于开放平台在停止生成后立即关闭本地输入,同时保持 RTC 房间连接, * 以等待 `video_completed` 等最终事件并向用户提供视频保存。 * SDK 管理的输入资源会被释放;调用方传入的原始 Track 不会被停止。 * 当前尚未提供在同一会话中恢复本地 Stream 的方法,请谨慎调用;完成结果处理后通常应调用 `disconnect()`。 */ stopLocalStream: () => Promise; /** * @brief 彻底断开实时会话。 * @returns RTC 离房、服务端会话关闭及 SDK 托管资源释放完成后 resolve。 * @notes 调用方通过 connect 传入的 MediaStream 不会由 SDK 停止。 */ disconnect: () => Promise; } /** * @brief 实时生成能力入口。 * 提供摄像头连接、媒体文件连接和自有 MediaStream 连接三种接入方式。 */ type RealtimeClient = { /** * @brief 采集浏览器摄像头并建立实时会话。 * @param options 摄像头采集、RTC 编码、渲染和生成设置。 * @returns 已建立的实时会话;SDK 拥有并负责释放摄像头媒体。 */ connectCamera: (options: RealtimeConnectCameraOptions) => Promise; /** * @brief 将图片、视频 Blob 或远程 URL 作为输入建立实时会话。 * @param source 媒体 Blob(File 继承自 Blob)或可访问的媒体 URL。 * @param options 媒体播放、RTC 编码、渲染和生成设置。 * @returns 已建立的实时会话;SDK 负责释放内部创建的媒体资源。 */ connectMedia: (source: Blob | string, options: RealtimeConnectMediaOptions) => Promise; /** * @brief 使用调用方已有的 MediaStream 建立实时会话。 * @param stream 至少包含一条可用视频轨道的 MediaStream。 * @param options RTC 编码、渲染和生成设置。 * @returns 已建立的实时会话。 * @notes MediaStream 的所有权仍属于调用方;disconnect 不会停止其中的 MediaStreamTrack。 */ connect: (stream: MediaStream, options: RealtimeConnectOptions) => Promise; }; type XmaxClientOptions = { apiKey: string; /** @default Xmax production API base URL. */ baseUrl?: string; /** @default Official Offline Task API URL for the package's build region. */ offlineBaseUrl?: string; authToken?: string; heartbeatIntervalMs?: number; /** Set false to opt this client out of SDK performance diagnostics. */ telemetry?: boolean; reportSource?: XmaxReportSource; /** Per-client probe settings. Remote settings take precedence when available. */ probe?: XmaxProbeOptions; /** Overrides the package default locale (`zh-CN` for domestic, `en-US` for global). */ locale?: SDKLocale; /** Complete custom i18n implementation. Takes precedence over `locale`. */ i18n?: SDKI18n; /** Default `(message, error)` handler. `error` is an XmaxSdkError containing code and message. */ onError?: XmaxErrorNotifier; /** Default non-fatal `(notice)` handler. Realtime operations continue normally. */ onNotice?: XmaxNoticeNotifier; /** Fired when H.264 SEI is received on a remote (non-local) stream. */ onRemoteSei?: (payload: RemoteSeiReceivedPayload) => void; /** Fired when remote SEI gate state changes. */ onSeiGateChange?: (state: SeiGateState) => void; /** Cleared when generation start completes; true while publish/start warmup is in progress. */ onPublishPipelineWaitChange?: (waiting: boolean) => void; }; type XmaxClient = { files: FileClient; realtime: RealtimeClient; offline: OfflineClient; }; declare function createXmaxClient(options: XmaxClientOptions): XmaxClient; declare const XMAX_OFFLINE_API_BASE_URLS: Record; /** Official Offline Task API URL for the region this package was built for. */ declare const XMAX_OFFLINE_API_PRODUCTION_BASE_URL: string; declare const DEFAULT_OFFLINE_POLL_INTERVAL_MS = 2000; declare const DEFAULT_OFFLINE_POLL_TIMEOUT_MS: number; type Models = RealtimeModels & OfflineModels; /** * @brief 生成模型入口。 * 用于按开放平台公开的模型名称创建实时或离线模型对象。 * @notes 该入口只负责构造模型对象,不会在本地校验模型名称或账号权限。 */ declare const models: Models; /** * @brief 实时媒体流的默认最大编码码率。 * 单位为 Kbps;RTC 会根据网络和设备状态在该上限内动态调整实际发送码率。 */ declare const DEFAULT_REALTIME_STREAM_MAX_KBPS = 1200; /** * @brief 实时媒体流的默认视频内容类型。 * `detail` 表示优先保留图片、文字和复杂纹理的画面细节。 */ declare const DEFAULT_REALTIME_STREAM_CONTENT_HINT: RealtimeContentHint; /** * @brief SDK 托管摄像头实时连接的环境默认设置。 * 桌面端使用 `1472 × 832 @ 24fps`,移动端使用 `960 × 1280 @ 24fps`。 */ declare const DEFAULT_CAMERA_REALTIME_SETTINGS: { desktop: { width: number; height: number; fps: number; maxKbps: number; contentHint: "detail"; }; mobile: { width: number; height: number; fps: number; maxKbps: number; contentHint: "detail"; }; }; /** * @brief 获取当前环境使用的摄像头默认媒体设置。 * @param mobile 是否使用移动端默认值;省略时由 SDK 根据当前视口自动判断。 * @returns 一份可独立修改的完整媒体设置。 */ declare function resolveDefaultCameraRealtimeSetting(mobile?: boolean): RealtimeMediaSetting; type DragTrackControllerOptions = { targetSize: [number, number]; fitMode?: 'contain' | 'cover'; mirrored?: boolean; enabled?: boolean; onTracks: (tracks: Array<[number, number]>) => void | Promise; /** Fired once when a real drag stroke begins (first pointer down). */ onStrokeStart?: () => void | Promise; /** Fired once when a real drag stroke ends (pointer up/cancel), not on disable/destroy. */ onStrokeEnd?: () => void | Promise; }; declare class DragTrackController { private readonly container; private readonly trailCanvas; private readonly fxCanvas; private readonly onTracks; private readonly onStrokeStart; private readonly onStrokeEnd; private strokeActive; private hasTrailPixels; private idleFadeFrames; private targetSize; private fitMode; private mirrored; private enabled; private readonly activePointers; private readonly lastTargetPoints; private readonly segQueue; private sampleTimer; private sampleInFlight; private rafId; private resizeObserver; private readonly onWindowResize; private readonly onPointerDown; private readonly onPointerMove; private readonly onPointerUp; private readonly onPointerCancel; constructor(container: HTMLElement, options: DragTrackControllerOptions); setEnabled(enabled: boolean): void; setTargetSize(targetSize: [number, number]): void; setFitMode(fitMode: 'contain' | 'cover'): void; setMirrored(mirrored: boolean): void; destroy(): void; private applyInteractionStyle; private bindResizeObserver; private unbindResizeObserver; private bindPointerEvents; private unbindPointerEvents; private clearVisuals; private resizeCanvas; private toTargetPoint; private stopDrawLoop; private renderPointerFx; private startDrawLoop; private stopSampling; private collectCurrentTracks; private flushTracks; private startSampling; private finishStroke; private handlePointerDown; private handlePointerMove; private handlePointerUp; private handlePointerCancel; } declare function createDragTrackController(container: HTMLElement, options: DragTrackControllerOptions): DragTrackController; type MapViewportOptions = { fitMode?: 'contain' | 'cover'; /** Flip X when the output video is horizontally mirrored in CSS. */ mirrored?: boolean; }; declare function mapViewportPointToCoordinateSpace(e: Pick, container: HTMLElement, targetSize: [number, number], options?: MapViewportOptions): [number, number] | null; /** Inverse of mapViewportPointToCoordinateSpace — target coords to canvas pixels (CSS space × dpr). */ declare function mapTargetPointToCanvas(point: [number, number], container: HTMLElement, targetSize: [number, number], dpr: number, options?: MapViewportOptions): [number, number] | null; type RemoteViewHost = { wrapper: HTMLElement; videoHost: HTMLElement; dragHost: HTMLElement; }; declare function createRemoteViewHost(wrapper: HTMLElement): RemoteViewHost; type DragVideoSyncOptions = { getTargetSize: () => [number, number]; getFitMode: () => 'contain' | 'cover'; onSync?: () => void; }; /** Align drag overlay to the painted RTC media region. */ declare function syncDragSurfaceToVideo(dragSurface: HTMLElement, targetSize: [number, number], fitMode: 'contain' | 'cover'): boolean; /** Keep a drag surface aligned with remote output video layout. */ declare function observeDragSurfaceVideoSync(dragSurface: HTMLElement, options: DragVideoSyncOptions): () => void; export { ACTIVE_STATUS, API_ERROR_MESSAGES, type CameraAccessErrorKind, type CameraEnvironmentIssue, type ChangeConditionRtcRoomEvent, type ClientOptions, type CosSts, DEFAULT_CAMERA_REALTIME_SETTINGS, DEFAULT_OFFLINE_POLL_INTERVAL_MS, DEFAULT_OFFLINE_POLL_TIMEOUT_MS, DEFAULT_REALTIME_STREAM_CONTENT_HINT, DEFAULT_REALTIME_STREAM_MAX_KBPS, DEFAULT_SESSION_TARGET_SIZE, type DownloadRemoteFileOptions, DragTrackController, type DragTrackControllerOptions, type ExternalVideoPublishDeadlines, type FileClient, type ImageFileStreamOptions, type LocalOutboundStallInfo, MAX_UPLOAD_VIDEO_PIXELS, MEDIA_TIME_EPSILON_S, MEDIA_TIME_LOOP_JUMP_S, MIN_UPLOAD_VIDEO_PIXELS, MOBILE_PUBLISH_MAX_WIDTH_PX, type ModelDefinition, type ModelExtra, type Models, type NormalizeHeicImageOptions, OFFLINE_TASK_SUPPORTED_FPS, type OfflineBatchQueryResult, type OfflineClient, type OfflineContext, type OfflineGenerateOptions, type OfflineListOptions, type OfflineMediaInput, type OfflineModel, type OfflineModels, type OfflineRequestOptions, type OfflineSubmitOptions, type OfflineTask, type OfflineTaskFps, type OfflineTaskPage, type OfflineTaskQuality, type OfflineTaskResult, type OfflineTaskStatus, PREVIEW_CONTAINER_ASPECT_RATIO, PREVIEW_CONTAIN_ATTR, PREVIEW_COVER_ATTR, PREVIEW_OUTPUT_LAYOUT_ATTR, PREVIEW_UPLOAD_FIT_ATTR, PREVIEW_UPLOAD_LAYOUT_ATTR, REMOTE_FIRST_OUTPUT_TIMEOUT_MS, RTC_PUBLISH_FPS_MOBILE, RTC_PUBLISH_FPS_WEB, RTC_PUBLISH_FRAME_INTERVAL_MS, RTC_PUBLISH_FRAME_INTERVAL_S, RTC_RECONNECT_TIMEOUT_MS, type RealtimeAudioSetting, type RealtimeClient, type RealtimeConnectCameraOptions, type RealtimeConnectMediaOptions, type RealtimeConnectOptions, type RealtimeContentHint, type RealtimeContext, type RealtimeDisconnectReason, type RealtimeDragSetting, type RealtimeLogSetting, type RealtimeMedia, type RealtimeMediaKind, type RealtimeMediaSetting, type RealtimeModel, type RealtimeModels, type RealtimePlaybackSetting, type RealtimePresentationState, type RealtimeRemoteVideoFirstFrameInfo, type RealtimeRenderSetting, type RealtimeRoomEventPayload, type RealtimeRoomEventResult, type RealtimeSession, type RealtimeSessionState, type RemoteSeiReceivedPayload, type RemoteViewHost, type RequestOptions, type ResolveRtcPublishFpsOptions, type ResolvedXmaxProbeConfig, type RtcAsyncErrorInfo, type RtcJoinInfo, type RtcLogEntry, RtcManager, type RtcRoomEvent, type RtcStateSnapshot, type SDKI18n, type SDKLocale, type SDKMessages, type SeiGateState, type Session, type StartRtcRoomEvent, type StopRtcRoomEvent, type StsCredentials, type TracksRtcRoomEvent, type UploadImageResult, type UploadVideoResult, type VideoFileStream, type VideoFileStreamOptions, type VideoInputHealth, XMAX_DISCONNECT_REASON_CODES, XMAX_MIN_RECOMMENDED_INPUT_SHORT_EDGE, XMAX_OFFLINE_API_BASE_URLS, XMAX_OFFLINE_API_PRODUCTION_BASE_URL, XMAX_OPEN_API_BASE_URLS, XMAX_OPEN_API_PRODUCTION_BASE_URL, XMAX_SDK_DEFAULT_LOCALE, XMAX_TELEMETRY_CONFIG_ENDPOINTS, XMAX_TELEMETRY_DEFAULT_CONFIG_ENDPOINT, XMAX_TELEMETRY_DEFAULT_ENDPOINT, XMAX_TELEMETRY_ENDPOINTS, type XmaxClient, type XmaxClientOptions, type XmaxDisconnectReasonCode, type XmaxErrorCode, type XmaxErrorDetails, type XmaxErrorNotifier, type XmaxLogEntry, type XmaxLowInputResolutionNotice, type XmaxNoticeCode, type XmaxNoticeInputKind, type XmaxNoticeNotifier, XmaxOpenClient, type XmaxProbeOptions, type XmaxReportSource, XmaxSdkError, type XmaxSdkNotice, type XmaxSdkRegion, type XmaxTelemetryDeviceMeta, type XmaxTelemetryEnvelope, type XmaxTelemetryEvent, type XmaxTelemetryEventName, type XmaxTelemetryMeta, type XmaxTelemetryNetworkMeta, type XmaxTelemetryOptions, type XmaxTelemetryParams, type XmaxTelemetryPayload, type XmaxTelemetryProbeMeta, type XmaxTelemetryRtcStats, type XmaxTelemetryWireEvent, applyUploadPreviewMediaLayout, classifyCameraAccessError, clearPrefetchedRemoteFile, configureXmaxTelemetry, createChangeConditionRtcRoomEvent, createDragTrackController, createImageFileStream, createMediaFileStream, createRemoteViewHost, createSDKI18n, createStartRtcRoomEvent, createStopRtcRoomEvent, createTaskUid, createTracksRtcRoomEvent, createVideoFileStream, createXmaxClient, downloadRemoteFile, getCameraEnvironmentIssue, getDefaultMessages, isCameraAccessError, isHeicImageFile, isImageMediaFile, isMobilePublishEnvironment, isRemoteFilePrefetched, isTelemetryEndpointConfigured, isVideoMediaFile, isXmaxSdkError, mapTargetPointToCanvas, mapViewportPointToCoordinateSpace, models, normalizeHeicImageFile, observeDragSurfaceVideoSync, observeUploadPreviewMediaLayout, prefetchRemoteFile, resolveAdaptiveRtcVideoSize, resolveApiErrorMessage, resolveDefaultCameraRealtimeSetting, resolvePreviewAspectRatio, resolveRefImageUrl, resolveRtcPublishFps, resolveRtcPublishFrameIntervalS, resolveSessionTargetSize, resolveUploadPublishSize, resolveUploadVideoSize, shouldSampleAtMediaTime, syncDragSurfaceToVideo };