UNPKG

bitmovin-player-react-native

Version:

Official React Native bindings for Bitmovin's mobile Player SDKs.

1,369 lines (1,347 loc) 66.6 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/advertising.ts var AdQuartile = /* @__PURE__ */ ((AdQuartile2) => { AdQuartile2["FIRST"] = "first"; AdQuartile2["MID_POINT"] = "mid_point"; AdQuartile2["THIRD"] = "third"; return AdQuartile2; })(AdQuartile || {}); var AdSourceType = /* @__PURE__ */ ((AdSourceType2) => { AdSourceType2["IMA"] = "ima"; AdSourceType2["UNKNOWN"] = "unknown"; AdSourceType2["PROGRESSIVE"] = "progressive"; return AdSourceType2; })(AdSourceType || {}); // src/analytics/player.ts import { NativeModules } from "react-native"; var PlayerAnalyticsModule = NativeModules.PlayerAnalyticsModule; var AnalyticsApi = class { constructor(playerId) { /** * The native player id that this analytics api is attached to. */ __publicField(this, "playerId"); /** * Sends a sample with the provided custom data. * Does not change the configured custom data of the collector or source. */ __publicField(this, "sendCustomDataEvent", (customData) => { PlayerAnalyticsModule.sendCustomDataEvent(this.playerId, customData); }); /** * Gets the current user id used by the bundled analytics instance. * * @returns The current user id. */ __publicField(this, "getUserId", async () => { return PlayerAnalyticsModule.getUserId(this.playerId); }); this.playerId = playerId; } }; // src/audioSession.ts import { NativeModules as NativeModules2 } from "react-native"; var AudioSessionModule = NativeModules2.AudioSessionModule; var AudioSession = { /** * Sets the audio session's category. * * @platform iOS * @see https://developer.apple.com/documentation/avfaudio/avaudiosession/1616583-setcategory */ setCategory: async (category) => { if (AudioSessionModule) { await AudioSessionModule.setCategory(category); } } }; // src/components/PlayerView/index.tsx import React, { useRef, useEffect, useCallback as useCallback2 } from "react"; import { Platform, UIManager, StyleSheet, findNodeHandle as findNodeHandle2 } from "react-native"; // src/components/PlayerView/native.ts import { requireNativeComponent } from "react-native"; var NativePlayerView = requireNativeComponent("NativePlayerView"); // src/hooks/useProxy.ts import omit from "lodash.omit"; import { useCallback } from "react"; import { findNodeHandle } from "react-native"; function unwrapNativeEvent(event) { return omit(event.nativeEvent, ["target"]); } function useProxy(viewRef) { return useCallback( (callback) => (event) => { const node = event.target._nativeTag; if (node === findNodeHandle(viewRef.current)) { callback?.(unwrapNativeEvent(event)); } }, [viewRef] ); } // src/ui/fullscreenhandlerbridge.ts import { NativeModules as NativeModules3 } from "react-native"; import BatchedBridge from "react-native/Libraries/BatchedBridge/BatchedBridge"; var Uuid = NativeModules3.UuidModule; var FullscreenHandlerModule = NativeModules3.FullscreenHandlerModule; var FullscreenHandlerBridge = class { constructor(nativeId) { __publicField(this, "nativeId"); __publicField(this, "fullscreenHandler"); __publicField(this, "isDestroyed"); this.nativeId = nativeId ?? Uuid.generate(); this.isDestroyed = false; BatchedBridge.registerCallableModule( `FullscreenBridge-${this.nativeId}`, this ); FullscreenHandlerModule.registerHandler(this.nativeId); } setFullscreenHandler(fullscreenHandler) { if (this.fullscreenHandler === fullscreenHandler) { return; } this.fullscreenHandler = fullscreenHandler; FullscreenHandlerModule.setIsFullscreenActive( this.nativeId, fullscreenHandler?.isFullscreenActive ?? false ); } /** * Destroys the native FullscreenHandler */ destroy() { if (!this.isDestroyed) { FullscreenHandlerModule.destroy(this.nativeId); this.isDestroyed = true; } } // noinspection JSUnusedGlobalSymbols /** * Called by native code, when the UI should enter fullscreen. */ enterFullscreen() { this.fullscreenHandler?.enterFullscreen(); FullscreenHandlerModule.onFullscreenChanged( this.nativeId, this.fullscreenHandler?.isFullscreenActive ?? false ); } // noinspection JSUnusedGlobalSymbols /** * Called by native code, when the UI should exit fullscreen. */ exitFullscreen() { this.fullscreenHandler?.exitFullscreen(); FullscreenHandlerModule.onFullscreenChanged( this.nativeId, this.fullscreenHandler?.isFullscreenActive ?? false ); } }; // src/ui/custommessagehandlerbridge.ts import { NativeModules as NativeModules4 } from "react-native"; import BatchedBridge2 from "react-native/Libraries/BatchedBridge/BatchedBridge"; var Uuid2 = NativeModules4.UuidModule; var CustomMessageHandlerModule = NativeModules4.CustomMessageHandlerModule; var CustomMessageHandlerBridge = class { constructor(nativeId) { __publicField(this, "nativeId"); __publicField(this, "customMessageHandler"); __publicField(this, "isDestroyed"); this.nativeId = nativeId ?? Uuid2.generate(); this.isDestroyed = false; BatchedBridge2.registerCallableModule( `CustomMessageBridge-${this.nativeId}`, this ); CustomMessageHandlerModule.registerHandler(this.nativeId); } setCustomMessageHandler(customMessageHandler) { this.customMessageHandler = customMessageHandler; this.customMessageHandler.customMessageSender = this; } /** * Destroys the native CustomMessageHandler */ destroy() { if (!this.isDestroyed) { CustomMessageHandlerModule.destroy(this.nativeId); this.isDestroyed = true; } } // noinspection JSUnusedGlobalSymbols /** * Called by native code, when the UI sends a synchronous message. * @internal */ receivedSynchronousMessage(message, data) { const result = this.customMessageHandler?.receivedSynchronousMessage( message, data ); CustomMessageHandlerModule.onReceivedSynchronousMessageResult( this.nativeId, result ); } // noinspection JSUnusedGlobalSymbols /** * Called by native code, when the UI sends an asynchronous message. * @internal */ receivedAsynchronousMessage(message, data) { this.customMessageHandler?.receivedAsynchronousMessage(message, data); } // noinspection JSUnusedGlobalSymbols /** * Called by CustomMessageHandler, when sending a message to the UI. */ sendMessage(message, data) { CustomMessageHandlerModule.sendMessage(this.nativeId, message, data); } }; // src/components/PlayerView/index.tsx var styles = StyleSheet.create({ baseStyle: { alignSelf: "stretch" } }); function dispatch(command, node, ...args) { const commandId = Platform.OS === "android" ? UIManager.NativePlayerView.Commands[command].toString() : UIManager.getViewManagerConfig("NativePlayerView").Commands[command]; UIManager.dispatchViewManagerCommand( node, commandId, Platform.select({ ios: args, android: [node, ...args] }) ); } function PlayerView({ viewRef, style, player, config, fullscreenHandler, customMessageHandler, isFullscreenRequested = false, scalingMode, isPictureInPictureRequested = false, ...props }) { const workaroundViewManagerCommandNotSent = useCallback2(() => { setTimeout(() => player.getDuration(), 100); }, [player]); const nativeView = useRef(viewRef?.current || null); const proxy = useProxy(nativeView); const nativeViewStyle = StyleSheet.flatten([styles.baseStyle, style]); const fullscreenBridge = useRef(void 0); if (fullscreenHandler && !fullscreenBridge.current) { fullscreenBridge.current = new FullscreenHandlerBridge(); } if (fullscreenBridge.current) { fullscreenBridge.current.setFullscreenHandler(fullscreenHandler); } const customMessageHandlerBridge = useRef(void 0); if (customMessageHandler && !customMessageHandlerBridge.current) { customMessageHandlerBridge.current = new CustomMessageHandlerBridge(); } if (customMessageHandlerBridge.current && customMessageHandler) { customMessageHandlerBridge.current.setCustomMessageHandler( customMessageHandler ); } useEffect(() => { player.initialize(); const node = findNodeHandle2(nativeView.current); if (node) { if (customMessageHandlerBridge.current) { dispatch( "setCustomMessageHandlerBridgeId", node, customMessageHandlerBridge.current.nativeId ); } dispatch("attachPlayer", node, player.nativeId, player.config); if (fullscreenBridge.current) { dispatch( "attachFullscreenBridge", node, fullscreenBridge.current.nativeId ); } workaroundViewManagerCommandNotSent(); } return () => { fullscreenBridge.current?.destroy(); fullscreenBridge.current = void 0; customMessageHandlerBridge.current?.destroy(); customMessageHandlerBridge.current = void 0; }; }, [player, workaroundViewManagerCommandNotSent]); useEffect(() => { const node = findNodeHandle2(nativeView.current); if (node) { dispatch("setFullscreen", node, isFullscreenRequested); } }, [isFullscreenRequested, nativeView]); useEffect(() => { const node = findNodeHandle2(nativeView.current); if (node && scalingMode) { dispatch("setScalingMode", node, scalingMode); } }, [scalingMode, nativeView]); useEffect(() => { const node = findNodeHandle2(nativeView.current); if (node) { dispatch("setPictureInPicture", node, isPictureInPictureRequested); } }, [isPictureInPictureRequested, nativeView]); useEffect(() => { if (viewRef) { viewRef.current = nativeView.current; } }, [viewRef, nativeView]); return /* @__PURE__ */ React.createElement( NativePlayerView, { ref: nativeView, style: nativeViewStyle, fullscreenBridge: fullscreenBridge.current, customMessageHandlerBridge: customMessageHandlerBridge.current, config, onBmpAdBreakFinished: proxy(props.onAdBreakFinished), onBmpAdBreakStarted: proxy(props.onAdBreakStarted), onBmpAdClicked: proxy(props.onAdClicked), onBmpAdError: proxy(props.onAdError), onBmpAdFinished: proxy(props.onAdFinished), onBmpAdManifestLoad: proxy(props.onAdManifestLoad), onBmpAdManifestLoaded: proxy(props.onAdManifestLoaded), onBmpAdQuartile: proxy(props.onAdQuartile), onBmpAdScheduled: proxy(props.onAdScheduled), onBmpAdSkipped: proxy(props.onAdSkipped), onBmpAdStarted: proxy(props.onAdStarted), onBmpCastAvailable: proxy(props.onCastAvailable), onBmpCastPaused: proxy(props.onCastPaused), onBmpCastPlaybackFinished: proxy(props.onCastPlaybackFinished), onBmpCastPlaying: proxy(props.onCastPlaying), onBmpCastStarted: proxy(props.onCastStarted), onBmpCastStart: proxy(props.onCastStart), onBmpCastStopped: proxy(props.onCastStopped), onBmpCastTimeUpdated: proxy(props.onCastTimeUpdated), onBmpCastWaitingForDevice: proxy(props.onCastWaitingForDevice), onBmpCueEnter: proxy(props.onCueEnter), onBmpCueExit: proxy(props.onCueExit), onBmpDestroy: proxy(props.onDestroy), onBmpEvent: proxy(props.onEvent), onBmpFullscreenEnabled: proxy(props.onFullscreenEnabled), onBmpFullscreenDisabled: proxy(props.onFullscreenDisabled), onBmpFullscreenEnter: proxy(props.onFullscreenEnter), onBmpFullscreenExit: proxy(props.onFullscreenExit), onBmpMuted: proxy(props.onMuted), onBmpPaused: proxy(props.onPaused), onBmpPictureInPictureAvailabilityChanged: proxy( props.onPictureInPictureAvailabilityChanged ), onBmpPictureInPictureEnter: proxy(props.onPictureInPictureEnter), onBmpPictureInPictureEntered: proxy(props.onPictureInPictureEntered), onBmpPictureInPictureExit: proxy(props.onPictureInPictureExit), onBmpPictureInPictureExited: proxy(props.onPictureInPictureExited), onBmpPlay: proxy(props.onPlay), onBmpPlaybackFinished: proxy(props.onPlaybackFinished), onBmpPlaybackSpeedChanged: proxy(props.onPlaybackSpeedChanged), onBmpPlayerActive: proxy(props.onPlayerActive), onBmpPlayerError: proxy(props.onPlayerError), onBmpPlayerWarning: proxy(props.onPlayerWarning), onBmpPlaying: proxy(props.onPlaying), onBmpReady: proxy(props.onReady), onBmpSeek: proxy(props.onSeek), onBmpSeeked: proxy(props.onSeeked), onBmpTimeShift: proxy(props.onTimeShift), onBmpTimeShifted: proxy(props.onTimeShifted), onBmpStallStarted: proxy(props.onStallStarted), onBmpStallEnded: proxy(props.onStallEnded), onBmpSourceError: proxy(props.onSourceError), onBmpSourceLoad: proxy(props.onSourceLoad), onBmpSourceLoaded: proxy(props.onSourceLoaded), onBmpSourceUnloaded: proxy(props.onSourceUnloaded), onBmpSourceWarning: proxy(props.onSourceWarning), onBmpAudioAdded: proxy(props.onAudioAdded), onBmpAudioChanged: proxy(props.onAudioChanged), onBmpAudioRemoved: proxy(props.onAudioRemoved), onBmpSubtitleAdded: proxy(props.onSubtitleAdded), onBmpSubtitleChanged: proxy(props.onSubtitleChanged), onBmpSubtitleRemoved: proxy(props.onSubtitleRemoved), onBmpTimeChanged: proxy(props.onTimeChanged), onBmpUnmuted: proxy(props.onUnmuted), onBmpVideoDownloadQualityChanged: proxy( props.onVideoDownloadQualityChanged ), onBmpVideoPlaybackQualityChanged: proxy( props.onVideoPlaybackQualityChanged ), onBmpDownloadFinished: proxy(props.onDownloadFinished) } ); } // src/components/PlayerView/playerViewConfig.ts var Variant = class { /** * Specifies the function name that will be used to initialize the `UIManager` * for the Bitmovin Player Web UI. * * The function is called on the `window` object with the `Player` as the first argument and * the `UIConfig` as the second argument. * * Example: * When you added a new function or want to use a different function of our `UIFactory`, * you can specify the full qualifier name including namespaces. * e.g. `bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI` for the SmallScreenUi. * @see UIFactory https://github.com/bitmovin/bitmovin-player-ui/blob/develop/src/ts/uifactory.ts#L60 * * Notes: * - It's not necessary to use our `UIFactory`. Any static function can be specified. */ constructor(uiManagerFactoryFunction) { this.uiManagerFactoryFunction = uiManagerFactoryFunction; } }; var SmallScreenUi = class extends Variant { constructor() { super("bitmovin.playerui.UIFactory.buildDefaultSmallScreenUI"); } }; var TvUi = class extends Variant { constructor() { super("bitmovin.playerui.UIFactory.buildDefaultTvUI"); } }; var CustomUi = class extends Variant { constructor(uiManagerFactoryFunction) { super(uiManagerFactoryFunction); } }; var SurfaceType = /* @__PURE__ */ ((SurfaceType2) => { SurfaceType2["SurfaceView"] = "SurfaceView"; SurfaceType2["TextureView"] = "TextureView"; return SurfaceType2; })(SurfaceType || {}); // src/drm/index.ts import { NativeModules as NativeModules6, Platform as Platform2 } from "react-native"; import BatchedBridge3 from "react-native/Libraries/BatchedBridge/BatchedBridge"; // src/nativeInstance.ts import { NativeModules as NativeModules5 } from "react-native"; var Uuid3 = NativeModules5.UuidModule; var NativeInstance = class { /** * Generate UUID in case the user-defined `nativeId` is empty. */ constructor(config) { /** * Optionally user-defined string `id` for the native instance, or UUIDv4. */ __publicField(this, "nativeId"); /** * The configuration object used to initialize this instance. */ __publicField(this, "config"); this.config = config; this.nativeId = config?.nativeId ?? Uuid3.generate(); } }; // src/drm/index.ts var DrmModule = NativeModules6.DrmModule; var Drm = class extends NativeInstance { constructor() { super(...arguments); /** * Whether this object's native instance has been created. */ __publicField(this, "isInitialized", false); /** * Whether this object's native instance has been disposed. */ __publicField(this, "isDestroyed", false); /** * Allocates the DRM config instance and its resources natively. */ __publicField(this, "initialize", () => { if (!this.isInitialized) { BatchedBridge3.registerCallableModule(`DRM-${this.nativeId}`, this); DrmModule.initWithConfig(this.nativeId, this.config); this.isInitialized = true; } }); /** * Destroys the native DRM config and releases all of its allocated resources. */ __publicField(this, "destroy", () => { if (!this.isDestroyed) { DrmModule.destroy(this.nativeId); this.isDestroyed = true; } }); /** * iOS only. * * Applies the user-defined `prepareCertificate` function to native's `certificate` data and store * the result back in `DrmModule`. * * Called from native code when `FairplayConfig.prepareCertificate` is dispatched. * * @param certificate - Base64 encoded certificate data. */ __publicField(this, "onPrepareCertificate", (certificate) => { if (this.config?.fairplay?.prepareCertificate) { DrmModule.setPreparedCertificate( this.nativeId, this.config?.fairplay?.prepareCertificate?.(certificate) ); } }); /** * Applies the user-defined `prepareMessage` function to native's `message` data and store * the result back in `DrmModule`. * * Called from native code when `prepareMessage` is dispatched. * * @param message - Base64 encoded message data. * @param assetId - Optional asset ID. Only sent by iOS. */ __publicField(this, "onPrepareMessage", (message, assetId) => { const config = Platform2.OS === "ios" ? this.config?.fairplay : this.config?.widevine; if (config && config.prepareMessage) { DrmModule.setPreparedMessage( this.nativeId, Platform2.OS === "ios" ? config.prepareMessage?.(message, assetId) : config.prepareMessage?.(message) ); } }); /** * iOS only. * * Applies the user-defined `prepareSyncMessage` function to native's `syncMessage` data and * store the result back in `DrmModule`. * * Called from native code when `FairplayConfig.prepareSyncMessage` is dispatched. * * @param syncMessage - Base64 encoded sync SPC message data. */ __publicField(this, "onPrepareSyncMessage", (syncMessage, assetId) => { if (this.config?.fairplay?.prepareSyncMessage) { DrmModule.setPreparedSyncMessage( this.nativeId, this.config?.fairplay?.prepareSyncMessage?.(syncMessage, assetId) ); } }); /** * Applies the user-defined `prepareLicense` function to native's `license` data and store * the result back in `DrmModule`. * * Called from native code when `prepareLicense` is dispatched. * * @param license - Base64 encoded license data. */ __publicField(this, "onPrepareLicense", (license) => { const prepareLicense = Platform2.OS === "ios" ? this.config?.fairplay?.prepareLicense : this.config?.widevine?.prepareLicense; if (prepareLicense) { DrmModule.setPreparedLicense(this.nativeId, prepareLicense(license)); } }); /** * iOS only. * * Applies the user-defined `prepareLicenseServerUrl` function to native's `licenseServerUrl` data * and store the result back in `DrmModule`. * * Called from native code when `FairplayConfig.prepareLicenseServerUrl` is dispatched. * * @param licenseServerUrl - The license server URL string. */ __publicField(this, "onPrepareLicenseServerUrl", (licenseServerUrl) => { if (this.config?.fairplay?.prepareLicenseServerUrl) { DrmModule.setPreparedLicenseServerUrl( this.nativeId, this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl) ); } }); /** * iOS only. * * Applies the user-defined `prepareContentId` function to native's `contentId` string * and store the result back in `DrmModule`. * * Called from native code when `FairplayConfig.prepareContentId` is dispatched. * * @param contentId - The extracted contentId string. */ __publicField(this, "onPrepareContentId", (contentId) => { if (this.config?.fairplay?.prepareContentId) { DrmModule.setPreparedContentId( this.nativeId, this.config?.fairplay?.prepareContentId?.(contentId) ); } }); } }; // src/hooks/usePlayer.ts import { useRef as useRef2 } from "react"; // src/player.ts import { NativeModules as NativeModules11, Platform as Platform3 } from "react-native"; // src/source.ts import { NativeModules as NativeModules7 } from "react-native"; var SourceModule = NativeModules7.SourceModule; var SourceType = /* @__PURE__ */ ((SourceType2) => { SourceType2["NONE"] = "none"; SourceType2["HLS"] = "hls"; SourceType2["DASH"] = "dash"; SourceType2["PROGRESSIVE"] = "progressive"; return SourceType2; })(SourceType || {}); var LoadingState = /* @__PURE__ */ ((LoadingState2) => { LoadingState2[LoadingState2["UNLOADED"] = 0] = "UNLOADED"; LoadingState2[LoadingState2["LOADING"] = 1] = "LOADING"; LoadingState2[LoadingState2["LOADED"] = 2] = "LOADED"; return LoadingState2; })(LoadingState || {}); var TimelineReferencePoint = /* @__PURE__ */ ((TimelineReferencePoint2) => { TimelineReferencePoint2["START"] = "start"; TimelineReferencePoint2["END"] = "end"; return TimelineReferencePoint2; })(TimelineReferencePoint || {}); var Source = class extends NativeInstance { constructor() { super(...arguments); /** * The native DRM config reference of this source. */ __publicField(this, "drm"); /** * The remote control config for this source. * This is only supported on iOS. * * @platform iOS */ __publicField(this, "remoteControl", null); /** * Whether the native {@link Source} object has been created. */ __publicField(this, "isInitialized", false); /** * Whether the native {@link Source} object has been disposed. */ __publicField(this, "isDestroyed", false); /** * Allocates the native {@link Source} instance and its resources natively. */ __publicField(this, "initialize", () => { if (!this.isInitialized) { const sourceMetadata = this.config?.analyticsSourceMetadata; if (this.config?.drmConfig) { this.drm = new Drm(this.config.drmConfig); this.drm.initialize(); } if (sourceMetadata) { SourceModule.initWithAnalyticsConfig( this.nativeId, this.drm?.nativeId, this.config, this.remoteControl, sourceMetadata ); } else { SourceModule.initWithConfig( this.nativeId, this.drm?.nativeId, this.config, this.remoteControl ); } this.isInitialized = true; } }); /** * Destroys the native {@link Source} and releases all of its allocated resources. */ __publicField(this, "destroy", () => { if (!this.isDestroyed) { SourceModule.destroy(this.nativeId); this.drm?.destroy(); this.isDestroyed = true; } }); /** * The duration of the source in seconds if it’s a VoD or `INFINITY` if it’s a live stream. * Default value is `0` if the duration is not available or not known. */ __publicField(this, "duration", async () => { return SourceModule.duration(this.nativeId); }); /** * Whether the source is currently active in a player (i.e. playing back or paused). * Only one source can be active in the same player instance at any time. */ __publicField(this, "isActive", async () => { return SourceModule.isActive(this.nativeId); }); /** * Whether the source is currently attached to a player instance. */ __publicField(this, "isAttachedToPlayer", async () => { return SourceModule.isAttachedToPlayer(this.nativeId); }); /** * Metadata for the currently loaded source. */ __publicField(this, "metadata", async () => { return SourceModule.getMetadata(this.nativeId); }); /** * Set metadata for the currently loaded source. * Setting the metadata to `null` clears the metadata object in native source. * * @param metadata metadata to be set. */ __publicField(this, "setMetadata", (metadata) => { SourceModule.setMetadata(this.nativeId, metadata); }); /** * The current `LoadingState` of the source. */ __publicField(this, "loadingState", async () => { return SourceModule.loadingState(this.nativeId); }); /** * @returns a `Thumbnail` for the specified playback time if available. * Supported thumbnail formats are: * - `WebVtt` configured via {@link SourceConfig.thumbnailTrack}, on all supported platforms * - HLS `Image Media Playlist` in the multivariant playlist, Android-only * - DASH `Image Adaptation Set` as specified in DASH-IF IOP, Android-only * If a `WebVtt` thumbnail track is provided, any potential in-manifest thumbnails are ignored on Android. * * @param time - The time in seconds for which to retrieve the thumbnail. */ __publicField(this, "getThumbnail", async (time) => { return SourceModule.getThumbnail(this.nativeId, time); }); } }; // src/bufferApi.ts import { NativeModules as NativeModules8 } from "react-native"; var BufferModule = NativeModules8.BufferModule; var MediaType = /* @__PURE__ */ ((MediaType2) => { MediaType2["AUDIO"] = "audio"; MediaType2["VIDEO"] = "video"; return MediaType2; })(MediaType || {}); var BufferType = /* @__PURE__ */ ((BufferType2) => { BufferType2["FORWARD_DURATION"] = "forwardDuration"; BufferType2["BACKWARD_DURATION"] = "backwardDuration"; return BufferType2; })(BufferType || {}); var BufferApi = class { constructor(playerId) { /** * The native player id that this buffer api is attached to. */ __publicField(this, "nativeId"); /** * Gets the {@link BufferLevel|buffer level} from the Player * @param type The {@link BufferType} to return the level for. * @returns a {@link BufferLevels} that contains {@link BufferLevel} values for audio and video. */ __publicField(this, "getLevel", async (type) => { return BufferModule.getLevel(this.nativeId, type); }); /** * Sets the target buffer level for the chosen buffer {@link BufferType} across all {@link MediaType} options. * * @param type The {@link BufferType} to set the target level for. On iOS and tvOS, only {@link BufferType.FORWARD_DURATION} is supported. * @param value The value to set. On iOS and tvOS when passing `0`, the player will choose an appropriate forward buffer duration suitable for most use-cases. On Android setting to `0` will have no effect. */ __publicField(this, "setTargetLevel", async (type, value) => { return BufferModule.setTargetLevel(this.nativeId, type, value); }); this.nativeId = playerId; } }; // src/network/index.ts import { NativeModules as NativeModules9 } from "react-native"; import BatchedBridge4 from "react-native/Libraries/BatchedBridge/BatchedBridge"; // src/network/networkConfig.ts var HttpRequestType = /* @__PURE__ */ ((HttpRequestType2) => { HttpRequestType2["ManifestDash"] = "manifest/dash"; HttpRequestType2["ManifestHlsMaster"] = "manifest/hls/master"; HttpRequestType2["ManifestHlsVariant"] = "manifest/hls/variant"; HttpRequestType2["ManifestSmooth"] = "manifest/smooth"; HttpRequestType2["MediaProgressive"] = "media/progressive"; HttpRequestType2["MediaAudio"] = "media/audio"; HttpRequestType2["MediaVideo"] = "media/video"; HttpRequestType2["MediaSubtitles"] = "media/subtitles"; HttpRequestType2["MediaThumbnails"] = "media/thumbnails"; HttpRequestType2["DrmLicenseFairplay"] = "drm/license/fairplay"; HttpRequestType2["DrmCertificateFairplay"] = "drm/certificate/fairplay"; HttpRequestType2["DrmLicenseWidevine"] = "drm/license/widevine"; HttpRequestType2["KeyHlsAes"] = "key/hls/aes"; HttpRequestType2["Unknown"] = "unknown"; return HttpRequestType2; })(HttpRequestType || {}); // src/network/index.ts var NetworkModule = NativeModules9.NetworkModule; var Network = class extends NativeInstance { constructor() { super(...arguments); /** * Whether this object's native instance has been created. */ __publicField(this, "isInitialized", false); /** * Whether this object's native instance has been disposed. */ __publicField(this, "isDestroyed", false); /** * Allocates the Network config instance and its resources natively. */ __publicField(this, "initialize", () => { if (!this.isInitialized) { BatchedBridge4.registerCallableModule(`Network-${this.nativeId}`, this); NetworkModule.initWithConfig(this.nativeId, this.config); this.isInitialized = true; } }); /** * Destroys the native Network config and releases all of its allocated resources. */ __publicField(this, "destroy", () => { if (!this.isDestroyed) { NetworkModule.destroy(this.nativeId); this.isDestroyed = true; } }); /** * Applies the user-defined `preprocessHttpRequest` function to native's `type` and `request` data and store * the result back in `NetworkModule`. * * Called from native code when `NetworkConfig.preprocessHttpRequest` is dispatched. * * @param requestId Passed through to identify the completion handler of the request on native. * @param type Type of the request to be made. * @param request The HTTP request to process. */ __publicField(this, "onPreprocessHttpRequest", (requestId, type, request) => { this.config?.preprocessHttpRequest?.(type, request).then((resultRequest) => { NetworkModule.setPreprocessedHttpRequest(requestId, resultRequest); }).catch(() => { NetworkModule.setPreprocessedHttpRequest(requestId, request); }); }); /** * Applies the user-defined `preprocessHttpResponse` function to native's `type` and `response` data and store * the result back in `NetworkModule`. * * Called from native code when `NetworkConfig.preprocessHttpResponse` is dispatched. * * @param responseId Passed through to identify the completion handler of the response on native. * @param type Type of the request to be made. * @param response The HTTP response to process. */ __publicField(this, "onPreprocessHttpResponse", (responseId, type, response) => { this.config?.preprocessHttpResponse?.(type, response).then((resultResponse) => { NetworkModule.setPreprocessedHttpResponse(responseId, resultResponse); }).catch(() => { NetworkModule.setPreprocessedHttpResponse(responseId, response); }); }); } }; // src/decoder/index.ts import { NativeModules as NativeModules10 } from "react-native"; import BatchedBridge5 from "react-native/Libraries/BatchedBridge/BatchedBridge"; var DecoderConfigModule = NativeModules10.DecoderConfigModule; var DecoderConfigBridge = class extends NativeInstance { constructor(decoderConfig) { super(decoderConfig); /** * Whether this object's native instance has been created. */ __publicField(this, "isInitialized", false); /** * Whether this object's native instance has been disposed. */ __publicField(this, "isDestroyed", false); } initialize() { if (!this.isInitialized) { BatchedBridge5.registerCallableModule( `DecoderConfigBridge-${this.nativeId}`, this ); DecoderConfigModule.initWithConfig(this.nativeId, this.config); this.isInitialized = true; } } /** * Destroys the native `DecoderConfig` */ destroy() { if (!this.isDestroyed) { DecoderConfigModule.destroy(this.nativeId); this.isDestroyed = true; } } // noinspection JSUnusedGlobalSymbols /** * Called by native code, when the decoder priority should be evaluated. */ overrideDecodersPriority(context, preferredDecoders) { const orderedPriority = this.config?.decoderPriorityProvider?.overrideDecodersPriority( context, preferredDecoders ) ?? preferredDecoders; DecoderConfigModule.overrideDecoderPriorityProviderComplete( this.nativeId, orderedPriority ); } }; // src/player.ts var PlayerModule = NativeModules11.PlayerModule; var Player = class extends NativeInstance { constructor() { super(...arguments); /** * Whether the native `Player` object has been created. */ __publicField(this, "isInitialized", false); /** * Whether the native `Player` object has been disposed. */ __publicField(this, "isDestroyed", false); /** * Currently active source, or `null` if none is active. */ __publicField(this, "source"); /** * The `AnalyticsApi` for interactions regarding the `Player`'s analytics. * * `undefined` if the player was created without analytics support. */ __publicField(this, "analytics"); /** * The {@link BufferApi} for interactions regarding the buffer. */ __publicField(this, "buffer", new BufferApi(this.nativeId)); __publicField(this, "network"); __publicField(this, "decoderConfig"); /** * Allocates the native `Player` instance and its resources natively. */ __publicField(this, "initialize", () => { if (!this.isInitialized) { if (this.config?.networkConfig) { this.network = new Network(this.config.networkConfig); this.network.initialize(); } this.maybeInitDecoderConfig(); const analyticsConfig = this.config?.analyticsConfig; if (analyticsConfig) { PlayerModule.initWithAnalyticsConfig( this.nativeId, this.config, this.network?.nativeId, this.decoderConfig?.nativeId, analyticsConfig ); this.analytics = new AnalyticsApi(this.nativeId); } else { PlayerModule.initWithConfig( this.nativeId, this.config, this.network?.nativeId, this.decoderConfig?.nativeId ); } this.isInitialized = true; } }); /** * Destroys the native `Player` and releases all of its allocated resources. */ __publicField(this, "destroy", () => { if (!this.isDestroyed) { PlayerModule.destroy(this.nativeId); this.source?.destroy(); this.network?.destroy(); this.decoderConfig?.destroy(); this.isDestroyed = true; } }); /** * Loads a new {@link Source} from `sourceConfig` into the player. */ __publicField(this, "load", (sourceConfig) => { this.loadSource(new Source(sourceConfig)); }); /** * Loads the downloaded content from {@link OfflineContentManager} into the player. */ __publicField(this, "loadOfflineContent", (offlineContentManager, options) => { PlayerModule.loadOfflineContent( this.nativeId, offlineContentManager.nativeId, options ); }); /** * Loads the given {@link Source} into the player. */ __publicField(this, "loadSource", (source) => { source.initialize(); this.source = source; PlayerModule.loadSource(this.nativeId, source.nativeId); }); /** * Unloads all {@link Source}s from the player. */ __publicField(this, "unload", () => { PlayerModule.unload(this.nativeId); }); /** * Starts or resumes playback after being paused. Has no effect if the player is already playing. */ __publicField(this, "play", () => { PlayerModule.play(this.nativeId); }); /** * Pauses the video if it is playing. Has no effect if the player is already paused. */ __publicField(this, "pause", () => { PlayerModule.pause(this.nativeId); }); /** * Seeks to the given playback time specified by the parameter `time` in seconds. Must not be * greater than the total duration of the video. Has no effect when watching a live stream since * seeking is not possible. * * @param time - The time to seek to in seconds. */ __publicField(this, "seek", (time) => { PlayerModule.seek(this.nativeId, time); }); /** * Shifts the time to the given `offset` in seconds from the live edge. The resulting offset has to be within the * timeShift window as specified by `maxTimeShift` (which is a negative value) and 0. When the provided `offset` is * positive, it will be interpreted as a UNIX timestamp in seconds and converted to fit into the timeShift window. * When the provided `offset` is negative, but lower than `maxTimeShift`, then it will be clamped to `maxTimeShift`. * Has no effect for VoD. * * Has no effect if no sources are loaded. * * @param offset - Target offset from the live edge in seconds. */ __publicField(this, "timeShift", (offset) => { PlayerModule.timeShift(this.nativeId, offset); }); /** * Mutes the player if an audio track is available. Has no effect if the player is already muted. */ __publicField(this, "mute", () => { PlayerModule.mute(this.nativeId); }); /** * Unmutes the player if it is muted. Has no effect if the player is already unmuted. */ __publicField(this, "unmute", () => { PlayerModule.unmute(this.nativeId); }); /** * Sets the player's volume between 0 (silent) and 100 (max volume). * * @param volume - The volume level to set. */ __publicField(this, "setVolume", (volume) => { PlayerModule.setVolume(this.nativeId, volume); }); /** * @returns The player's current volume level. */ __publicField(this, "getVolume", async () => { return PlayerModule.getVolume(this.nativeId); }); /** * @returns The current playback time in seconds. * * For VoD streams the returned time ranges between 0 and the duration of the asset. * * For live streams it can be specified if an absolute UNIX timestamp or a value * relative to the playback start should be returned. * * @param mode - The time mode to specify: an absolute UNIX timestamp ('absolute') or relative time ('relative'). */ __publicField(this, "getCurrentTime", async (mode = "absolute") => { return PlayerModule.currentTime(this.nativeId, mode); }); /** * @returns The total duration in seconds of the current video or INFINITY if it’s a live stream. */ __publicField(this, "getDuration", async () => { return PlayerModule.duration(this.nativeId); }); /** * @returns `true` if the player is muted. */ __publicField(this, "isMuted", async () => { return PlayerModule.isMuted(this.nativeId); }); /** * @returns `true` if the player is currently playing, i.e. has started and is not paused. */ __publicField(this, "isPlaying", async () => { return PlayerModule.isPlaying(this.nativeId); }); /** * @returns `true` if the player has started playback but it's currently paused. */ __publicField(this, "isPaused", async () => { return PlayerModule.isPaused(this.nativeId); }); /** * @returns `true` if the displayed video is a live stream. */ __publicField(this, "isLive", async () => { return PlayerModule.isLive(this.nativeId); }); /** * @remarks Only available for iOS devices. * @returns `true` when media is played externally using AirPlay. */ __publicField(this, "isAirPlayActive", async () => { if (Platform3.OS === "android") { console.warn( `[Player ${this.nativeId}] Method isAirPlayActive is not available for Android. Only iOS devices.` ); return false; } return PlayerModule.isAirPlayActive(this.nativeId); }); /** * @remarks Only available for iOS devices. * @returns `true` when AirPlay is available. */ __publicField(this, "isAirPlayAvailable", async () => { if (Platform3.OS === "android") { console.warn( `[Player ${this.nativeId}] Method isAirPlayAvailable is not available for Android. Only iOS devices.` ); return false; } return PlayerModule.isAirPlayAvailable(this.nativeId); }); /** * @returns The currently selected audio track or `null`. */ __publicField(this, "getAudioTrack", async () => { return PlayerModule.getAudioTrack(this.nativeId); }); /** * @returns An array containing {@link AudioTrack} objects for all available audio tracks. */ __publicField(this, "getAvailableAudioTracks", async () => { return PlayerModule.getAvailableAudioTracks(this.nativeId); }); /** * Sets the audio track to the ID specified by trackIdentifier. A list can be retrieved by calling getAvailableAudioTracks. * * @param trackIdentifier - The {@link AudioTrack.identifier} to be set. */ __publicField(this, "setAudioTrack", async (trackIdentifier) => { return PlayerModule.setAudioTrack(this.nativeId, trackIdentifier); }); /** * @returns The currently selected {@link SubtitleTrack} or `null`. */ __publicField(this, "getSubtitleTrack", async () => { return PlayerModule.getSubtitleTrack(this.nativeId); }); /** * @returns An array containing SubtitleTrack objects for all available subtitle tracks. */ __publicField(this, "getAvailableSubtitles", async () => { return PlayerModule.getAvailableSubtitles(this.nativeId); }); /** * Sets the subtitle track to the ID specified by trackIdentifier. A list can be retrieved by calling getAvailableSubtitles. * * @param trackIdentifier - The {@link SubtitleTrack.identifier} to be set. */ __publicField(this, "setSubtitleTrack", async (trackIdentifier) => { return PlayerModule.setSubtitleTrack(this.nativeId, trackIdentifier); }); /** * Dynamically schedules the {@link AdItem} for playback. * Has no effect if there is no active playback session. * * @param adItem - Ad to be scheduled for playback. * * @platform iOS, Android */ __publicField(this, "scheduleAd", (adItem) => { PlayerModule.scheduleAd(this.nativeId, adItem); }); /** * Skips the current ad. * Has no effect if the current ad is not skippable or if no ad is being played back. * * @platform iOS, Android */ __publicField(this, "skipAd", () => { PlayerModule.skipAd(this.nativeId); }); /** * @returns `true` while an ad is being played back or when main content playback has been paused for ad playback. * @platform iOS, Android */ __publicField(this, "isAd", async () => { return PlayerModule.isAd(this.nativeId); }); /** * The current time shift of the live stream in seconds. This value is always 0 if the active {@link Source} is not a * live stream or no sources are loaded. */ __publicField(this, "getTimeShift", async () => { return PlayerModule.getTimeShift(this.nativeId); }); /** * The limit in seconds for time shifting. This value is either negative or 0 and it is always 0 if the active * {@link Source} is not a live stream or no sources are loaded. */ __publicField(this, "getMaxTimeShift", async () => { return PlayerModule.getMaxTimeShift(this.nativeId); }); /** * Sets the upper bitrate boundary for video qualities. All qualities with a bitrate * that is higher than this threshold will not be eligible for automatic quality selection. * * Can be set to `null` for no limitation. */ __publicField(this, "setMaxSelectableBitrate", (bitrate) => { PlayerModule.setMaxSelectableBitrate(this.nativeId, bitrate || -1); }); /** * @returns a {@link Thumbnail} for the specified playback time for the currently active source if available. * Supported thumbnail formats are: * - `WebVtt` configured via {@link SourceConfig.thumbnailTrack}, on all supported platforms * - HLS `Image Media Playlist` in the multivariant playlist, Android-only * - DASH `Image Adaptation Set` as specified in DASH-IF IOP, Android-only * If a `WebVtt` thumbnail track is provided, any potential in-manifest thumbnails are ignored on Android. * * @param time - The time in seconds for which to retrieve the thumbnail. */ __publicField(this, "getThumbnail", async (time) => { return PlayerModule.getThumbnail(this.nativeId, time); }); /** * Whether casting to a cast-compatible remote device is available. {@link CastAvailableEvent} signals when * casting becomes available. * * @platform iOS, Android */ __publicField(this, "isCastAvailable", async () => { return PlayerModule.isCastAvailable(this.nativeId); }); /** * Whether video is currently being casted to a remote device and not played locally. * * @platform iOS, Android */ __publicField(this, "isCasting", async () => { return PlayerModule.isCasting(this.nativeId); }); /** * Initiates casting the current video to a cast-compatible remote device. The user has to choose to which device it * should be sent. * * @platform iOS, Android */ __publicField(this, "castVideo", () => { PlayerModule.castVideo(this.nativeId); }); /** * Stops casting the current video. Has no effect if {@link Player.isCasting} is `false`. * * @platform iOS, Android */ __publicField(this, "castStop", () => { PlayerModule.castStop(this.nativeId); }); /** * Returns the currently selected video quality. * @returns The currently selected video quality. */ __publicField(this, "getVideoQuality", async () => { return PlayerModule.getVideoQuality(this.nativeId); }); /** * Returns an array containing all available video qualities the player can adapt between. * @returns An array containing all available video qualities the player can adapt between. */ __publicField(this, "getAvailableVideoQualities", async () => { return PlayerModule.getAvailableVideoQualities(this.nativeId); }); /** * Sets the video quality. * @remarks Only available on Android. * @platform Android * * @param qualityId value obtained from {@link VideoQuality}'s `id` property, which can be obtained via `Player.getAvailableVideoQualities()` to select a specific quality. To use automatic quality selection, 'auto' can be passed here. */ __publicField(this, "setVideoQuality", (qualityId) => { if (Platform3.OS !== "android") { console.warn( `[Player ${this.nativeId}] Method setVideoQuality is not available for iOS and tvOS devices. Only Android devices.` ); return; } PlayerModule.setVideoQuality(this.nativeId, qualityId); }); /** * Sets the playback speed of the player. Fast forward, slow motion and reverse playback are supported. * @note * - Slow motion is indicated by values between `0` and `1`. * - Fast forward by values greater than `1`. * - Slow reverse is used by values between `0` and `-1`, and fast reverse is used by values less than `-1`. iOS and tvOS only. * @note * Negative values are ignored during Casting and on Android. * @note * During reverse playback the playback will continue until the beginning of the active source is * reached. When reaching the beginning of the source, playback will be paused and the playback * speed will be reset to its default value of `1`. No {@link PlaybackFinishedEvent} will be * emitted in this case. * * @param playbackSpeed - The playback speed to set. */ __publicField(this, "setPlaybackSpeed", (playbackSpeed) => { PlayerModule.setPlaybackSpeed(this.nativeId, playbackSpeed); }); /** * @see {@link setPlaybackSpeed} for details on which values playback speed can assume. * @returns The player's current playback speed. */ __publicField(this, "getPlaybackSpeed", async () => { return PlayerModule.getPlaybackSpeed(this.nativeId); }); /** * Checks the possibility to play the media at specified playback speed. * @param playbackSpeed - The playback speed to check. * @returns `true` if it's possible to play the media at the specified playback speed, otherwise `false`. On Androi