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.
- package/RNBitmovinPlayer.podspec +1 -1
- package/android/build.gradle +3 -3
- package/android/gradle.properties +2 -2
- package/android/src/main/java/com/bitmovin/player/reactnative/BitmovinBaseModule.kt +4 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/DecoderConfigModule.kt +81 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +30 -3
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +1 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +36 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +2 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineContentManagerBridge.kt +11 -11
- package/ios/PlayerModule.m +2 -2
- package/ios/PlayerModule.swift +6 -4
- package/lib/index.d.mts +109 -13
- package/lib/index.d.ts +109 -13
- package/lib/index.js +100 -23
- package/lib/index.mjs +90 -14
- package/package.json +1 -1
- package/src/decoder/decoderConfig.ts +103 -0
- package/src/decoder/index.ts +66 -0
- package/src/index.ts +1 -0
- package/src/playbackConfig.ts +9 -0
- package/src/player.ts +28 -6
- package/src/tweaksConfig.ts +0 -7
package/RNBitmovinPlayer.podspec
CHANGED
|
@@ -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.
|
|
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
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
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.
|
|
109
|
-
implementation 'com.bitmovin.player:player-media-session:3.
|
|
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=
|
|
5
|
-
BitmovinPlayerReactNative_compileSdkVersion=
|
|
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(
|
|
47
|
-
|
|
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(
|
|
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 {
|
|
@@ -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
|
+
}
|
package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt
CHANGED
|
@@ -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>()
|
package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineContentManagerBridge.kt
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
166
|
+
override fun onError(source: SourceConfig, event: ErrorEvent) {
|
|
167
167
|
sendEvent(
|
|
168
168
|
OfflineEventType.ON_ERROR,
|
|
169
169
|
Arguments.createMap().apply {
|
|
170
|
-
|
|
171
|
-
putString("message", event
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/ios/PlayerModule.m
CHANGED
|
@@ -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)
|
package/ios/PlayerModule.swift
CHANGED
|
@@ -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 };
|