/** * Movi Types - Core type definitions for the streaming video library */ export type TrackType = "video" | "audio" | "subtitle"; export interface Track { id: number; type: "video" | "audio" | "subtitle"; codec: string; codecString?: string; extradata?: Uint8Array; profile?: number; level?: number; language?: string; label?: string; width?: number; height?: number; frameRate?: number; channels?: number; sampleRate?: number; subtitleType?: "text" | "image"; } export interface VideoTrack extends Track { type: "video"; width: number; height: number; frameRate: number; pixelFormat?: string; colorSpace?: string; colorPrimaries?: string; colorTransfer?: string; bitRate?: number; rotation?: number; colorRange?: string; isHDR?: boolean; /** * 360° spherical projection from container metadata: 0 / undefined = not a * 360 video, else AVSphericalProjection+1 (1=equirectangular, 2=cubemap, * 3=equirectangular-tile, 4=half-equirectangular). Only equirectangular * (1 and 3) is renderable by the current 360 viewer. */ projection?: number; /** * True when this is an embedded cover-art pseudo-stream (ID3v2 APIC, * FLAC PICTURE, MP4 covr, Matroska attachment). These look like single- * frame PNG/JPEG video streams to the demuxer; consumers picking an * active video track should skip them and read the picture via the * player's cover-art accessor instead. */ isAttachedPic?: boolean; } export interface AudioTrack extends Track { type: "audio"; channels: number; sampleRate: number; bitRate?: number; } export interface SubtitleTrack extends Track { type: "subtitle"; subtitleType: "text" | "image"; } export interface SubtitleCue { start: number; end: number; text?: string; image?: ImageBitmap; position?: { x: number; y: number; }; } export interface SourceConfig { type: "url" | "file" | "encrypted"; url?: string; file?: File; headers?: Record; /** Encrypted source config */ encrypted?: { videoUrl: string; tokenUrl: string; videoId: string; fingerprint: string; sessionToken: string; tokenRefreshInterval?: number; onAuthFailed?: (reason: string) => void; }; } /** Audio source with language metadata for multi-language support */ export interface AudioSourceEntry { url: string; type?: string; lang: string; label: string; } /** External subtitle source (VTT/SRT) with language metadata */ export interface SubtitleSourceEntry { url: string; lang: string; label: string; format?: "vtt" | "srt"; } export interface CacheConfig { type: "lru"; maxSizeMB: number; } export type RendererType = "canvas"; export type DecoderType = "auto" | "software"; export interface PlayerConfig { /** * Standard source descriptor (url / file / encrypted). Optional when a * pre-built `sourceAdapter` is supplied instead. */ source?: SourceConfig; /** * Pre-built SourceAdapter — overrides `source` when present. * Use this to feed media from a custom protocol (WebSocket, WebRTC data * channel, IndexedDB, encrypted blob, etc.) without writing a SourceConfig * branch. The adapter's `getSize()` and `read()` are called directly. */ sourceAdapter?: import("./source/SourceAdapter").SourceAdapter; /** Separate audio source — single or multi-language */ audioSource?: SourceConfig; /** Multiple audio tracks with language metadata */ audioTracks?: AudioSourceEntry[]; /** External subtitle tracks (VTT/SRT) with language metadata */ subtitleTracks?: SubtitleSourceEntry[]; renderer?: RendererType; decoder?: DecoderType; cache?: CacheConfig; canvas?: HTMLCanvasElement | OffscreenCanvas; wasmBinary?: Uint8Array; enablePreviews?: boolean; frameRate?: number; headers?: Record; audioOnly?: boolean; drm?: boolean; licenseUrl?: string; licenseHeaders?: Record; lcevc?: boolean; lcevcUrl?: string; } export interface Chapter { title: string; start: number; end: number; } export interface MediaInfo { formatName: string; duration: number; bitRate: number; startTime: number; tracks: Track[]; chapters: Chapter[]; metadata?: { [key: string]: string; }; } export interface VideoDecoderConfig { codec: string; codedWidth: number; codedHeight: number; description?: Uint8Array; colorSpace?: { primaries?: VideoColorPrimaries | null; transfer?: VideoTransferCharacteristics | null; matrix?: VideoMatrixCoefficients | null; fullRange?: boolean | null; }; hardwareAcceleration?: "no-preference" | "prefer-hardware" | "prefer-software"; } export interface AudioDecoderConfig { codec: string; sampleRate: number; numberOfChannels: number; description?: Uint8Array; } export interface Packet { streamIndex: number; keyframe: boolean; timestamp: number; dts: number; duration: number; data: Uint8Array; isIdr: boolean; isRasl: boolean; } export interface DecodedVideoFrame { timestamp: number; duration: number; width: number; height: number; format: "yuv420p" | "rgb24" | "rgba"; data: Uint8Array; planes?: { y?: Uint8Array; u?: Uint8Array; v?: Uint8Array; }; } export interface DecodedAudioFrame { timestamp: number; duration: number; sampleRate: number; channels: number; numFrames: number; format: "f32-planar"; channelData: Float32Array[]; } export type PlayerState = "idle" | "loading" | "ready" | "playing" | "paused" | "seeking" | "buffering" | "ended" | "error"; export interface PlayerEventMap { frame: DecodedVideoFrame; audio: DecodedAudioFrame; subtitle: SubtitleCue; stateChange: PlayerState; timeUpdate: number; durationChange: number; tracksChange: Track[]; error: Error; filerevoked: { offset: number; length: number; reason: string; }; loadStart: void; loadEnd: void; seeking: number; seeked: number; bufferUpdate: { start: number; end: number; }[]; ended: void; preloadcomplete: void; /** * Embedded cover art extracted from the source (ID3v2 APIC, FLAC PICTURE, * MP4 covr, Matroska attachment). Fires once after track enumeration when * an attached_pic pseudo-stream is present. Recipients own the bitmap and * should close() it on disposal. Fires with `null` when an art track was * present but extraction failed, so listeners waiting on it can stop. */ coverart: ImageBitmap | null; /** * Fired once when playback falls back to linear (forward-only, non-seekable) * mode because the server has no HTTP Range support and the file is too large * to cache whole. The UI hides the timeline and disables seeking/thumbnails. */ linearmode: void; } //# sourceMappingURL=types.d.ts.map