API reference
Exports of @sigx/lynx-video v0.4.9.
Import everything from the package entry. Importing the entry also auto-applies the JSX augmentation that registers the <video-player> intrinsic, so you never import it directly.
import { VideoPlayer } from '@sigx/lynx-video';
import type {
VideoPlayerProps,
VideoPlayerAttributes,
VideoResizeMode,
VideoLoadEvent,
VideoLoadEventDetail,
VideoEndEvent,
VideoEndEventDetail,
VideoErrorEvent,
VideoErrorEventDetail,
VideoTimeUpdateEvent,
VideoTimeUpdateEventDetail,
} from '@sigx/lynx-video';
Components
VideoPlayer
The recommended entry point — a typed sigx-lynx component wrapping the native <video-player> intrinsic. On iOS it wraps an AVPlayer inside an AVPlayerLayer; on Android it wraps an androidx.media3 ExoPlayer inside a PlayerView. It participates in Lynx's layout tree like any other view — give it a width/height (or aspectRatio) and it draws decoded frames there. Prefer it over the raw <video-player> intrinsic. Available on iOS and Android (native UI).
export const VideoPlayer: component<VideoPlayerProps>(({ props }) => () => JSX.Element)
It accepts the props described by VideoPlayerProps, maps camelCase React-style props onto the native element's kebab/bind attributes (resizeMode → resize-mode, onLoad → bindload, onEnd → bindend, onError → binderror, onTimeUpdate → bindtimeupdate), and returns a render function so signals and props read inside it stay reactive.
v1 is declarative-only. Imperative methods (seek, getStatus) are not implemented — drive playback through the playing and src props.
Types
VideoPlayerProps
Props type for VideoPlayer. Every prop is optional (the third Define.Prop type argument is false = not required). Shared across platforms.
export type VideoPlayerProps =
& Define.Prop<'src', string, false>
& Define.Prop<'poster', string, false>
& Define.Prop<'autoplay', boolean, false>
& Define.Prop<'playing', boolean, false>
& Define.Prop<'loop', boolean, false>
& Define.Prop<'muted', boolean, false>
& Define.Prop<'volume', number, false>
& Define.Prop<'controls', boolean, false>
& Define.Prop<'resizeMode', VideoResizeMode, false>
& Define.Prop<'class', string, false>
& Define.Prop<'style', string | Record<string, string | number>, false>
& Define.Prop<'onLoad', (e: VideoLoadEvent) => void, false>
& Define.Prop<'onEnd', (e: VideoEndEvent) => void, false>
& Define.Prop<'onError', (e: VideoErrorEvent) => void, false>
& Define.Prop<'onTimeUpdate', (e: VideoTimeUpdateEvent) => void, false>;
Props
src— URL orfile://URI of the asset. Also acceptshttp://and absolute paths starting with/(treated as a local file). Setting it reloads the player; clearing it (empty/undefined) stops playback and releases the asset.poster— image shown before the first frame. iOS loads it async (best-effort, no caching) and hides it once the first frame is ready. On Android it is a no-op stub in v1.autoplay— begin playback once the asset is ready. Defaultfalse.playing— declarative play/pause toggle. Overridesautoplaywhen both are set.loop— restart at end-of-clip, handled natively. Defaultfalse. SuppressesonEnd.muted— mute audio independently ofvolume. Defaultfalse. Sets effective volume to 0 without losing the stored value.volume— audio volume, clamped to0..1. Default1.controls— show the platform default controls overlay. Defaultfalse.resizeMode— how the frame fits the box; aVideoResizeMode. Defaultcontain.class/style— standard styling. The player must be given a size.onLoad/onEnd/onError/onTimeUpdate— event handlers; see the event types below.
VideoResizeMode
How the video frame fits inside the element box. Default contain. Shared across platforms.
export type VideoResizeMode = 'contain' | 'cover' | 'stretch';
Values
contain— letterbox/fit (iOSAVLayerVideoGravity.resizeAspect, AndroidRESIZE_MODE_FIT).cover— fill, cropping overflow (iOS.resizeAspectFill, AndroidRESIZE_MODE_ZOOM).stretch— distort to fill (iOS.resize, AndroidRESIZE_MODE_FILL).
Interfaces
VideoPlayerAttributes
Low-level JSX intrinsic attribute interface for the raw <video-player> element — the native attribute surface, with kebab-case attrs and bind* event handlers. Registered globally as JSX.IntrinsicElements['video-player']. Most apps use the VideoPlayer wrapper instead, which exposes camelCase prop names. Shared (JSX intrinsic).
export interface VideoPlayerAttributes extends LynxCommonAttributes {
src?: string;
poster?: string;
autoplay?: boolean;
playing?: boolean;
loop?: boolean;
muted?: boolean;
volume?: number;
controls?: boolean;
'resize-mode'?: VideoResizeMode;
bindload?: LynxEventHandler<VideoLoadEvent>;
bindend?: LynxEventHandler<VideoEndEvent>;
binderror?: LynxEventHandler<VideoErrorEvent>;
bindtimeupdate?: LynxEventHandler<VideoTimeUpdateEvent>;
}
Extends LynxCommonAttributes (from @sigx/lynx-runtime), which adds Lynx's shared view attributes like style/class and common layout events. bindtimeupdate fires ~4x/sec and crosses the bridge on each call — use sparingly.
VideoLoadEvent
Event passed to onLoad / bindload. Fires once asset metadata is available — iOS on AVPlayerItem .readyToPlay, Android on ExoPlayer STATE_READY. Fires at most once per loaded asset. Shared across platforms.
export interface VideoLoadEvent {
type: 'load';
detail: VideoLoadEventDetail;
}
VideoLoadEventDetail
Detail payload of VideoLoadEvent. Shared across platforms.
export interface VideoLoadEventDetail {
durationMs: number;
width: number;
height: number;
[k: string]: unknown;
}
Fields
durationMs— total duration in milliseconds;0if unknown (live streams / indeterminate duration).width/height— natural pixel dimensions. May be0if the codec has not decoded a frame yet on Android, and are not re-fired when the size later resolves.- Index signature for forward-compatible extra fields.
VideoEndEvent
Event passed to onEnd / bindend. Fires when playback reaches the end of the clip. Does not fire when loop is true — looping is handled natively (iOS seeks to zero and replays; Android uses REPEAT_MODE_ONE). Shared across platforms.
export interface VideoEndEvent {
type: 'end';
detail: VideoEndEventDetail;
}
VideoEndEventDetail
Detail payload of VideoEndEvent. Empty in v1 — only an index signature for forward-compat. Shared across platforms.
export interface VideoEndEventDetail {
[k: string]: unknown;
}
VideoErrorEvent
Event passed to onError / binderror. Fires on a non-recoverable load or playback error (iOS AVPlayerItem .failed or invalid src; Android Player.Listener.onPlayerError). Also fired immediately for an invalid/unparseable src URL on iOS. Shared across platforms.
export interface VideoErrorEvent {
type: 'error';
detail: VideoErrorEventDetail;
}
VideoErrorEventDetail
Detail payload of VideoErrorEvent. Shared across platforms.
export interface VideoErrorEventDetail {
message: string;
[k: string]: unknown;
}
Fields
message— human-readable error string (iOSlocalizedDescription/'Invalid src: ...'; AndroidPlaybackException.messageor'Playback error').- Index signature for forward-compat.
VideoTimeUpdateEvent
Event passed to onTimeUpdate / bindtimeupdate. Fires ~4x/sec (every 250ms) while actively playing, broadcasting the current position. Crosses the bridge on each call — use sparingly; for high-frequency animation, read the duration once via onLoad and animate locally. On Android the 250ms timer only runs while playing (re-armed on play, stopped on pause/end). Shared across platforms.
export interface VideoTimeUpdateEvent {
type: 'timeupdate';
detail: VideoTimeUpdateEventDetail;
}
VideoTimeUpdateEventDetail
Detail payload of VideoTimeUpdateEvent. Shared across platforms.
export interface VideoTimeUpdateEventDetail {
positionMs: number;
[k: string]: unknown;
}
Fields
positionMs— current playback position in milliseconds (clamped>= 0; iOS guards againstNaN/Inffrom live streams).- Index signature for forward-compat.
See also
- Usage — practical guides and examples.
- Installation — project setup.
