bitmovin-player-react-native 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,7 @@ Pod::Spec.new do |s|
20
20
 
21
21
  s.swift_version = "5.10"
22
22
  s.dependency "React-Core"
23
- s.dependency "BitmovinPlayer", "3.85.2"
23
+ s.dependency "BitmovinPlayer", "3.86.0"
24
24
  s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.23.0"
25
25
  s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.13.0"
26
26
  end
@@ -103,8 +103,8 @@ dependencies {
103
103
  implementation "androidx.concurrent:concurrent-futures-ktx:1.1.0"
104
104
 
105
105
  // Bitmovin
106
- implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.33.0'
106
+ implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1'
107
107
  implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
108
- implementation 'com.bitmovin.player:player:3.104.2+jason'
109
- implementation 'com.bitmovin.player:player-media-session:3.104.2+jason'
108
+ implementation 'com.bitmovin.player:player:3.106.0+jason'
109
+ implementation 'com.bitmovin.player:player-media-session:3.106.0+jason'
110
110
  }
@@ -1,8 +1,8 @@
1
1
  android.useAndroidX=true
2
2
  BitmovinPlayerReactNative_kotlinVersion=1.9.21
3
3
  BitmovinPlayerReactNative_minSdkVersion=21
4
- BitmovinPlayerReactNative_targetSdkVersion=34
5
- BitmovinPlayerReactNative_compileSdkVersion=34
4
+ BitmovinPlayerReactNative_targetSdkVersion=35
5
+ BitmovinPlayerReactNative_compileSdkVersion=35
6
6
  BitmovinPlayerReactNative_buildToolsVersion=34.0.0
7
7
  BitmovinPlayerReactNative_ndkversion=25.1.8937393
8
8
  BitmovinPlayerReactNative_androidToolsVersion=8.1.0
@@ -3,6 +3,7 @@ package com.bitmovin.player.reactnative
3
3
  import android.util.Log
4
4
  import com.bitmovin.player.api.Player
5
5
  import com.bitmovin.player.api.source.Source
6
+ import com.bitmovin.player.reactnative.extensions.decoderConfigModule
6
7
  import com.bitmovin.player.reactnative.extensions.drmModule
7
8
  import com.bitmovin.player.reactnative.extensions.networkModule
8
9
  import com.bitmovin.player.reactnative.extensions.offlineModule
@@ -58,6 +59,9 @@ abstract class BitmovinBaseModule(
58
59
  protected val RejectPromiseOnExceptionBlock.networkModule: NetworkModule get() = context.networkModule
59
60
  ?: throw IllegalStateException("NetworkModule not found")
60
61
 
62
+ protected val RejectPromiseOnExceptionBlock.decoderConfigModule: DecoderConfigModule
63
+ get() = context.decoderConfigModule ?: throw IllegalStateException("DecoderConfigModule not found")
64
+
61
65
  fun RejectPromiseOnExceptionBlock.getPlayer(
62
66
  nativeId: NativeId,
63
67
  playerModule: PlayerModule = this.playerModule,
@@ -0,0 +1,81 @@
1
+ package com.bitmovin.player.reactnative
2
+
3
+ import androidx.concurrent.futures.CallbackToFutureAdapter
4
+ import com.bitmovin.player.api.decoder.DecoderConfig
5
+ import com.bitmovin.player.api.decoder.DecoderPriorityProvider
6
+ import com.bitmovin.player.api.decoder.MediaCodecInfo
7
+ import com.bitmovin.player.reactnative.converter.toJson
8
+ import com.bitmovin.player.reactnative.converter.toMediaCodecInfoList
9
+ import com.facebook.react.bridge.*
10
+ import com.facebook.react.module.annotations.ReactModule
11
+ import java.util.concurrent.ConcurrentHashMap
12
+
13
+ private const val MODULE_NAME = "DecoderConfigModule"
14
+
15
+ @ReactModule(name = MODULE_NAME)
16
+ class DecoderConfigModule(context: ReactApplicationContext) : BitmovinBaseModule(context) {
17
+ override fun getName() = MODULE_NAME
18
+
19
+ /**
20
+ * In-memory mapping from `nativeId`s to `DecoderConfig` instances.
21
+ */
22
+ private val decoderConfigs: Registry<DecoderConfig> = mutableMapOf()
23
+ private val overrideDecoderPriorityProviderCompleters =
24
+ ConcurrentHashMap<NativeId, CallbackToFutureAdapter.Completer<List<MediaCodecInfo>>>()
25
+
26
+ fun getConfig(nativeId: NativeId?): DecoderConfig? = nativeId?.let { decoderConfigs[it] }
27
+
28
+ @ReactMethod
29
+ fun initWithConfig(nativeId: NativeId, config: ReadableMap, promise: Promise) {
30
+ if (decoderConfigs.containsKey(nativeId)) {
31
+ return
32
+ }
33
+ if (config.getMap("playbackConfig")?.hasKey("decoderConfig") == false) {
34
+ return
35
+ }
36
+
37
+ val decoderConfig = DecoderConfig(
38
+ decoderPriorityProvider = object : DecoderPriorityProvider {
39
+ override fun overrideDecodersPriority(
40
+ context: DecoderPriorityProvider.DecoderContext,
41
+ preferredDecoders: List<MediaCodecInfo>,
42
+ ): List<MediaCodecInfo> {
43
+ return overrideDecoderPriorityProvider(nativeId, context, preferredDecoders)
44
+ }
45
+ },
46
+ )
47
+ decoderConfigs[nativeId] = decoderConfig
48
+ }
49
+
50
+ @ReactMethod
51
+ fun destroy(nativeId: NativeId) {
52
+ decoderConfigs.remove(nativeId)
53
+ overrideDecoderPriorityProviderCompleters.keys.filter { it.startsWith(nativeId) }.forEach {
54
+ overrideDecoderPriorityProviderCompleters.remove(it)
55
+ }
56
+ }
57
+
58
+ private fun overrideDecoderPriorityProvider(
59
+ nativeId: NativeId,
60
+ context: DecoderPriorityProvider.DecoderContext,
61
+ preferredDecoders: List<MediaCodecInfo>,
62
+ ): List<MediaCodecInfo> {
63
+ return CallbackToFutureAdapter.getFuture { completer ->
64
+ overrideDecoderPriorityProviderCompleters[nativeId] = completer
65
+ val args = Arguments.createArray()
66
+ args.pushMap(context.toJson())
67
+ args.pushArray(preferredDecoders.toJson())
68
+ this@DecoderConfigModule.context.catalystInstance.callFunction(
69
+ "DecoderConfigBridge-$nativeId",
70
+ "overrideDecodersPriority",
71
+ args as NativeArray,
72
+ )
73
+ }.get()
74
+ }
75
+
76
+ @ReactMethod
77
+ fun overrideDecoderPriorityProviderComplete(nativeId: NativeId, response: ReadableArray) {
78
+ overrideDecoderPriorityProviderCompleters[nativeId]?.set(response.toMediaCodecInfoList())
79
+ overrideDecoderPriorityProviderCompleters.remove(nativeId)
80
+ }
81
+ }
@@ -43,8 +43,21 @@ class PlayerModule(context: ReactApplicationContext) : BitmovinBaseModule(contex
43
43
  * @param config `PlayerConfig` object received from JS.
44
44
  */
45
45
  @ReactMethod
46
- fun initWithConfig(nativeId: NativeId, config: ReadableMap?, networkNativeId: NativeId?, promise: Promise) {
47
- init(nativeId, config, networkNativeId = networkNativeId, analyticsConfigJson = null, promise)
46
+ fun initWithConfig(
47
+ nativeId: NativeId,
48
+ config: ReadableMap?,
49
+ networkNativeId: NativeId?,
50
+ decoderNativeId: NativeId?,
51
+ promise: Promise,
52
+ ) {
53
+ init(
54
+ nativeId,
55
+ config,
56
+ networkNativeId = networkNativeId,
57
+ decoderNativeId = decoderNativeId,
58
+ analyticsConfigJson = null,
59
+ promise,
60
+ )
48
61
  }
49
62
 
50
63
  /**
@@ -57,14 +70,23 @@ class PlayerModule(context: ReactApplicationContext) : BitmovinBaseModule(contex
57
70
  nativeId: NativeId,
58
71
  playerConfigJson: ReadableMap?,
59
72
  networkNativeId: NativeId?,
73
+ decoderNativeId: NativeId?,
60
74
  analyticsConfigJson: ReadableMap,
61
75
  promise: Promise,
62
- ) = init(nativeId, playerConfigJson, networkNativeId, analyticsConfigJson, promise)
76
+ ) = init(
77
+ nativeId,
78
+ playerConfigJson,
79
+ networkNativeId,
80
+ decoderNativeId,
81
+ analyticsConfigJson,
82
+ promise,
83
+ )
63
84
 
64
85
  private fun init(
65
86
  nativeId: NativeId,
66
87
  playerConfigJson: ReadableMap?,
67
88
  networkNativeId: NativeId?,
89
+ decoderNativeId: NativeId?,
68
90
  analyticsConfigJson: ReadableMap?,
69
91
  promise: Promise,
70
92
  ) = promise.unit.resolveOnUiThread {
@@ -85,6 +107,11 @@ class PlayerModule(context: ReactApplicationContext) : BitmovinBaseModule(contex
85
107
  playerConfig.networkConfig = networkConfig
86
108
  }
87
109
 
110
+ val decoderConfig = decoderNativeId?.let { decoderConfigModule.getConfig(it) }
111
+ if (decoderConfig != null) {
112
+ playerConfig.playbackConfig = playerConfig.playbackConfig.copy(decoderConfig = decoderConfig)
113
+ }
114
+
88
115
  players[nativeId] = if (analyticsConfig == null) {
89
116
  Player.create(context, playerConfig)
90
117
  } else {
@@ -31,6 +31,7 @@ class RNPlayerViewPackage : ReactPackage {
31
31
  BufferModule(reactContext),
32
32
  NetworkModule(reactContext),
33
33
  DebugModule(reactContext),
34
+ DecoderConfigModule(reactContext),
34
35
  )
35
36
  }
36
37
 
@@ -25,6 +25,8 @@ import com.bitmovin.player.api.buffer.BufferLevel
25
25
  import com.bitmovin.player.api.buffer.BufferMediaTypeConfig
26
26
  import com.bitmovin.player.api.buffer.BufferType
27
27
  import com.bitmovin.player.api.casting.RemoteControlConfig
28
+ import com.bitmovin.player.api.decoder.DecoderPriorityProvider.DecoderContext
29
+ import com.bitmovin.player.api.decoder.MediaCodecInfo
28
30
  import com.bitmovin.player.api.drm.WidevineConfig
29
31
  import com.bitmovin.player.api.event.PlayerEvent
30
32
  import com.bitmovin.player.api.event.SourceEvent
@@ -206,7 +208,6 @@ fun ReadableMap.toTweaksConfig(): TweaksConfig = TweaksConfig().apply {
206
208
  withBoolean("useDrmSessionForClearPeriods") { useDrmSessionForClearPeriods = it }
207
209
  withBoolean("useDrmSessionForClearSources") { useDrmSessionForClearSources = it }
208
210
  withBoolean("useFiletypeExtractorFallbackForHls") { useFiletypeExtractorFallbackForHls = it }
209
- withBoolean("preferSoftwareDecodingForAds") { preferSoftwareDecodingForAds = it }
210
211
  withStringArray("forceReuseVideoCodecReasons") {
211
212
  forceReuseVideoCodecReasons = it
212
213
  .filterNotNull()
@@ -949,3 +950,37 @@ private fun CastPayload.toJson(): WritableMap = Arguments.createMap().apply {
949
950
  }
950
951
 
951
952
  private fun WritableMap.putStringIfNotNull(name: String, value: String?) = value?.let { putString(name, value) }
953
+
954
+ fun DecoderContext.toJson(): ReadableMap = Arguments.createMap().apply {
955
+ putString("mediaType", mediaType.name)
956
+ putBoolean("isAd", isAd)
957
+ }
958
+
959
+ fun List<MediaCodecInfo>.toJson(): ReadableArray = Arguments.createArray().apply {
960
+ forEach {
961
+ pushMap(it.toJson())
962
+ }
963
+ }
964
+
965
+ fun MediaCodecInfo.toJson(): ReadableMap = Arguments.createMap().apply {
966
+ putString("name", name)
967
+ putBoolean("isSoftware", isSoftware)
968
+ }
969
+
970
+ fun ReadableArray.toMediaCodecInfoList(): List<MediaCodecInfo> {
971
+ if (size() <= 0) {
972
+ return emptyList()
973
+ }
974
+ val mediaCodecInfoList = mutableListOf<MediaCodecInfo>()
975
+ (0 until size()).forEach {
976
+ val info = getMap(it).toMediaCodecInfo() ?: return@forEach
977
+ mediaCodecInfoList.add(info)
978
+ }
979
+ return mediaCodecInfoList
980
+ }
981
+
982
+ fun ReadableMap.toMediaCodecInfo(): MediaCodecInfo? {
983
+ val name = getString("name") ?: return null
984
+ val isSoftware = getBooleanOrNull("isSoftware") ?: return null
985
+ return MediaCodecInfo(name, isSoftware)
986
+ }
@@ -1,5 +1,6 @@
1
1
  package com.bitmovin.player.reactnative.extensions
2
2
 
3
+ import com.bitmovin.player.reactnative.DecoderConfigModule
3
4
  import com.bitmovin.player.reactnative.DrmModule
4
5
  import com.bitmovin.player.reactnative.NetworkModule
5
6
  import com.bitmovin.player.reactnative.OfflineModule
@@ -20,3 +21,4 @@ val ReactApplicationContext.uiManagerModule get() = getModule<UIManagerModule>()
20
21
  val ReactApplicationContext.drmModule get() = getModule<DrmModule>()
21
22
  val ReactApplicationContext.customMessageHandlerModule get() = getModule<CustomMessageHandlerModule>()
22
23
  val ReactApplicationContext.networkModule get() = getModule<NetworkModule>()
24
+ val ReactApplicationContext.decoderConfigModule get() = getModule<DecoderConfigModule>()
@@ -150,12 +150,12 @@ class OfflineContentManagerBridge(
150
150
  /**
151
151
  * Called when a process call has completed.
152
152
  */
153
- override fun onCompleted(source: SourceConfig?, options: OfflineContentOptions?) {
153
+ override fun onCompleted(source: SourceConfig, options: OfflineContentOptions) {
154
154
  this.contentOptions = options
155
155
  sendEvent(
156
156
  OfflineEventType.ON_COMPLETED,
157
157
  Arguments.createMap().apply {
158
- putMap("options", options?.toJson())
158
+ putMap("options", options.toJson())
159
159
  },
160
160
  )
161
161
  }
@@ -163,12 +163,12 @@ class OfflineContentManagerBridge(
163
163
  /**
164
164
  * Called when an error occurs.
165
165
  */
166
- override fun onError(source: SourceConfig?, event: ErrorEvent?) {
166
+ override fun onError(source: SourceConfig, event: ErrorEvent) {
167
167
  sendEvent(
168
168
  OfflineEventType.ON_ERROR,
169
169
  Arguments.createMap().apply {
170
- event?.code?.value?.let { putInt("code", it) }
171
- putString("message", event?.message)
170
+ putInt("code", event.code.value)
171
+ putString("message", event.message)
172
172
  },
173
173
  )
174
174
  }
@@ -176,7 +176,7 @@ class OfflineContentManagerBridge(
176
176
  /**
177
177
  * Called when the progress for a process call changes.
178
178
  */
179
- override fun onProgress(source: SourceConfig?, progress: Float) {
179
+ override fun onProgress(source: SourceConfig, progress: Float) {
180
180
  sendEvent(
181
181
  OfflineEventType.ON_PROGRESS,
182
182
  Arguments.createMap().apply {
@@ -188,12 +188,12 @@ class OfflineContentManagerBridge(
188
188
  /**
189
189
  * Called after a getOptions or when am OfflineOptionEntry has been updated during a process call.
190
190
  */
191
- override fun onOptionsAvailable(source: SourceConfig?, options: OfflineContentOptions?) {
191
+ override fun onOptionsAvailable(source: SourceConfig, options: OfflineContentOptions) {
192
192
  this.contentOptions = options
193
193
  sendEvent(
194
194
  OfflineEventType.ON_OPTIONS_AVAILABLE,
195
195
  Arguments.createMap().apply {
196
- putMap("options", options?.toJson())
196
+ putMap("options", options.toJson())
197
197
  },
198
198
  )
199
199
  }
@@ -201,21 +201,21 @@ class OfflineContentManagerBridge(
201
201
  /**
202
202
  * Called when the DRM license was updated.
203
203
  */
204
- override fun onDrmLicenseUpdated(source: SourceConfig?) {
204
+ override fun onDrmLicenseUpdated(source: SourceConfig) {
205
205
  sendEvent(OfflineEventType.ON_DRM_LICENSE_UPDATED)
206
206
  }
207
207
 
208
208
  /**
209
209
  * Called when all actions have been suspended.
210
210
  */
211
- override fun onSuspended(source: SourceConfig?) {
211
+ override fun onSuspended(source: SourceConfig) {
212
212
  sendEvent(OfflineEventType.ON_SUSPENDED)
213
213
  }
214
214
 
215
215
  /**
216
216
  * Called when all actions have been resumed.
217
217
  */
218
- override fun onResumed(source: SourceConfig?) {
218
+ override fun onResumed(source: SourceConfig) {
219
219
  sendEvent(OfflineEventType.ON_RESUMED)
220
220
  }
221
221
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  @interface RCT_EXTERN_REMAP_MODULE(PlayerModule, PlayerModule, NSObject)
4
4
 
5
- RCT_EXTERN_METHOD(initWithConfig:(NSString *)nativeId config:(nullable id)config networkNativeId:(nullable NSString *)networkNativeId)
6
- RCT_EXTERN_METHOD(initWithAnalyticsConfig:(NSString *)nativeId config:(nullable id)config networkNativeId:(nullable NSString *)networkNativeId analyticsConfig:(nullable id)analyticsConfig)
5
+ RCT_EXTERN_METHOD(initWithConfig:(NSString *)nativeId config:(nullable id)config networkNativeId:(nullable NSString *)networkNativeId decoderNativeId:(nullable NSString *)decoderNativeId)
6
+ RCT_EXTERN_METHOD(initWithAnalyticsConfig:(NSString *)nativeId config:(nullable id)config networkNativeId:(nullable NSString *)networkNativeId analyticsConfig:(nullable id)analyticsConfig decoderNativeId:(nullable NSString *)decoderNativeId)
7
7
  RCT_EXTERN_METHOD(loadSource:(NSString *)nativeId sourceNativeId:(NSString *)sourceNativeId)
8
8
  RCT_EXTERN_METHOD(loadOfflineContent:(NSString *)nativeId offlineContentManagerBridgeId:(NSString *)offlineContentManagerBridgeId options:(nullable id)options)
9
9
  RCT_EXTERN_METHOD(unload:(NSString *)nativeId)
@@ -46,11 +46,12 @@ public class PlayerModule: NSObject, RCTBridgeModule { // swiftlint:disable:this
46
46
  Creates a new `Player` instance inside the internal players using the provided `config` object.
47
47
  - Parameter config: `PlayerConfig` object received from JS.
48
48
  */
49
- @objc(initWithConfig:config:networkNativeId:)
49
+ @objc(initWithConfig:config:networkNativeId:decoderNativeId:)
50
50
  func initWithConfig(
51
51
  _ nativeId: NativeId,
52
52
  config: Any?,
53
- networkNativeId: NativeId?
53
+ networkNativeId: NativeId?,
54
+ decoderNativeId: NativeId?
54
55
  ) {
55
56
  bridge.uiManager.addUIBlock { [weak self] _, _ in
56
57
  guard
@@ -76,12 +77,13 @@ public class PlayerModule: NSObject, RCTBridgeModule { // swiftlint:disable:this
76
77
  - Parameter config: `PlayerConfig` object received from JS.
77
78
  - Parameter analyticsConfig: `AnalyticsConfig` object received from JS.
78
79
  */
79
- @objc(initWithAnalyticsConfig:config:networkNativeId:analyticsConfig:)
80
+ @objc(initWithAnalyticsConfig:config:networkNativeId:analyticsConfig:decoderNativeId:)
80
81
  func initWithAnalyticsConfig(
81
82
  _ nativeId: NativeId,
82
83
  config: Any?,
83
84
  networkNativeId: NativeId?,
84
- analyticsConfig: Any?
85
+ analyticsConfig: Any?,
86
+ decoderNativeId: NativeId?
85
87
  ) {
86
88
  bridge.uiManager.addUIBlock { [weak self] _, _ in
87
89
  let analyticsConfigJson = analyticsConfig
package/lib/index.d.mts CHANGED
@@ -2961,13 +2961,6 @@ interface TweaksConfig {
2961
2961
  * @platform Android
2962
2962
  */
2963
2963
  useFiletypeExtractorFallbackForHls?: boolean;
2964
- /**
2965
- * Specifies whether the player should prefer software decoding over hardware decoding for ad playback.
2966
- * This only affects ads playback, the player will still prefer hardware decoding for the main content.
2967
- *
2968
- * @platform Android
2969
- */
2970
- preferSoftwareDecodingForAds?: boolean;
2971
2964
  /**
2972
2965
  * Determines whether `AVKit` should update Now Playing information automatically when using System UI.
2973
2966
  *
@@ -3077,6 +3070,101 @@ interface BufferConfig {
3077
3070
  startupThreshold?: number;
3078
3071
  }
3079
3072
 
3073
+ /**
3074
+ * Configures the playback behaviour of the player.
3075
+ *
3076
+ * @platform Android
3077
+ */
3078
+ interface DecoderConfig extends NativeInstanceConfig {
3079
+ /**
3080
+ * A callback interface for sorting and filtering decoders based on priority.
3081
+ *
3082
+ * This callback is invoked when the player selects a decoder, providing the {@link DecoderContext}
3083
+ * and a list of available {@link MediaCodecInfo} objects. The list is initially ordered by
3084
+ * the default priority in which decoders will be attempted.
3085
+ *
3086
+ * The callback should return a reordered or filtered list of {@link MediaCodecInfo} objects
3087
+ * that determines the selection priority.
3088
+ *
3089
+ * ## Example Usage
3090
+ *
3091
+ * ### Prefer a specific decoder for main content video playback
3092
+ * The following example prioritizes a specific decoder for non-ad video playback:
3093
+ * ```ts
3094
+ * const decoderPriorityProvider: DecoderPriorityProvider = {
3095
+ * overrideDecodersPriority: (context: DecoderContext, preferredDecoders: MediaCodecInfo[]): MediaCodecInfo[] => {
3096
+ * if (!context.isAd && context.mediaType === DecoderContextMediaType.VIDEO) {
3097
+ * // Prioritize a specific decoder
3098
+ * return preferredDecoders.sort((a, b) => {
3099
+ * const aAsNumber = a.name.startsWith("OMX.google.") ? 1 : 2
3100
+ * const bAsNumber = b.name.startsWith("OMX.google.") ? 1 : 2
3101
+ * return aAsNumber - bAsNumber
3102
+ * })
3103
+ * }
3104
+ * return preferredDecoders
3105
+ * }
3106
+ * }
3107
+ * ```
3108
+ *
3109
+ * ### Prefer software decoders for ads playback
3110
+ * The following example prioritizes software decoders over hardware decoders for ad playback:
3111
+ * ```ts
3112
+ * const decoderPriorityProvider: DecoderPriorityProvider = {
3113
+ * overrideDecodersPriority: (context: DecoderContext, preferredDecoders: MediaCodecInfo[]): MediaCodecInfo[] => {
3114
+ * if (context.isAd) {
3115
+ * // Prioritize a specific decoder
3116
+ * return preferredDecoders.sort((a, b) => {
3117
+ * const aAsNumber = a.isSoftware ? 1 : 2
3118
+ * const bAsNumber = b.isSoftware ? 1 : 2
3119
+ * return aAsNumber - bAsNumber
3120
+ * })
3121
+ * }
3122
+ * return preferredDecoders
3123
+ * }
3124
+ * }
3125
+ * ```
3126
+ *
3127
+ * ### Disable software fallback for video playback
3128
+ * The following example disables software decoders for non-ad video playback:
3129
+ * ```ts
3130
+ * const decoderPriorityProvider: DecoderPriorityProvider = {
3131
+ * overrideDecodersPriority: (context: DecoderContext, preferredDecoders: MediaCodecInfo[]): MediaCodecInfo[] => {
3132
+ * if (!context.isAd && context.mediaType === DecoderContextMediaType.VIDEO) {
3133
+ * // Prioritize a specific decoder
3134
+ * return preferredDecoders.filter((info) => {
3135
+ * return !info.isSoftware
3136
+ * })
3137
+ * }
3138
+ * return preferredDecoders
3139
+ * }
3140
+ * }
3141
+ * ```
3142
+ */
3143
+ decoderPriorityProvider?: DecoderPriorityProvider | null;
3144
+ }
3145
+ /**
3146
+ * Can be set on the `DecoderConfig.decoderPriorityProvider` to override the default decoder selection logic.
3147
+ * See {@link DecoderConfig#decoderPriorityProvider} for more details
3148
+ *
3149
+ * @platform Android
3150
+ * */
3151
+ interface DecoderPriorityProvider {
3152
+ overrideDecodersPriority: (context: DecoderContext, preferredDecoders: MediaCodecInfo[]) => MediaCodecInfo[];
3153
+ }
3154
+ /** The context in which a new decoder is chosen. */
3155
+ interface DecoderContext {
3156
+ mediaType: DecoderContextMediaType;
3157
+ isAd: boolean;
3158
+ }
3159
+ interface MediaCodecInfo {
3160
+ name: String;
3161
+ isSoftware: boolean;
3162
+ }
3163
+ declare enum DecoderContextMediaType {
3164
+ AUDIO = "Audio",
3165
+ VIDEO = "Video"
3166
+ }
3167
+
3080
3168
  /**
3081
3169
  * Configures the playback behaviour of the player.
3082
3170
  */
@@ -3157,6 +3245,12 @@ interface PlaybackConfig {
3157
3245
  * @deprecated Use {@link PictureInPictureConfig.isEnabled} instead.
3158
3246
  */
3159
3247
  isPictureInPictureEnabled?: boolean;
3248
+ /**
3249
+ * Configures decoder behaviour.
3250
+ *
3251
+ * @platform Android
3252
+ */
3253
+ decoderConfig?: DecoderConfig;
3160
3254
  }
3161
3255
 
3162
3256
  /**
@@ -3398,11 +3492,6 @@ declare class BufferApi {
3398
3492
  * @see PlayerView
3399
3493
  */
3400
3494
  declare class Player extends NativeInstance<PlayerConfig> {
3401
- private network?;
3402
- /**
3403
- * Currently active source, or `null` if none is active.
3404
- */
3405
- source?: Source;
3406
3495
  /**
3407
3496
  * Whether the native `Player` object has been created.
3408
3497
  */
@@ -3411,6 +3500,10 @@ declare class Player extends NativeInstance<PlayerConfig> {
3411
3500
  * Whether the native `Player` object has been disposed.
3412
3501
  */
3413
3502
  isDestroyed: boolean;
3503
+ /**
3504
+ * Currently active source, or `null` if none is active.
3505
+ */
3506
+ source?: Source;
3414
3507
  /**
3415
3508
  * The `AnalyticsApi` for interactions regarding the `Player`'s analytics.
3416
3509
  *
@@ -3421,6 +3514,8 @@ declare class Player extends NativeInstance<PlayerConfig> {
3421
3514
  * The {@link BufferApi} for interactions regarding the buffer.
3422
3515
  */
3423
3516
  buffer: BufferApi;
3517
+ private network?;
3518
+ private decoderConfig?;
3424
3519
  /**
3425
3520
  * Allocates the native `Player` instance and its resources natively.
3426
3521
  */
@@ -3682,6 +3777,7 @@ declare class Player extends NativeInstance<PlayerConfig> {
3682
3777
  * @platform iOS, tvOS
3683
3778
  */
3684
3779
  canPlayAtPlaybackSpeed: (playbackSpeed: number) => Promise<boolean | undefined>;
3780
+ private maybeInitDecoderConfig;
3685
3781
  }
3686
3782
 
3687
3783
  /**
@@ -4113,4 +4209,4 @@ declare class DebugConfig {
4113
4209
  static setDebugLoggingEnabled(value: boolean): Promise<void>;
4114
4210
  }
4115
4211
 
4116
- export { Ad, AdBreak, AdBreakFinishedEvent, AdBreakStartedEvent, AdClickedEvent, AdConfig, AdData, AdErrorEvent, AdFinishedEvent, AdItem, AdManifestLoadEvent, AdManifestLoadedEvent, AdQuartile, AdQuartileEvent, AdScheduledEvent, AdSkippedEvent, AdSource, AdSourceType, AdStartedEvent, AdaptationConfig, AdvertisingConfig, AnalyticsApi, AnalyticsConfig, AudioAddedEvent, AudioChangedEvent, AudioRemovedEvent, AudioSession, AudioSessionCategory, AudioTrack, BasePlayerViewProps, BitmovinCastManager, BitmovinCastManagerOptions, BitmovinNativeOfflineEventData, BufferApi, BufferConfig, BufferLevel, BufferLevels, BufferMediaTypeConfig, BufferType, CastAvailableEvent, CastPausedEvent, CastPayload, CastPlaybackFinishedEvent, CastPlayingEvent, CastStartEvent, CastStartedEvent, CastStoppedEvent, CastTimeUpdatedEvent, CastWaitingForDeviceEvent, CueEnterEvent, CueExitEvent, CustomDataConfig, CustomMessageHandler, CustomMessageHandlerProps, CustomUi, DebugConfig, DefaultMetadata, DestroyEvent, DownloadFinishedEvent, Drm, DrmConfig, ErrorEvent, Event, EventSource, FairplayConfig, ForceReuseVideoCodecReason, FullscreenDisabledEvent, FullscreenEnabledEvent, FullscreenEnterEvent, FullscreenExitEvent, FullscreenHandler, HttpRequest, HttpRequestType, HttpResponse, LiveConfig, LoadingState, MediaControlConfig, MediaType, MutedEvent, Network, NetworkConfig, OfflineContentConfig, OfflineContentManager, OfflineContentManagerListener, OfflineContentOptionEntry, OfflineContentOptions, OfflineDownloadRequest, OfflineEvent, OfflineEventType, OfflineSourceOptions, OfflineState, OnCanceledEvent, OnCompletedEvent, OnDrmLicenseExpiredEvent, OnDrmLicenseUpdatedEvent, OnErrorEvent, OnOptionsAvailableEvent, OnProgressEvent, OnResumedEvent, OnSuspendedEvent, PausedEvent, PictureInPictureAvailabilityChangedEvent, PictureInPictureConfig, PictureInPictureEnterEvent, PictureInPictureEnteredEvent, PictureInPictureExitEvent, PictureInPictureExitedEvent, PlayEvent, PlaybackConfig, PlaybackFinishedEvent, PlaybackSpeedChangedEvent, Player, PlayerActiveEvent, PlayerConfig, PlayerErrorEvent, PlayerView, PlayerViewConfig, PlayerViewProps, PlayerWarningEvent, PlayingEvent, ReadyEvent, RemoteControlConfig, ScalingMode, SeekEvent, SeekPosition, SeekedEvent, SideLoadedSubtitleTrack, SmallScreenUi, Source, SourceConfig, SourceErrorEvent, SourceLoadEvent, SourceLoadedEvent, SourceMetadata, SourceOptions, SourceRemoteControlConfig, SourceType, SourceUnloadedEvent, SourceWarningEvent, StallEndedEvent, StallStartedEvent, StyleConfig, SubtitleAddedEvent, SubtitleChangedEvent, SubtitleFormat, SubtitleRemovedEvent, SubtitleTrack, SurfaceType, Thumbnail, TimeChangedEvent, TimeShiftEvent, TimeShiftedEvent, TimelineReferencePoint, TvUi, TweaksConfig, UiConfig, UnmutedEvent, UserInterfaceType, Variant, VideoDownloadQualityChangedEvent, VideoPlaybackQualityChangedEvent, VideoQuality, WebUiConfig, WidevineConfig, usePlayer };
4212
+ export { Ad, AdBreak, AdBreakFinishedEvent, AdBreakStartedEvent, AdClickedEvent, AdConfig, AdData, AdErrorEvent, AdFinishedEvent, AdItem, AdManifestLoadEvent, AdManifestLoadedEvent, AdQuartile, AdQuartileEvent, AdScheduledEvent, AdSkippedEvent, AdSource, AdSourceType, AdStartedEvent, AdaptationConfig, AdvertisingConfig, AnalyticsApi, AnalyticsConfig, AudioAddedEvent, AudioChangedEvent, AudioRemovedEvent, AudioSession, AudioSessionCategory, AudioTrack, BasePlayerViewProps, BitmovinCastManager, BitmovinCastManagerOptions, BitmovinNativeOfflineEventData, BufferApi, BufferConfig, BufferLevel, BufferLevels, BufferMediaTypeConfig, BufferType, CastAvailableEvent, CastPausedEvent, CastPayload, CastPlaybackFinishedEvent, CastPlayingEvent, CastStartEvent, CastStartedEvent, CastStoppedEvent, CastTimeUpdatedEvent, CastWaitingForDeviceEvent, CueEnterEvent, CueExitEvent, CustomDataConfig, CustomMessageHandler, CustomMessageHandlerProps, CustomUi, DebugConfig, DecoderConfig, DecoderContext, DecoderContextMediaType, DecoderPriorityProvider, DefaultMetadata, DestroyEvent, DownloadFinishedEvent, Drm, DrmConfig, ErrorEvent, Event, EventSource, FairplayConfig, ForceReuseVideoCodecReason, FullscreenDisabledEvent, FullscreenEnabledEvent, FullscreenEnterEvent, FullscreenExitEvent, FullscreenHandler, HttpRequest, HttpRequestType, HttpResponse, LiveConfig, LoadingState, MediaCodecInfo, MediaControlConfig, MediaType, MutedEvent, Network, NetworkConfig, OfflineContentConfig, OfflineContentManager, OfflineContentManagerListener, OfflineContentOptionEntry, OfflineContentOptions, OfflineDownloadRequest, OfflineEvent, OfflineEventType, OfflineSourceOptions, OfflineState, OnCanceledEvent, OnCompletedEvent, OnDrmLicenseExpiredEvent, OnDrmLicenseUpdatedEvent, OnErrorEvent, OnOptionsAvailableEvent, OnProgressEvent, OnResumedEvent, OnSuspendedEvent, PausedEvent, PictureInPictureAvailabilityChangedEvent, PictureInPictureConfig, PictureInPictureEnterEvent, PictureInPictureEnteredEvent, PictureInPictureExitEvent, PictureInPictureExitedEvent, PlayEvent, PlaybackConfig, PlaybackFinishedEvent, PlaybackSpeedChangedEvent, Player, PlayerActiveEvent, PlayerConfig, PlayerErrorEvent, PlayerView, PlayerViewConfig, PlayerViewProps, PlayerWarningEvent, PlayingEvent, ReadyEvent, RemoteControlConfig, ScalingMode, SeekEvent, SeekPosition, SeekedEvent, SideLoadedSubtitleTrack, SmallScreenUi, Source, SourceConfig, SourceErrorEvent, SourceLoadEvent, SourceLoadedEvent, SourceMetadata, SourceOptions, SourceRemoteControlConfig, SourceType, SourceUnloadedEvent, SourceWarningEvent, StallEndedEvent, StallStartedEvent, StyleConfig, SubtitleAddedEvent, SubtitleChangedEvent, SubtitleFormat, SubtitleRemovedEvent, SubtitleTrack, SurfaceType, Thumbnail, TimeChangedEvent, TimeShiftEvent, TimeShiftedEvent, TimelineReferencePoint, TvUi, TweaksConfig, UiConfig, UnmutedEvent, UserInterfaceType, Variant, VideoDownloadQualityChangedEvent, VideoPlaybackQualityChangedEvent, VideoQuality, WebUiConfig, WidevineConfig, usePlayer };