Lynx/Modules/Video/API reference
@sigx/lynx-video · Stable

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.

TypeScript
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).

TypeScript
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 (resizeModeresize-mode, onLoadbindload, onEndbindend, onErrorbinderror, onTimeUpdatebindtimeupdate), 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.

TypeScript
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 or file:// URI of the asset. Also accepts http:// 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. Default false.
  • playing — declarative play/pause toggle. Overrides autoplay when both are set.
  • loop — restart at end-of-clip, handled natively. Default false. Suppresses onEnd.
  • muted — mute audio independently of volume. Default false. Sets effective volume to 0 without losing the stored value.
  • volume — audio volume, clamped to 0..1. Default 1.
  • controls — show the platform default controls overlay. Default false.
  • resizeMode — how the frame fits the box; a VideoResizeMode. Default contain.
  • 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.

TypeScript
export type VideoResizeMode = 'contain' | 'cover' | 'stretch';

Values

  • contain — letterbox/fit (iOS AVLayerVideoGravity.resizeAspect, Android RESIZE_MODE_FIT).
  • cover — fill, cropping overflow (iOS .resizeAspectFill, Android RESIZE_MODE_ZOOM).
  • stretch — distort to fill (iOS .resize, Android RESIZE_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).

TypeScript
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.

TypeScript
export interface VideoLoadEvent {
    type: 'load';
    detail: VideoLoadEventDetail;
}

VideoLoadEventDetail#

Detail payload of VideoLoadEvent. Shared across platforms.

TypeScript
export interface VideoLoadEventDetail {
    durationMs: number;
    width: number;
    height: number;
    [k: string]: unknown;
}

Fields

  • durationMs — total duration in milliseconds; 0 if unknown (live streams / indeterminate duration).
  • width / height — natural pixel dimensions. May be 0 if 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.

TypeScript
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.

TypeScript
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.

TypeScript
export interface VideoErrorEvent {
    type: 'error';
    detail: VideoErrorEventDetail;
}

VideoErrorEventDetail#

Detail payload of VideoErrorEvent. Shared across platforms.

TypeScript
export interface VideoErrorEventDetail {
    message: string;
    [k: string]: unknown;
}

Fields

  • message — human-readable error string (iOS localizedDescription / 'Invalid src: ...'; Android PlaybackException.message or '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.

TypeScript
export interface VideoTimeUpdateEvent {
    type: 'timeupdate';
    detail: VideoTimeUpdateEventDetail;
}

VideoTimeUpdateEventDetail#

Detail payload of VideoTimeUpdateEvent. Shared across platforms.

TypeScript
export interface VideoTimeUpdateEventDetail {
    positionMs: number;
    [k: string]: unknown;
}

Fields

  • positionMs — current playback position in milliseconds (clamped >= 0; iOS guards against NaN/Inf from live streams).
  • Index signature for forward-compat.

See also#