import type { ViewProps } from "react-native"; import type { CustomStatistics, MediaClip, Phase, Project, State, } from "./types"; /** * Context for playlist/collection navigation. * Enables "next up" list and proper playlist navigation in the player. */ export type LoadContext = { /** Context entity type (always 'MediaClipList' for playlists) */ contextEntityType?: 'MediaClipList'; /** Playlist ID for "next up" list */ contextEntityId?: string; /** Context collection type (always 'MediaClipList' for collections) */ contextCollectionType?: 'MediaClipList'; /** Collection ID if playing within a collection */ contextCollectionId?: string; }; /** * Valid content types for loadWithContentIdAndType(). * Short aliases match the BB URL path segment convention. */ export type BBContentType = | 'mediaclip' | 'c' | 'mediacliplist' | 'l' | 'project' | 'p' | 'pj'; /** * @deprecated Use loadWithContentIdAndType() instead. * Note: the `playout` field was never correctly forwarded to the native player. * Use reinitializeIfNeeded() for playout/publication switching. */ export type LoadClipOptions = { autoPlay?: boolean; seekTo?: number; initiator?: string; context?: LoadContext; /** @deprecated Ignored — use reinitializeIfNeeded() to switch playout */ playout?: string; }; /** * Options for loading Shorts via loadShorts() */ export type LoadShortsOptions = { /** Initiator identifier for analytics */ initiator?: string; /** Auto-play after loading (default: true) */ autoPlay?: boolean; /** Seek to position after loading (seconds) */ seekTo?: number; }; export type BBPlayerViewMethods = { // Playback control methods play: () => void; pause: () => void; seek: (position: number) => void; seekRelative: (offsetSeconds: number) => void; setMuted: (muted: boolean) => void; setVolume: (volume: number) => void; /** Override the scroll-based viewability state */ setInView: (inView: boolean) => void; enterFullscreen: () => void; enterFullscreenLandscape: () => void; exitFullscreen: () => void; /** Present native SDK modal (iOS: overFullScreen with swipe-to-close, Android: in-place fullscreen) */ presentModal: () => void; /** Close native SDK modal */ closeModal: () => void; collapse: () => void; expand: () => void; autoPlayNextCancel: () => void; destroy: () => void; unload: () => void; showCastPicker: () => void; /** Update playout data without re-creating the player. Takes raw playout JSON string. */ updatePlayout: (playoutJson: string) => void; /** * Load content by ID and type. Entity-type agnostic primary API. * Naming follows the native SDK convention (loadWith... prefix). * * @param contentId - Numeric content ID * @param contentType - 'mediaclip' | 'c', 'mediacliplist' | 'l', or 'project' | 'p' * @param autoPlay - Auto-play after loading (default: true) * @param context - Playlist/collection context for navigation * * @example * playerRef.current?.loadWithContentIdAndType('12345', 'mediaclip'); * playerRef.current?.loadWithContentIdAndType('789', 'mediacliplist', false); */ loadWithContentIdAndType: (contentId: string, contentType: BBContentType, autoPlay?: boolean, context?: LoadContext) => void; /** * @deprecated Use loadWithContentIdAndType() instead. loadClip() only supports mediaclips and * incorrectly passed the playout option as an analytics initiator. */ loadClip: (clipId: string, options?: LoadClipOptions) => void; // Note: For Shorts playback, use the BBShortsView component instead of BBPlayerView. // Load methods (legacy signatures - kept for backwards compatibility) loadWithClipId: ( clipId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithClipListId: ( clipListId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithProjectId: ( projectId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithClipJson: ( clipJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithClipListJson: ( clipListJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithProjectJson: ( projectJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext ) => void; loadWithJsonUrl: (jsonUrl: string, autoPlay?: boolean, context?: LoadContext) => void; // Getter methods (async) getDuration: () => Promise; getMuted: () => Promise; getVolume: () => Promise; getPhase: () => Promise; getState: () => Promise; getMode: () => Promise; getClipData: () => Promise<{ id?: string; title?: string; description?: string; length?: number; } | null>; getProjectData: () => Promise<{ id?: string; name?: string; } | null>; getPlayoutData: () => Promise<{ name?: string; } | null>; /** Get current viewability override state */ getInView: () => Promise; /** Get the ad creative width in pixels */ getAdMediaWidth: () => Promise; /** Get the ad creative height in pixels */ getAdMediaHeight: () => Promise; /** Whether the player is currently casting to a Chromecast device */ getIsCasting: () => Promise; /** Friendly name of the connected Chromecast device */ getCastDeviceName: () => Promise; /** End the active Chromecast session */ endCastSession: () => void; /** * Get the complete player state as a structured object. * This is the primary method for getting player state, matching the channel SDK pattern. * * @returns Promise resolving to BBPlayerState or null if player not ready * * @example * const state = await playerRef.current?.getPlayerState(); * if (state) { * console.log(`Playing: ${state.state === 'PLAYING'}`); * console.log(`Duration: ${state.duration}`); * } */ getPlayerState: () => Promise; }; export type BBPlayerViewProps = { /** * Unique identifier for this player instance. * Used for multi-player scenarios and player identification in events. */ playerId?: string; /** * JWT token for authenticated access to protected content. * Will be merged into options.jwt automatically. */ jwt?: string; /** * Opt into the SDK's Continue Watching feature: the player persists the playhead per clip * to local storage on a 5 s throttle and auto-seeks to the stored position on the next load * of the same clip. Default off. Set true for long-form detail screens; leave off for shorts * feeds, autoplay carousels, and ad-only flows. * * Forwarded into `options.continueWatching` so consumers who construct the `options` dict * directly can also opt in via that key. * * Cross-platform: same canonical key string on iOS, Android, and the web standardplayer. * See ADO #19099 (iOS), #19143 (Android), #19149 (web). */ continueWatching?: boolean; /** * Player options passed to the native SDK. */ options?: Record; /** * JSON URL to load player configuration from. */ jsonUrl?: string; onDidFailWithError?: (error: string) => void; onDidRequestCollapse?: () => void; onDidRequestExpand?: () => void; onDidRequestOpenUrl?: (url: string) => void; onDidSetupWithJsonUrl?: (url: string) => void; onDidTriggerAdError?: (error: string) => void; onDidTriggerAdFinished?: () => void; onDidTriggerAdLoaded?: () => void; onDidTriggerAdLoadStart?: () => void; onDidTriggerAdNotFound?: () => void; onDidTriggerAdQuartile1?: () => void; onDidTriggerAdQuartile2?: () => void; onDidTriggerAdQuartile3?: () => void; onDidTriggerAdStarted?: () => void; onDidTriggerAllAdsCompleted?: () => void; onDidTriggerApiReady?: () => void; onDidTriggerAutoPause?: (why: string) => void; onDidTriggerAutoPausePlay?: (why: string) => void; onDidTriggerCanPlay?: () => void; onDidTriggerCustomStatistics?: (customStatistics: CustomStatistics) => void; onDidTriggerDurationChange?: (duration: number) => void; onDidTriggerEnded?: () => void; onDidTriggerFullscreen?: () => void; onDidTriggerMediaClipFailed?: () => void; onDidTriggerMediaClipLoaded?: (mediaClip: MediaClip) => void; onDidTriggerModeChange?: (mode: string) => void; onDidTriggerPause?: () => void; onDidTriggerPhaseChange?: (phase: Phase) => void; onDidTriggerPlay?: () => void; onDidTriggerPlaying?: () => void; onDidTriggerProjectLoaded?: (project: Project) => void; onDidTriggerRetractFullscreen?: () => void; onDidTriggerSeeked?: (position: number) => void; onDidTriggerSeeking?: () => void; onDidTriggerStall?: () => void; onDidTriggerStateChange?: (state: State) => void; onDidTriggerViewFinished?: () => void; onDidTriggerViewStarted?: () => void; onDidTriggerVolumeChange?: (volume: number) => void; } & ViewProps; // ============================================================================ // Structured Event Types (Channel SDK compatible) // ============================================================================ /** * Player state object returned by getPlayerState(). * Compatible with channel SDK BBPlayerState format. */ export type BBPlayerState = { /** Current playback state */ state: State; /** Current phase */ phase: Phase; /** Current playback mode */ mode: string | null; /** Total duration in seconds */ duration: number; /** Whether audio is muted */ muted: boolean; /** Volume level (0-1) */ volume: number; /** Currently loaded clip data */ clip: { id?: string; title?: string; description?: string; length?: number; } | null; /** Currently loaded project data */ project: { id?: string; name?: string; } | null; /** Current playout data */ playout: { name?: string; } | null; }; /** * Event payload types for structured event handling. * These provide typed payloads for event listeners. */ export type BBPlayerEventPayloads = { play: void; pause: void; playing: void; ended: void; stateChange: { state: State }; phaseChange: { phase: Phase }; modeChange: { mode: string }; durationChange: { duration: number }; volumeChange: { volume: number; muted: boolean }; seeked: { position: number }; seeking: void; stall: void; canPlay: void; fullscreen: void; retractFullscreen: void; mediaClipLoaded: MediaClip; mediaClipFailed: void; projectLoaded: Project; viewStarted: void; viewFinished: void; adLoadStart: void; adLoaded: void; adStarted: void; adQuartile1: void; adQuartile2: void; adQuartile3: void; adFinished: void; adNotFound: void; adError: { error: string }; allAdsCompleted: void; apiReady: void; autoPause: { reason: string }; autoPausePlay: { reason: string }; customStatistics: CustomStatistics; error: { error: string }; }; /** * Event names for the player. */ export type BBPlayerEventName = keyof BBPlayerEventPayloads; // For backwards compatibility export type ExpoBBPlayerViewType = BBPlayerViewMethods; export type ExpoBBPlayerViewProps = BBPlayerViewProps;