UNPKG

bitmovin-player-react-native

Version:

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

225 lines (203 loc) 6.73 kB
import { AndroidConfig, ConfigPlugin, withAndroidManifest, withGradleProperties, } from 'expo/config-plugins'; import Features from './Features'; import withAppGradleDependencies from './withAppGradleDependencies'; type ManifestActivity = AndroidConfig.Manifest.ManifestActivity; const withBitmovinAndroidConfig: ConfigPlugin<{ playerLicenseKey: string; features: Features; }> = (config, { playerLicenseKey, features }) => { const offlineFeatureConfig = typeof features.offline === 'object' ? features.offline : { android: { isEnabled: !!features.offline, externalStoragePermission: false, }, ios: { isEnabled: !!features.offline }, }; if (features.backgroundPlayback) { config = AndroidConfig.Permissions.withPermissions(config, [ 'android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK', 'android.permission.FOREGROUND_SERVICE', ]); } if (offlineFeatureConfig.android?.isEnabled) { config = AndroidConfig.Permissions.withPermissions(config, [ 'android.permission.ACCESS_NETWORK_STATE', 'android.permission.FOREGROUND_SERVICE', 'android.permission.FOREGROUND_SERVICE_DATA_SYNC', 'android.permission.POST_NOTIFICATIONS', ]); if (offlineFeatureConfig.android?.externalStoragePermission) { config = AndroidConfig.Permissions.withPermissions(config, [ 'android.permission.WRITE_EXTERNAL_STORAGE', ]); } } config = withAndroidManifest(config, (config) => { const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow( config.modResults ); AndroidConfig.Manifest.addMetaDataItemToMainApplication( mainApplication, 'BITMOVIN_PLAYER_LICENSE_KEY', playerLicenseKey ); config.modResults.manifest['uses-permission'] = config.modResults.manifest['uses-permission'] || []; // Configure Picture-in-Picture support if (features.pictureInPicture) { const mainActivity = AndroidConfig.Manifest.getMainActivityOrThrow( config.modResults ); // Add PiP support attribute mainActivity.$['android:supportsPictureInPicture'] = 'true'; // Enhance configChanges to handle PiP transitions properly const currentConfigChanges = mainActivity.$['android:configChanges'] || ''; const requiredConfigChanges = [ 'keyboard', 'keyboardHidden', 'orientation', 'screenLayout', 'screenSize', 'smallestScreenSize', 'uiMode', ]; const existingChanges = currentConfigChanges.split('|').filter(Boolean); const allChanges = [ ...new Set([...existingChanges, ...requiredConfigChanges]), ]; mainActivity.$['android:configChanges'] = allChanges.join('|'); } if (features.backgroundPlayback) { mainApplication.service = mainApplication.service || []; if ( !mainApplication.service.find( (s) => s.$['android:name'] === 'com.bitmovin.player.reactnative.services.MediaSessionPlaybackService' ) ) { mainApplication.service.push({ '$': { 'android:name': 'com.bitmovin.player.reactnative.services.MediaSessionPlaybackService', 'android:exported': 'true', 'android:foregroundServiceType': 'mediaPlayback', }, 'intent-filter': [ { action: [ { $: { 'android:name': 'androidx.media3.session.MediaSessionService', }, }, ], }, ], }); } } if (features.googleCastSDK) { const expandedControllerActivity = { '$': { 'android:name': 'com.bitmovin.player.casting.ExpandedControllerActivity', 'android:exported': 'true', 'android:label': '@string/app_name', 'android:launchMode': 'singleTask', 'android:screenOrientation': 'portrait', }, 'intent-filter': [ { action: [ { $: { 'android:name': 'android.intent.action.MAIN' }, }, ], }, ], 'meta-data': [ { $: { 'android:name': 'android.support.PARENT_ACTIVITY', 'android:value': '.MainActivity', // maybe needs to be taken from main activity }, }, ], } as ManifestActivity; mainApplication.activity = mainApplication.activity || []; if ( !mainApplication.activity.find( (a) => a.$['android:name'] === expandedControllerActivity.$['android:name'] ) ) { mainApplication.activity.push(expandedControllerActivity); } AndroidConfig.Manifest.addMetaDataItemToMainApplication( mainApplication, 'com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME', 'com.bitmovin.player.casting.BitmovinCastOptionsProvider' ); } return config; }); const dependencies: string[] = []; if (features.offline) { dependencies.push( 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' ); } if (features.googleCastSDK?.android) { const castSdkVersion = typeof features.googleCastSDK.android === 'string' ? features.googleCastSDK.android : features.googleCastSDK.android.version; if (!castSdkVersion) { throw new Error( 'Google Cast SDK version is not specified in feature flags.' ); } dependencies.push( `com.google.android.gms:play-services-cast-framework:${castSdkVersion}` ); } config = withAppGradleDependencies(config, { dependencies }); config = withGradleProperties(config, (config) => { const properties = config.modResults; const existingEntry = properties.find( (item) => item.type === 'property' && item.key === 'android.extraMavenRepos' && item.value ); if (existingEntry) { properties.splice(config.modResults.indexOf(existingEntry), 1); } const mavenRepos = JSON.parse( existingEntry?.type == 'property' ? existingEntry.value : '[]' ); mavenRepos.push({ url: 'https://artifacts.bitmovin.com/artifactory/public-releases', }); properties.push({ type: 'property', key: 'android.extraMavenRepos', value: JSON.stringify(mavenRepos), }); config.modResults = properties; return config; }); return config; }; export default withBitmovinAndroidConfig;