@jwplayer/jwplayer-react-native
Version:
React-native Android/iOS plugin for JWPlayer SDK (https://www.jwplayer.com/)
704 lines (677 loc) • 22.4 kB
TypeScript
declare module "@jwplayer/jwplayer-react-native" {
import React from "react";
import { ViewStyle } from "react-native";
// ============================================================================
// UNIFIED CONFIGURATION TYPES
// ============================================================================
// For detailed type definitions, see types/ directory
// Types are also available by importing from '@jwplayer/jwplayer-react-native/types'
// Main configuration interface - see types/unified-config.d.ts for full documentation
export interface JWPlayerConfig {
license: string;
file?: string;
sources?: any[];
playlist?: any[] | string;
playlistIndex?: number;
autostart?: boolean;
mute?: boolean;
repeat?: boolean;
preload?: 'auto' | 'none' | boolean;
stretching?: 'uniform' | 'fill' | 'exactfit' | 'none';
playbackRates?: number[];
playbackRateControls?: boolean;
bitrateUpperBound?: number;
advertising?: any;
related?: any;
pid?: string;
playerId?: string;
styling?: any;
uiConfig?: any;
backgroundAudioEnabled?: boolean;
category?: string;
categoryOptions?: string[];
mode?: string;
forceLegacyConfig?: boolean;
playlistItemCallbackEnabled?: boolean;
playerInModal?: boolean;
fullScreenOnLandscape?: boolean;
landscapeOnFullScreen?: boolean;
portraitOnExitFullScreen?: boolean;
exitFullScreenOnPortrait?: boolean;
enableLockScreenControls?: boolean;
pipEnabled?: boolean;
useTextureView?: boolean;
allowCrossProtocolRedirectsSupport?: boolean;
displaytitle?: boolean;
displayTitle?: boolean;
displaydescription?: boolean;
displayDescription?: boolean;
nextupoffset?: string | number;
thumbnailPreview?: number;
logoView?: any;
title?: string;
description?: string;
image?: string;
tracks?: any[];
starttime?: number;
mediaid?: string;
mediaId?: string;
[key: string]: any;
}
// Main configuration type alias
export type Config = JWPlayerConfig;
// Re-export common types with proper names
export type JWAdvertisingConfig = any;
export type JWPlaylistItem = any;
export type JWSource = any;
export type JWTrack = any;
export type JWImaDaiSettings = any;
export type JWImaSdkSettings = any;
export type JWAdBreak = any;
export type JWAdRules = any;
export type JWUiConfig = any;
export type JWLogoView = any;
export type JWRelatedConfig = any;
export type JWStyling = any;
export type ThumbnailPreview = 101 | 102 | 103;
export type Stretching = 'uniform' | 'fill' | 'exactfit' | 'none';
// ============================================================================
// BACKWARD COMPATIBILITY
// ============================================================================
/**
* @deprecated Use JWPlayerConfig or Config instead
* Maintained for backward compatibility
*/
interface JwConfig {
pid?: string;
mute?: boolean;
forceLegacyConfig?: boolean;
playlistItemCallbackEnabled?: boolean;
useTextureView?: boolean;
autostart?: boolean;
nextupoffset?: string | number;
repeat?: boolean;
allowCrossProtocolRedirectsSupport?: boolean;
displaytitle?: boolean;
displaydescription?: boolean;
stretching?: string;
thumbnailPreview?: number;
preload?: boolean;
playlist?: any[] | string;
sources?: any[];
file?: string;
playlistIndex?: number;
related?: any;
uiConfig?: any;
logoView?: any;
advertising?: any;
playbackRates?: number[];
playbackRateControls?: boolean;
license: string;
playerInModal?: boolean;
fullScreenOnLandscape?: boolean;
landscapeOnFullScreen?: boolean;
portraitOnExitFullScreen?: boolean;
exitFullScreenOnPortrait?: boolean;
enableLockScreenControls?: boolean;
pipEnabled?: boolean;
[key: string]: any;
}
// ============================================================================
// TYPE ALIASES FOR BACKWARD COMPATIBILITY
// ============================================================================
/**
* @deprecated Use Stretching from unified types
*/
type JwStretching = Stretching;
/**
* @deprecated Use ThumbnailPreview from unified types
*/
type JwThumbnailPreview = ThumbnailPreview;
// Re-export advertising types with legacy names for backward compatibility
/**
* @deprecated Advertising types are now imported from unified types
* Use JWAdvertisingConfig instead
*/
type VmapAdvertisingConfig = import('./types').VmapAdvertisingConfig;
type VastAdvertisingConfig = import('./types').VastAdvertisingConfig;
type ImaVmapAdvertisingConfig = import('./types').ImaAdvertisingConfig;
type ImaAdvertisingConfig = import('./types').ImaAdvertisingConfig;
type ImaDaiAdvertisingConfig = import('./types').ImaDaiAdvertisingConfig;
/**
* @deprecated Use JWAdRules from unified types
*/
type JwStartOnSeek = "pre" | "none";
/**
* @deprecated Use JWAdBreak from unified types
*/
type JwAdType = "LINEAR" | "NONLINEAR";
/**
* @deprecated Use OmidSupport from unified types
*/
type JwOmidSupport = "auto" | "enabled" | "disabled";
/**
* @deprecated Use LogoPosition from unified types
*/
type JwLogoPosition = "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
// Re-export playlist and media types for backward compatibility
/**
* @deprecated These types are now imported from unified types
* Direct usage is discouraged - import from './types' instead
*/
type JwRelatedOnComplete = "hide" | "show" | "none" | "autoplay";
type JwOnRelatedClick = "play" | "link";
// ============================================================================
// LEGACY TYPE DEFINITIONS
// ============================================================================
// The following types are maintained for backward compatibility with existing code.
// New code should use the unified types imported from './types' above.
// These legacy definitions may be removed in a future major version.
/**
* @deprecated Use types from './types' instead
*/
interface AudioTrack {
autoSelect: boolean;
defaultTrack: boolean;
groupId: string;
language: string;
name: string;
}
export interface QualityLevel {
playListPosition: number;
bitRate: number;
label: string;
height: number;
width: number;
index: number;
}
interface CastingDevice {
name?: string;
identifier?: string;
}
interface Source {
file: string;
label: string;
default?: boolean;
}
type TrackKind = "captions" | "chapters" | "thumbnails";
interface Track {
file: string;
label: string;
kind: TrackKind;
default?: boolean;
}
interface JWAdSettings {
allowsBackgroundPlayback?: boolean;
// Add other ad settings properties as needed
}
interface IMASettings {
locale?: string;
ppid?: string;
maxRedirects?: number;
sessionID?: string;
debugMode?: boolean;
}
interface AdSchedule {
tag: string;
offset: string;
}
// interface CompanionAdSlot {
// viewId: string; // Reference to a UIView in the application
// size?: { width: number; height: number };
// }
interface GoogleDAIStream {
videoID?: string;
cmsID?: string;
assetKey?: string;
apiKey?: string;
adTagParameters?: { [key: string]: string };
}
interface AdRule {
startOn: number;
frequency: number;
timeBetweenAds: number;
startOnSeek: 'none' | 'pre'; // Mapped from JWAdShownOnSeek
}
// interface FriendlyObstruction {
// viewId: string;
// purpose: 'mediaControls' | 'closeAd' | 'notVisible' | 'other'; // Mapped from JWFriendlyObstructionPurpose
// reason?: string;
// }
type ClientTypes = "vast" | "ima" | "ima_dai";
interface VASTAdvertising {
adSchedule?: AdSchedule[];
adVmap?: string;
tag?: string; // Vast xml url
openBrowserOnAdClick?: boolean;
adClient: "vast";
adRules?: AdRule;
adSettings?: JWAdSettings;
}
interface IMAAdvertising {
adSchedule?: AdSchedule[];
adVmap?: string;
tag?: string; // Vast xml url
adClient: "ima";
adRules?: AdRule;
imaSettings?: IMASettings;
// companionAdSlots?: CompanionAdSlot[];
// friendlyObstructions?: FriendlyObstruction[];
}
interface IMA_DAIAdvertising {
adClient: "ima_dai";
imaSettings?: IMASettings;
// friendlyObstructions?: FriendlyObstruction[];
googleDAIStream?: GoogleDAIStream;
}
type Advertising = VASTAdvertising | IMAAdvertising | IMA_DAIAdvertising;
interface PlaylistItem {
file: string;
sources?: Source[];
image?: string;
title?: string;
description?: string;
mediaId?: string;
adSchedule?: AdSchedule[];
adVmap?: string;
tracks?: Track[];
recommendations?: string;
startTime?: number;
autostart?: boolean;
/**
* Data to be passed to Chromecast receiver (optional and typically used for DRM implementations)
*
* Only made available in legacy objects as there is no way to pass this otherwise
*/
userInfo?: { [key: string]: any };
}
type RelatedOnClicks = "play" | "link";
type RelatedOnCompletes = "show" | "hide" | "autoplay";
interface Related {
onClick?: RelatedOnClicks;
onComplete?: RelatedOnCompletes;
heading?: string;
url?: string;
autoplayMessage?: string;
autoplayTimer?: number;
}
interface Font {
name?: string;
size?: number;
}
type EdgeStyles = "none" | "dropshadow" | "raised" | "depressed" | "uniform";
// All `Styling` is only intended to be used with iOS. Android requires overloading
// of the JWP IDs seen here: https://docs.jwplayer.com/players/docs/android-styling-guide
interface Styling {
colors?: {
buttons?: string;
backgroundColor?: string;
fontColor?: string;
timeslider?: {
thumb?: string;
rail?: string;
slider?: string;
};
};
font?: Font;
showTitle?: boolean;
showDesc?: boolean;
captionsStyle?: {
font?: Font;
fontColor?: string;
backgroundColor?: string;
highlightColor?: string;
edgeStyle?: EdgeStyles;
};
menuStyle?: {
font?: Font;
fontColor?: string;
backgroundColor?: string;
};
}
type Preloads = "auto" | "none";
type InterfaceBehaviors = "normal" | "hidden" | "onscreen";
type UIGroups =
| "overlay"
| "control_bar"
| "center_controls"
| "next_up"
| "error"
| "playlist"
| "controls_container"
| "settings_menu"
| "quality_submenu"
| "captions_submenu"
| "playback_submenu"
| "audiotracks_submenu"
| "casting_menu";
type AudioSessionCategory =
| "Ambient"
| "SoloAmbient"
| "Playback"
| "Record"
| "PlayAndRecord"
| "MultiRoute";
type AudioSessionCategoryOptions =
| "MixWithOthers"
| "DuckOthers"
| "AllowBluetooth"
| "DefaultToSpeaker"
| "InterruptSpokenAudioAndMix"
| "AllowBluetoothA2DP"
| "AllowAirPlay"
| "OverrideMutedMicrophone";
type AudioSessionMode =
| "Default"
| "VoiceChat"
| "VideoChat"
| "GameChat"
| "VideoRecording"
| "Measurement"
| "MoviePlayback"
| "SpokenAudio"
| "VoicePrompt";
type JWControlType =
| "forward"
| "rewind"
| "pip"
| "airplay"
| "chromecast"
| "next"
| "previous"
| "settings"
| "languages"
| "fullscreen";
/**
* @deprecated Legacy iOS config interface - use JWPlayerConfig instead
*/
interface LegacyIOSConfig {
license: string;
advertising?: Advertising;
autostart?: boolean;
controls?: boolean;
repeat?: boolean;
nextUpStyle?: { offsetSeconds: number; offsetPercentage: number };
styling?: Styling;
backgroundAudioEnabled?: boolean;
category?: AudioSessionCategory;
categoryOptions?: Array<AudioSessionCategoryOptions>;
mode?: AudioSessionMode;
fullScreenOnLandscape?: boolean;
landscapeOnFullScreen?: boolean;
portraitOnExitFullScreen?: boolean;
exitFullScreenOnPortrait?: boolean;
playerInModal?: boolean;
playlist?: PlaylistItem[];
stretching?: string;
related?: Related;
preload?: Preloads;
interfaceBehavior?: InterfaceBehaviors;
interfaceFadeDelay?: number;
hideUIGroups?: UIGroups[];
processSpcUrl?: string;
fairplayCertUrl?: string;
contentUUID?: string;
viewOnly?: boolean;
enableLockScreenControls?: boolean;
pipEnabled?: boolean;
offlineMessage?: string;
offlineImage?: string;
forceFullScreenOnLandscape?: boolean;
forceLandscapeOnFullScreen?: boolean;
}
interface BaseEvent<T> {
nativeEvent: T;
}
interface SeekEventProps {
position: number;
offset: number;
}
interface SeekedEventProps {
position: number;
}
interface RateChangedEventProps {
rate: number;
at: number;
}
interface PlayerSetupErrorProps {
errorMessage?: string;
errorCode?: number;
}
interface PlayerErrorProps {
error?: string;
errorCode?: number;
description?: string; // Android Only
}
interface TimeEventProps {
position: number;
duration: number;
}
interface ControlBarVisibleEventProps {
visible: boolean;
}
interface PlaylistEventProps {
playlist: PlaylistItem[]
}
interface LoadEventProps {
loadTime: number;
}
interface PlaylistItemEventProps {
playlistItem: PlaylistItem
}
interface PlayerErrorEventProps {
code: string;
error: string;
}
interface PlayerWarningEventProps {
code?: number;
warning?: string;
adErrorCode?: number; // Android only
}
interface AdEventProps {
client: number;
reason?: string;
type: number;
}
// Overloaded type to be used in multiple error events
interface CaptionsChangedEventProps {
index?: number;
}
interface CaptionsListEventProps {
index: number;
file?: string;
label: string;
default: string;
}
type NativeError = (event: BaseEvent<PlayerErrorEventProps> | BaseEvent<PlayerSetupErrorProps> | BaseEvent<PlayerErrorProps>) => void;
type NativeWarning = (event: BaseEvent<PlayerWarningEventProps>) => void;
interface PropsType {
config: JWPlayerConfig | JwConfig | LegacyIOSConfig;
style?: ViewStyle;
controls?: boolean;
forceLegacyConfig?: boolean;
onPlayerReady?: () => void;
onPlaylist?: (event: BaseEvent<PlaylistEventProps>) => void;
onLoaded? : (event: BaseEvent<LoadEventProps>) => void;
onBeforePlay?: () => void;
onBeforeComplete?: () => void;
onComplete?: () => void;
onPlay?: () => void;
onPause?: () => void;
onSeek?: (event: BaseEvent<SeekEventProps>) => void;
onSeeked?: (event?: BaseEvent<SeekedEventProps>) => void;
onRateChanged?: (event?: BaseEvent<RateChangedEventProps>) => void;
onSetupPlayerError?: NativeError;
onPlayerError?: NativeError;
onPlayerWarning?: NativeWarning;
onPlayerAdError?: NativeError;
onPlayerAdWarning?: NativeWarning;
onAdEvent?: (event: BaseEvent<AdEventProps>) => void;
onAdTime?: (event: BaseEvent<TimeEventProps>) => void;
onBuffer?: () => void;
onTime?: (event: BaseEvent<TimeEventProps>) => void;
onFullScreenRequested?: () => void;
onFullScreen?: () => void;
onFullScreenExitRequested?: () => void;
onFullScreenExit?: () => void;
onControlBarVisible?: (event: BaseEvent<ControlBarVisibleEventProps>) => void;
onPlaylistComplete?: () => void;
onPlaylistItem?: (event: BaseEvent<PlaylistItemEventProps>) => void;
onCaptionsChanged?: (event: BaseEvent<CaptionsChangedEventProps>) => void;
onCaptionsList?: (event: BaseEvent<CaptionsListEventProps>) => void;
onAudioTracks?: () => void;
shouldComponentUpdate?: (nextProps: any, nextState: any) => boolean;
onBeforeNextPlaylistItem?: (event: BaseEvent<PlaylistItemEventProps>) => void;
}
export const JWPlayerAdEvents: {
/// This event is reported when the ad break has come to an end.
JWAdEventTypeAdBreakEnd: 0;
/// This event is reported when the ad break has begun.
JWAdEventTypeAdBreakStart: 1;
/// This event is reported when the user taps the ad.
JWAdEventTypeClicked: 2;
/// This event is reported when the ad is done playing.
JWAdEventTypeComplete: 3;
/// This event is used to report the ad impression, supplying additional detailed information about the ad.
JWAdEventTypeImpression: 4;
/// This event reports meta data information associated with the ad.
JWAdEventTypeMeta: 5;
/// The event is reported when the ad pauses.
JWAdEventTypePause: 6;
/// This event is reported when the ad begins playing, even in the middle of the stream after it was paused.
JWAdEventTypePlay: 7;
/// The event reports data about the ad request, when the ad is about to be loaded.
JWAdEventTypeRequest: 8;
/// This event reports the schedule of ads across the currently playing content.
JWAdEventTypeSchedule: 9;
/// This event is reported when the user skips the ad.
JWAdEventTypeSkipped: 10;
/// This event is reported when the ad begins.
JWAdEventTypeStarted: 11;
/// This event relays information about ad companions.
JWAdEventTypeCompanion: 12;
};
export const JWPlayerState: {
JWPlayerStateUnknown?: number;
JWPlayerStateIdle: number;
JWPlayerStateBuffering: number;
JWPlayerStatePlaying: number;
JWPlayerStatePaused: number;
JWPlayerStateComplete: number;
JWPlayerStateError: number | null;
};
export const JWPlayerAdClients: {
JWAdClientJWPlayer: 0;
JWAdClientGoogleIMA: 1;
JWAdClientGoogleIMADAI: 2;
JWAdClientUnknown: 3;
};
export default class JWPlayer extends React.Component<PropsType> {
quite(): void;
pause(): void;
play(): void;
stop(): void;
toggleSpeed(): void;
setSpeed(speed: number): void;
setCurrentQuality(index: number): void;
currentQuality(): number;
getQualityLevels(): Promise<QualityLevel[] | null>;
setVolume(volume: number): void;
setPlaylistIndex(index: number): void;
setControls(show: boolean): void;
setLockScreenControls(show: boolean): void;
seekTo(time: number): void;
changePlaylist(fileUrl: string): void;
/**
* Side load playlist items into an already setup player
* @param playlistItems `PlaylistItem` or `JWPlaylistItem`
*/
loadPlaylist(playlistItems: PlaylistItem[] | JWPlaylistItem[]): void;
/**
* Side load playlist via URL into an already setup player
* @param playlistUrl URL for playlist to load (format for response: json)
*/
loadPlaylistWithUrl(playlistUrl: string): void;
setFullscreen(fullScreen: boolean): void;
time(): Promise<number | null>;
position(): Promise<number | null>;
togglePIP(): void;
setUpCastController(): void;
presentCastDialog(): void;
connectedDevice(): Promise<CastingDevice | null>;
availableDevices(): Promise<CastingDevice[] | null>;
castState(): Promise<number | null>;
playerState(): Promise<number | null>;
getAudioTracks(): Promise<AudioTrack[] | null>;
getCurrentAudioTrack(): Promise<number | null>;
setCurrentAudioTrack(index: number): void;
setCurrentCaptions(index: number): void;
getCurrentCaptions(): Promise<number | null>;
setVisibility(visibility: boolean, controls: JWControlType[]): void;
/**
* Reconfigures or recreates the player with a new configuration.
*
* IMPORTANT: This method should only be called after the player has been properly
* initialized and is ready (i.e., after onPlayerReady has fired). Calling this
* method before the player is ready may lead to undefined behavior.
*
* **Platform Behavior:**
*
* - **iOS**: Always performs a complete player recreation by:
* 1. Safely handling PiP state if active (waits for PiP to close)
* 2. Performing complete cleanup of the current player instance
* 3. Creating a new player instance with the provided config
*
* - **Android**: Intelligently determines whether to recreate or reconfigure:
* - ~90% of cases: Reconfigures existing player (preserves player instance, faster)
* - ~10% of cases: Recreates player (only when necessary, e.g., license changes)
* - Automatically handles state preservation (fullscreen, PiP)
*
* **Use this method when you need to:**
* - Switch to a new playlist or video programmatically
* - Update player configuration dynamically (e.g., from user settings)
* - Handle content changes during PiP mode
* - Write cross-platform code (same API works on both platforms)
*
* **Do NOT use this method:**
* - Before the player is ready (wait for onPlayerReady)
* - When the player is not properly initialized
*
* **For simple playlist updates, consider using `loadPlaylist()` instead.**
*
* @example
* ```typescript
* // Cross-platform example - works the same on both iOS and Android
* const switchVideo = () => {
* playerRef.current?.recreatePlayerWithConfig({
* license: 'YOUR_LICENSE_KEY',
* playlist: [{
* file: 'https://example.com/video.mp4',
* title: 'New Video'
* }],
* autostart: true
* });
* };
*
* // Use inside onPlayerReady
* <JWPlayer
* ref={playerRef}
* config={initialConfig}
* onPlayerReady={() => {
* // Now safe to use recreatePlayerWithConfig
* console.log('Player ready, can switch content if needed');
* }}
* />
* ```
*
* @param config The new configuration to apply
* @throws May throw if called before player is ready or with invalid config
*/
recreatePlayerWithConfig(config: JWPlayerConfig | JwConfig | LegacyIOSConfig): void;
/**
* Only called inside `onBeforeNextPlaylistItem` callback, and once per callback
* @param playlistItem `PlaylistItem` or `JWPlaylistItem`
*/
resolveNextPlaylistItem(playlistItem: PlaylistItem | JWPlaylistItem): void;
}
}