/** * VideoPlayer types — discriminated `VideoSource` union + props. * * The component is engine-agnostic at the API surface: callers either * pass a structured `VideoSource` or a raw URL string (auto-parsed via * `parseEmbedUrl`). */ import type { ReactNode } from 'react'; export interface UrlSource { readonly type: 'url'; readonly url: string; readonly mimeType?: string; readonly title?: string; readonly poster?: string; } export interface YouTubeSource { readonly type: 'youtube'; readonly videoId: string; readonly startTime?: number; readonly playlistId?: string; readonly title?: string; readonly poster?: string; } export interface VimeoSource { readonly type: 'vimeo'; readonly videoId: string; readonly startTime?: number; readonly title?: string; readonly poster?: string; } export interface HlsSource { readonly type: 'hls'; readonly url: string; readonly title?: string; readonly poster?: string; } export interface IframeSource { readonly type: 'iframe'; readonly url: string; readonly title?: string; readonly poster?: string; readonly allow?: string; } export type VideoSource = | UrlSource | YouTubeSource | VimeoSource | HlsSource | IframeSource; export type AspectRatioValue = number | 'auto' | 'fill'; export interface VideoPlayerSettings { readonly autoPlay?: boolean; readonly muted?: boolean; readonly loop?: boolean; readonly playsInline?: boolean; readonly crossOrigin?: '' | 'anonymous' | 'use-credentials'; readonly preload?: 'none' | 'metadata' | 'auto'; } export interface VideoPlayerProps extends VideoPlayerSettings { /** * Structured source object — or a raw URL string that will be * auto-classified via `parseEmbedUrl` (YouTube / Vimeo / HLS / MP4 / iframe). */ readonly source: VideoSource | string; /** Default `true`. When `false`, no built-in `` is rendered. */ readonly controls?: boolean; /** Default `16/9`. `'fill'` stretches to parent height; `'auto'` keeps intrinsic. */ readonly aspectRatio?: AspectRatioValue; readonly className?: string; /** Custom children replace the default control bar entirely. */ readonly children?: ReactNode; /** Focus the player container on mount so media-chrome keyboard shortcuts * (space=play/pause, f=fullscreen, arrows=seek/volume) are active * immediately. Pair with `key={src}` upstream for per-source focus reset. */ readonly autoFocus?: boolean; }