UNPKG

bitmovin-player-react-native

Version:

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

274 lines (254 loc) 8.03 kB
import { Platform } from 'react-native'; import { EventSubscription } from 'expo-modules-core'; import NativeInstance, { NativeInstanceConfig } from '../nativeInstance'; import { FairplayConfig } from './fairplayConfig'; import { WidevineConfig } from './widevineConfig'; import DrmModule from './drmModule'; // Export config types from DRM module. export { FairplayConfig, WidevineConfig }; /** * Represents the general Streaming DRM config. */ export interface DrmConfig extends NativeInstanceConfig { /** * FairPlay specific configuration. * * @platform iOS */ fairplay?: FairplayConfig; /** * Widevine specific configuration. * * @platform Android, iOS (only for casting). */ widevine?: WidevineConfig; } /** * Represents a native DRM configuration object. * @internal */ export class Drm extends NativeInstance<DrmConfig> { /** * Whether this object's native instance has been created. */ isInitialized = false; /** * Whether this object's native instance has been disposed. */ isDestroyed = false; private eventSubscriptions: EventSubscription[] = []; /** * Allocates the DRM config instance and its resources natively. */ initialize = async () => { if (!this.isInitialized) { // Set up event listeners for DRM preparation callbacks this.setupEventListeners(); // Create native configuration object using Expo module. if (this.config) { await DrmModule.initializeWithConfig(this.nativeId, this.config); } this.isInitialized = true; } }; /** * Destroys the native DRM config and releases all of its allocated resources. */ destroy = async () => { if (!this.isDestroyed) { await DrmModule.destroy(this.nativeId); // Clean up event subscriptions this.eventSubscriptions.forEach((subscription) => subscription.remove()); this.eventSubscriptions = []; this.isDestroyed = true; } }; /** * Sets up event listeners for all DRM preparation callbacks */ private setupEventListeners() { // iOS-only events this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareCertificate', ({ nativeId, id, certificate }) => { if (nativeId !== this.nativeId) return; this.onPrepareCertificate(id, certificate); } ) ); this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareSyncMessage', ({ nativeId, id, syncMessage, assetId }) => { if (nativeId !== this.nativeId) return; this.onPrepareSyncMessage(id, syncMessage, assetId); } ) ); this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareLicenseServerUrl', ({ nativeId, id, licenseServerUrl }) => { if (nativeId !== this.nativeId) return; this.onPrepareLicenseServerUrl(id, licenseServerUrl); } ) ); this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareContentId', ({ nativeId, id, contentId }) => { if (nativeId !== this.nativeId) return; this.onPrepareContentId(id, contentId); } ) ); // Cross-platform events this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareMessage', ({ nativeId, id, data, message, assetId }) => { if (nativeId !== this.nativeId) return; // Android sends 'data', iOS sends 'message' this.onPrepareMessage(id, data || message, assetId); } ) ); this.eventSubscriptions.push( DrmModule.addListener( 'onPrepareLicense', ({ nativeId, id, data, license }) => { if (nativeId !== this.nativeId) return; // Android sends 'data', iOS sends 'license' this.onPrepareLicense(id, data || license); } ) ); } /** * 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. */ private onPrepareCertificate = (id: string, certificate: string) => { if (this.config?.fairplay?.prepareCertificate) { const result = this.config?.fairplay?.prepareCertificate?.(certificate); DrmModule.setPreparedCertificate(id, result); } }; /** * 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. */ private onPrepareMessage = ( id: string, message?: string, assetId?: string ) => { if (!message) { DrmModule.setPreparedMessage(id, undefined); return; } const config = Platform.OS === 'ios' ? this.config?.fairplay : this.config?.widevine; if (config && config.prepareMessage) { const result = Platform.OS === 'ios' ? (config as FairplayConfig).prepareMessage?.(message, assetId!) : (config as WidevineConfig).prepareMessage?.(message); DrmModule.setPreparedMessage(id, result); } }; /** * 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. */ private onPrepareSyncMessage = ( id: string, syncMessage: string, assetId: string ) => { if (this.config?.fairplay?.prepareSyncMessage) { const result = this.config?.fairplay?.prepareSyncMessage?.( syncMessage, assetId ); DrmModule.setPreparedSyncMessage(id, result); } }; /** * 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. */ private onPrepareLicense = (id: string, license?: string) => { if (!license) { DrmModule.setPreparedLicense(id, undefined); return; } const prepareLicense = Platform.OS === 'ios' ? this.config?.fairplay?.prepareLicense : this.config?.widevine?.prepareLicense; if (prepareLicense) { DrmModule.setPreparedLicense(id, 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. */ private onPrepareLicenseServerUrl = ( id: string, licenseServerUrl: string ) => { if (this.config?.fairplay?.prepareLicenseServerUrl) { const result = this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl); DrmModule.setPreparedLicenseServerUrl(id, result); } }; /** * 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. */ private onPrepareContentId = (id: string, contentId: string) => { console.log('onPrepareContentId', contentId); if (this.config?.fairplay?.prepareContentId) { const result = this.config?.fairplay?.prepareContentId?.(contentId); DrmModule.setPreparedContentId(id, result); } }; }