bitmovin-player-react-native 0.14.2 → 0.15.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.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/RNBitmovinPlayer.podspec +1 -1
  3. package/android/build.gradle +69 -27
  4. package/android/gradle.properties +7 -0
  5. package/android/src/main/AndroidManifestNew.xml +2 -0
  6. package/android/src/main/java/com/bitmovin/player/reactnative/BitmovinBaseModule.kt +106 -0
  7. package/android/src/main/java/com/bitmovin/player/reactnative/BitmovinCastManagerModule.kt +14 -30
  8. package/android/src/main/java/com/bitmovin/player/reactnative/BufferModule.kt +17 -33
  9. package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +33 -45
  10. package/android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt +64 -106
  11. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerAnalyticsModule.kt +17 -25
  12. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +186 -237
  13. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +5 -5
  14. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +41 -54
  15. package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +51 -93
  16. package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +1 -2
  17. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +658 -1140
  18. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/CustomData.kt +71 -0
  19. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +14 -2
  20. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableArray.kt +13 -28
  21. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableMap.kt +8 -12
  22. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableMapExtension.kt +49 -17
  23. package/android/src/main/java/com/bitmovin/player/reactnative/offline/OfflineContentManagerBridge.kt +13 -14
  24. package/ios/Event+JSON.swift +1 -1
  25. package/lib/index.d.mts +1070 -1065
  26. package/lib/index.d.ts +1070 -1065
  27. package/lib/index.js +2 -2
  28. package/lib/index.mjs +2 -2
  29. package/package.json +26 -15
  30. package/src/components/PlayerView/index.tsx +1 -1
  31. package/src/events.ts +5 -0
  32. package/src/player.ts +3 -1
  33. package/android/.editorconfig +0 -8
  34. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  35. package/android/gradle/wrapper/gradle-wrapper.properties +0 -7
  36. package/android/gradlew +0 -248
  37. package/android/gradlew.bat +0 -92
  38. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Any.kt +0 -27
package/README.md CHANGED
@@ -12,7 +12,7 @@ This is an open-source project created to enable customers to integrate the Bitm
12
12
 
13
13
  ## Platform Support
14
14
 
15
- This library requires at least React Native 0.64+ and React 17+ to work properly. The **officially supported** platforms are:
15
+ This library requires at least React Native 0.65+ and React 17+ to work properly. The **officially supported** platforms are:
16
16
 
17
17
  - **iOS/iPadOS/tvOS:** 14.0+
18
18
  - **Android:** 5.0+
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
19
19
  s.source_files = "ios/**/*.{h,m,mm,swift}"
20
20
 
21
21
  s.dependency "React-Core"
22
- s.dependency "BitmovinPlayer", "3.49.0"
22
+ s.dependency "BitmovinPlayer", "3.51.0"
23
23
  s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.18.4"
24
24
  s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.8.2"
25
25
  end
@@ -1,9 +1,9 @@
1
1
  buildscript {
2
- ext {
3
- kotlinVersion = '1.7.21'
4
- androidToolsVersion = '7.4.2'
5
- ktlintVersion = '11.6.0'
6
- }
2
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["BitmovinPlayerReactNative_kotlinVersion"]
4
+ def ktlint_version = rootProject.ext.has("ktlintVersion") ? rootProject.ext.get("ktlintVersion") : project.properties["BitmovinPlayerReactNative_ktlintVersion"]
5
+ def android_tools_version = rootProject.ext.has("androidToolsVersion") ? rootProject.ext.get("androidToolsVersion") : project.properties["BitmovinPlayerReactNative_androidToolsVersion"]
6
+
7
7
  repositories {
8
8
  google()
9
9
  mavenCentral()
@@ -12,54 +12,96 @@ buildscript {
12
12
  }
13
13
  }
14
14
  dependencies {
15
- classpath "com.android.tools.build:gradle:$androidToolsVersion"
16
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
17
- classpath "org.jlleitschuh.gradle:ktlint-gradle:$ktlintVersion"
15
+ classpath "com.android.tools.build:gradle:$android_tools_version"
16
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
17
+ classpath "org.jlleitschuh.gradle:ktlint-gradle:$ktlint_version"
18
18
  }
19
19
  }
20
20
 
21
+ def isNewArchitectureEnabled() {
22
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
23
+ }
24
+
21
25
  apply plugin: 'com.android.library'
22
26
  apply plugin: 'kotlin-android'
23
27
  apply plugin: 'org.jlleitschuh.gradle.ktlint'
24
28
 
25
- repositories {
26
- mavenLocal()
27
- maven {
28
- // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
29
- url "$rootDir/../node_modules/react-native/android"
30
- }
31
- google()
32
- mavenCentral()
33
- maven { url 'https://artifacts.bitmovin.com/artifactory/public-releases' }
29
+ if (isNewArchitectureEnabled()) {
30
+ apply plugin: "com.facebook.react"
31
+ }
32
+
33
+ def getExtOrDefault(name) {
34
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["BitmovinPlayerReactNative_" + name]
35
+ }
36
+
37
+ def getExtOrIntegerDefault(name) {
38
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["BitmovinPlayerReactNative_" + name]).toInteger()
39
+ }
40
+
41
+ def supportsNamespace() {
42
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
43
+ def major = parsed[0].toInteger()
44
+ def minor = parsed[1].toInteger()
45
+
46
+ // Namespace support was added in 7.3.0
47
+ return (major == 7 && minor >= 3) || major >= 8
34
48
  }
35
49
 
36
50
  android {
37
- compileSdk 33
51
+ if (supportsNamespace()) {
52
+ namespace "com.bitmovin.player.reactnative"
53
+
54
+ sourceSets {
55
+ main {
56
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
57
+ }
58
+ }
59
+ }
60
+
61
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
62
+
38
63
  defaultConfig {
39
- minSdkVersion 21
40
- targetSdkVersion 33
41
- versionCode 1
42
- versionName '1.0'
64
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
65
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
66
+
43
67
  }
68
+
44
69
  buildTypes {
45
70
  release {
46
71
  minifyEnabled false
47
72
  }
48
73
  }
74
+
49
75
  lintOptions {
50
- disable 'GradleCompatible'
76
+ disable "GradleCompatible"
51
77
  }
78
+
52
79
  compileOptions {
53
80
  sourceCompatibility JavaVersion.VERSION_1_8
54
81
  targetCompatibility JavaVersion.VERSION_1_8
55
82
  }
83
+
84
+ buildFeatures {
85
+ buildConfig true
86
+ }
87
+ }
88
+
89
+ repositories {
90
+ google()
91
+ mavenCentral()
56
92
  }
57
93
 
94
+ def kotlin_version = getExtOrDefault("kotlinVersion")
95
+
58
96
  dependencies {
59
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
60
- implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.31.0'
61
- implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
62
- implementation 'com.bitmovin.player:player:3.51.0+jason'
97
+ // For < 0.71, this will be from the local maven repo
98
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
63
99
  //noinspection GradleDynamicVersion
64
100
  implementation 'com.facebook.react:react-native:+' // From node_modules
101
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
102
+
103
+ // Bitmovin
104
+ implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.31.0'
105
+ implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
106
+ implementation 'com.bitmovin.player:player:3.54.0+jason'
65
107
  }
@@ -1 +1,8 @@
1
1
  android.useAndroidX=true
2
+ BitmovinPlayerReactNative_kotlinVersion=1.8.20
3
+ BitmovinPlayerReactNative_minSdkVersion=21
4
+ BitmovinPlayerReactNative_targetSdkVersion=33
5
+ BitmovinPlayerReactNative_compileSdkVersion=33
6
+ BitmovinPlayerReactNative_ndkversion=21.4.7075529
7
+ BitmovinPlayerReactNative_androidToolsVersion=7.4.2
8
+ BitmovinPlayerReactNative_ktlintVersion=11.6.0
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,106 @@
1
+ package com.bitmovin.player.reactnative
2
+
3
+ import android.util.Log
4
+ import com.bitmovin.player.api.Player
5
+ import com.bitmovin.player.api.source.Source
6
+ import com.bitmovin.player.reactnative.extensions.drmModule
7
+ import com.bitmovin.player.reactnative.extensions.offlineModule
8
+ import com.bitmovin.player.reactnative.extensions.playerModule
9
+ import com.bitmovin.player.reactnative.extensions.sourceModule
10
+ import com.bitmovin.player.reactnative.extensions.uiManagerModule
11
+ import com.facebook.react.bridge.*
12
+ import com.facebook.react.uimanager.UIManagerModule
13
+
14
+ private const val MODULE_NAME = "BitmovinBaseModule"
15
+
16
+ /**
17
+ * Base for Bitmovin React modules.
18
+ *
19
+ * Provides many helper methods that are promise exception safe.
20
+ *
21
+ * In general, code should not throw while resolving a [Promise]. Instead, [Promise.reject] should be used.
22
+ * This doesn't match Kotlin's error style, which uses exception. The helper methods in this class, provide such
23
+ * convenience, they can only be called in a context that will catch any Exception and reject the [Promise].
24
+ *
25
+ */
26
+ abstract class BitmovinBaseModule(
27
+ protected val context: ReactApplicationContext,
28
+ ) : ReactContextBaseJavaModule(context) {
29
+ /**
30
+ * Runs [block] on the UI thread with [UIManagerModule.addUIBlock] and [TPromise.resolve] [this] with
31
+ * its return value. If [block] throws, [Promise.reject] [this] with the [Throwable].
32
+ */
33
+ protected inline fun <T, R : T> TPromise<T>.resolveOnUiThread(
34
+ crossinline block: RejectPromiseOnExceptionBlock.() -> R,
35
+ ) {
36
+ val uiManager = runAndRejectOnException { uiManager } ?: return
37
+ uiManager.addUIBlock {
38
+ resolveOnCurrentThread { block() }
39
+ }
40
+ }
41
+
42
+ protected val RejectPromiseOnExceptionBlock.playerModule: PlayerModule get() = context.playerModule
43
+ ?: throw IllegalArgumentException("PlayerModule not found")
44
+
45
+ protected val RejectPromiseOnExceptionBlock.uiManager: UIManagerModule get() = context.uiManagerModule
46
+ ?: throw IllegalStateException("UIManager not found")
47
+
48
+ protected val RejectPromiseOnExceptionBlock.sourceModule: SourceModule get() = context.sourceModule
49
+ ?: throw IllegalStateException("SourceModule not found")
50
+
51
+ protected val RejectPromiseOnExceptionBlock.offlineModule: OfflineModule get() = context.offlineModule
52
+ ?: throw IllegalStateException("OfflineModule not found")
53
+
54
+ protected val RejectPromiseOnExceptionBlock.drmModule: DrmModule get() = context.drmModule
55
+ ?: throw IllegalStateException("DrmModule not found")
56
+
57
+ fun RejectPromiseOnExceptionBlock.getPlayer(
58
+ nativeId: NativeId,
59
+ playerModule: PlayerModule = this.playerModule,
60
+ ): Player = playerModule.getPlayerOrNull(nativeId) ?: throw IllegalArgumentException("Invalid PlayerId $nativeId")
61
+
62
+ fun RejectPromiseOnExceptionBlock.getSource(
63
+ nativeId: NativeId,
64
+ sourceModule: SourceModule = this.sourceModule,
65
+ ): Source = sourceModule.getSourceOrNull(nativeId) ?: throw IllegalArgumentException("Invalid SourceId $nativeId")
66
+ }
67
+
68
+ /** Run [block], returning it's return value. If [block] throws, [Promise.reject] [this] and return null. */
69
+ inline fun <T, R> TPromise<T>.runAndRejectOnException(block: RejectPromiseOnExceptionBlock.() -> R): R? = try {
70
+ RejectPromiseOnExceptionBlock.block()
71
+ } catch (e: Exception) {
72
+ reject(e)
73
+ null
74
+ }
75
+
76
+ /**
77
+ * [TPromise.resolve] [this] with [block] return value.
78
+ * If [block] throws, [Promise.reject] [this] with the [Throwable].
79
+ */
80
+ inline fun <T> TPromise<T>.resolveOnCurrentThread(
81
+ crossinline block: RejectPromiseOnExceptionBlock.() -> T,
82
+ ): Unit = runAndRejectOnException { this@resolveOnCurrentThread.resolve(block()) } ?: Unit
83
+
84
+ /** Receiver of code that can safely throw when resolving a [Promise]. */
85
+ object RejectPromiseOnExceptionBlock
86
+
87
+ /** Compile time wrapper for Promises to type check the resolved type [T]. */
88
+ @JvmInline
89
+ value class TPromise<T>(val promise: Promise) {
90
+ // Promise only support built-in types. Functions that return [Unit] must resolve to `null`.
91
+ fun resolve(value: T): Unit = promise.resolve(value.takeUnless { it is Unit })
92
+ fun reject(throwable: Throwable) {
93
+ Log.e(MODULE_NAME, "Failed to execute Bitmovin method", throwable)
94
+ promise.reject(throwable)
95
+ }
96
+ }
97
+
98
+ inline val Promise.int get() = TPromise<Int>(this)
99
+ inline val Promise.unit get() = TPromise<Unit>(this)
100
+ inline val Promise.string get() = TPromise<String>(this)
101
+ inline val Promise.double get() = TPromise<Double>(this)
102
+ inline val Promise.float get() = TPromise<Float>(this)
103
+ inline val Promise.bool get() = TPromise<Boolean>(this)
104
+ inline val Promise.map get() = TPromise<ReadableMap>(this)
105
+ inline val Promise.array get() = TPromise<ReadableArray>(this)
106
+ inline val <T> TPromise<T>.nullable get() = TPromise<T?>(promise)
@@ -1,70 +1,54 @@
1
1
  package com.bitmovin.player.reactnative
2
2
 
3
3
  import com.bitmovin.player.casting.BitmovinCastManager
4
- import com.bitmovin.player.reactnative.converter.JsonConverter
4
+ import com.bitmovin.player.reactnative.converter.toCastOptions
5
5
  import com.facebook.react.bridge.Promise
6
6
  import com.facebook.react.bridge.ReactApplicationContext
7
- import com.facebook.react.bridge.ReactContextBaseJavaModule
8
7
  import com.facebook.react.bridge.ReactMethod
9
8
  import com.facebook.react.bridge.ReadableMap
10
9
  import com.facebook.react.module.annotations.ReactModule
11
- import com.facebook.react.uimanager.UIManagerModule
12
10
 
13
11
  private const val MODULE_NAME = "BitmovinCastManagerModule"
14
12
 
15
13
  @ReactModule(name = MODULE_NAME)
16
- class BitmovinCastManagerModule(
17
- private val context: ReactApplicationContext,
18
- ) : ReactContextBaseJavaModule(context) {
14
+ class BitmovinCastManagerModule(context: ReactApplicationContext) : BitmovinBaseModule(context) {
19
15
  override fun getName() = MODULE_NAME
20
16
 
21
17
  /**
22
18
  * Returns whether the [BitmovinCastManager] is initialized.
23
19
  */
24
20
  @ReactMethod
25
- fun isInitialized(promise: Promise) = uiManager?.addUIBlock {
26
- promise.resolve(BitmovinCastManager.isInitialized())
21
+ fun isInitialized(promise: Promise) = promise.unit.resolveOnUiThread {
22
+ BitmovinCastManager.isInitialized()
27
23
  }
28
24
 
29
25
  /**
30
26
  * Initializes the [BitmovinCastManager] with the given options.
31
27
  */
32
28
  @ReactMethod
33
- fun initializeCastManager(options: ReadableMap?, promise: Promise) {
34
- val castOptions = JsonConverter.toCastOptions(options)
35
- uiManager?.addUIBlock {
36
- BitmovinCastManager.initialize(
37
- castOptions?.applicationId,
38
- castOptions?.messageNamespace,
39
- )
40
- promise.resolve(null)
41
- }
29
+ fun initializeCastManager(options: ReadableMap?, promise: Promise) = promise.unit.resolveOnUiThread {
30
+ val castOptions = options?.toCastOptions()
31
+ BitmovinCastManager.initialize(
32
+ castOptions?.applicationId,
33
+ castOptions?.messageNamespace,
34
+ )
42
35
  }
43
36
 
44
37
  /**
45
38
  * Sends a message to the receiver.
46
39
  */
47
40
  @ReactMethod
48
- fun sendMessage(message: String, messageNamespace: String?, promise: Promise) {
49
- uiManager?.addUIBlock {
50
- BitmovinCastManager.getInstance().sendMessage(message, messageNamespace)
51
- promise.resolve(null)
52
- }
41
+ fun sendMessage(message: String, messageNamespace: String?, promise: Promise) = promise.unit.resolveOnUiThread {
42
+ BitmovinCastManager.getInstance().sendMessage(message, messageNamespace)
53
43
  }
54
44
 
55
45
  /**
56
46
  * Updates the context of the [BitmovinCastManager] to the current activity.
57
47
  */
58
48
  @ReactMethod
59
- fun updateContext(promise: Promise) {
60
- uiManager?.addUIBlock {
61
- BitmovinCastManager.getInstance().updateContext(currentActivity)
62
- promise.resolve(null)
63
- }
49
+ fun updateContext(promise: Promise) = promise.unit.resolveOnUiThread {
50
+ BitmovinCastManager.getInstance().updateContext(currentActivity)
64
51
  }
65
-
66
- private val uiManager: UIManagerModule?
67
- get() = context.getNativeModule(UIManagerModule::class.java)
68
52
  }
69
53
 
70
54
  /**
@@ -2,66 +2,50 @@ package com.bitmovin.player.reactnative
2
2
 
3
3
  import com.bitmovin.player.api.buffer.BufferLevel
4
4
  import com.bitmovin.player.api.media.MediaType
5
- import com.bitmovin.player.reactnative.converter.JsonConverter
5
+ import com.bitmovin.player.reactnative.converter.toBufferType
6
+ import com.bitmovin.player.reactnative.converter.toJson
6
7
  import com.facebook.react.bridge.*
7
8
  import com.facebook.react.module.annotations.ReactModule
8
- import com.facebook.react.uimanager.UIManagerModule
9
9
 
10
10
  private const val MODULE_NAME = "BufferModule"
11
+ private const val INVALID_BUFFER_TYPE = "Invalid buffer type"
11
12
 
12
13
  @ReactModule(name = MODULE_NAME)
13
- class BufferModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
14
+ class BufferModule(context: ReactApplicationContext) : BitmovinBaseModule(context) {
14
15
  override fun getName() = MODULE_NAME
15
16
 
16
17
  /**
17
18
  * Gets the [BufferLevel] from the Player
18
19
  * @param nativeId Target player id.
19
- * @param type The [type of buffer][JsonConverter.toBufferType] to return the level for.
20
+ * @param type The [type of buffer][toBufferType] to return the level for.
20
21
  * @param promise JS promise object.
21
22
  */
22
23
  @ReactMethod
23
24
  fun getLevel(nativeId: NativeId, type: String, promise: Promise) {
24
- uiManager()?.addUIBlock { _ ->
25
- val player = playerModule()?.getPlayer(nativeId) ?: return@addUIBlock
26
- val bufferType = JsonConverter.toBufferType(type)
27
- if (bufferType == null) {
28
- promise.reject("Error: ", "Invalid buffer type")
29
- return@addUIBlock
30
- }
31
- val bufferLevels = RNBufferLevels(
32
- player.buffer.getLevel(bufferType, MediaType.Audio),
33
- player.buffer.getLevel(bufferType, MediaType.Video),
34
- )
35
- JsonConverter.fromRNBufferLevels(bufferLevels).let {
36
- promise.resolve(it)
37
- }
25
+ promise.map.resolveOnUiThread {
26
+ val player = getPlayer(nativeId)
27
+ val bufferType = type.toBufferTypeOrThrow()
28
+ RNBufferLevels(
29
+ audio = player.buffer.getLevel(bufferType, MediaType.Audio),
30
+ video = player.buffer.getLevel(bufferType, MediaType.Video),
31
+ ).toJson()
38
32
  }
39
33
  }
40
34
 
41
35
  /**
42
36
  * Sets the target buffer level for the chosen buffer type across all media types.
43
37
  * @param nativeId Target player id.
44
- * @param type The [type of buffer][JsonConverter.toBufferType] to set the target level for.
38
+ * @param type The [type of buffer][toBufferType] to set the target level for.
45
39
  * @param value The value to set.
46
40
  */
47
41
  @ReactMethod
48
- fun setTargetLevel(nativeId: NativeId, type: String, value: Double) {
49
- uiManager()?.addUIBlock { _ ->
50
- val player = playerModule()?.getPlayer(nativeId) ?: return@addUIBlock
51
- val bufferType = JsonConverter.toBufferType(type) ?: return@addUIBlock
52
- player.buffer.setTargetLevel(bufferType, value)
42
+ fun setTargetLevel(nativeId: NativeId, type: String, value: Double, promise: Promise) {
43
+ promise.unit.resolveOnUiThread {
44
+ getPlayer(nativeId).buffer.setTargetLevel(type.toBufferTypeOrThrow(), value)
53
45
  }
54
46
  }
55
47
 
56
- /**
57
- * Helper function that gets the instantiated `UIManagerModule` from modules registry.
58
- */
59
- private fun uiManager(): UIManagerModule? = context.getNativeModule(UIManagerModule::class.java)
60
-
61
- /**
62
- * Helper function that gets the instantiated `PlayerModule` from modules registry.
63
- */
64
- private fun playerModule(): PlayerModule? = context.getNativeModule(PlayerModule::class.java)
48
+ private fun String.toBufferTypeOrThrow() = toBufferType() ?: throw IllegalArgumentException(INVALID_BUFFER_TYPE)
65
49
  }
66
50
 
67
51
  /**
@@ -4,10 +4,10 @@ import android.util.Base64
4
4
  import com.bitmovin.player.api.drm.PrepareLicenseCallback
5
5
  import com.bitmovin.player.api.drm.PrepareMessageCallback
6
6
  import com.bitmovin.player.api.drm.WidevineConfig
7
- import com.bitmovin.player.reactnative.converter.JsonConverter
7
+ import com.bitmovin.player.reactnative.converter.toWidevineConfig
8
8
  import com.facebook.react.bridge.*
9
9
  import com.facebook.react.module.annotations.ReactModule
10
- import com.facebook.react.uimanager.UIManagerModule
10
+ import java.security.InvalidParameterException
11
11
  import java.util.concurrent.locks.Condition
12
12
  import java.util.concurrent.locks.ReentrantLock
13
13
  import kotlin.concurrent.withLock
@@ -20,7 +20,7 @@ typealias PrepareCallback = (ByteArray) -> ByteArray
20
20
  private const val MODULE_NAME = "DrmModule"
21
21
 
22
22
  @ReactModule(name = MODULE_NAME)
23
- class DrmModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
23
+ class DrmModule(context: ReactApplicationContext) : BitmovinBaseModule(context) {
24
24
  /**
25
25
  * In-memory mapping from `nativeId`s to `WidevineConfig` instances.
26
26
  */
@@ -74,15 +74,15 @@ class DrmModule(private val context: ReactApplicationContext) : ReactContextBase
74
74
  * @param config `DrmConfig` object received from JS.
75
75
  */
76
76
  @ReactMethod
77
- fun initWithConfig(nativeId: NativeId, config: ReadableMap?) {
78
- uiManager()?.addUIBlock {
79
- if (!drmConfigs.containsKey(nativeId) && config != null) {
80
- JsonConverter.toWidevineConfig(config)?.let {
81
- drmConfigs[nativeId] = it
82
- initPrepareMessage(nativeId, config)
83
- initPrepareLicense(nativeId, config)
84
- }
77
+ fun initWithConfig(nativeId: NativeId, config: ReadableMap, promise: Promise) {
78
+ promise.unit.resolveOnUiThread {
79
+ if (drmConfigs.containsKey(nativeId)) {
80
+ throw InvalidParameterException("NativeId already exists $nativeId")
85
81
  }
82
+ val widevineConfig = config.toWidevineConfig() ?: throw InvalidParameterException("Invalid widevine config")
83
+ widevineConfig.prepareMessageCallback = buildPrepareMessageCallback(nativeId, config)
84
+ widevineConfig.prepareLicenseCallback = buildPrepareLicense(nativeId, config)
85
+ drmConfigs[nativeId] = widevineConfig
86
86
  }
87
87
  }
88
88
 
@@ -118,24 +118,21 @@ class DrmModule(private val context: ReactApplicationContext) : ReactContextBase
118
118
  }
119
119
 
120
120
  /**
121
- * Initialize the `prepareMessage` block in the `WidevineConfig` associated with `nativeId`.
122
- * @param nativeId Instance ID.
121
+ * Initialize the `prepareMessage` block in the [widevineConfig]
122
+ * @param widevineConfig Instance ID.
123
123
  * @param config `DrmConfig` config object sent from JS.
124
124
  */
125
- private fun initPrepareMessage(nativeId: NativeId, config: ReadableMap) {
126
- val widevineConfig = drmConfigs[nativeId]
127
- val widevineJson = config.getMap("widevine")
128
- if (widevineConfig != null && widevineJson != null && widevineJson.hasKey("prepareMessage")) {
129
- val prepareMessage = createPrepareCallback(
130
- nativeId,
131
- "onPrepareMessage",
132
- preparedMessages,
133
- preparedMessagesCondition,
134
- )
135
- widevineConfig.prepareMessageCallback = PrepareMessageCallback {
136
- prepareMessage(it)
137
- }
125
+ private fun buildPrepareMessageCallback(nativeId: NativeId, config: ReadableMap): PrepareMessageCallback? {
126
+ if (config.getMap("widevine")?.hasKey("prepareMessage") != true) {
127
+ return null
138
128
  }
129
+ val prepareMessageCallback = createPrepareCallback(
130
+ nativeId,
131
+ "onPrepareMessage",
132
+ preparedMessages,
133
+ preparedMessagesCondition,
134
+ )
135
+ return PrepareMessageCallback(prepareMessageCallback)
139
136
  }
140
137
 
141
138
  /**
@@ -143,20 +140,17 @@ class DrmModule(private val context: ReactApplicationContext) : ReactContextBase
143
140
  * @param nativeId Instance ID.
144
141
  * @param config `DrmConfig` config object sent from JS.
145
142
  */
146
- private fun initPrepareLicense(nativeId: NativeId, config: ReadableMap) {
147
- val widevineConfig = drmConfigs[nativeId]
148
- val widevineJson = config.getMap("widevine")
149
- if (widevineConfig != null && widevineJson != null && widevineJson.hasKey("prepareLicense")) {
150
- val prepareLicense = createPrepareCallback(
151
- nativeId,
152
- "onPrepareLicense",
153
- preparedLicenses,
154
- preparedLicensesCondition,
155
- )
156
- widevineConfig.prepareLicenseCallback = PrepareLicenseCallback {
157
- prepareLicense(it)
158
- }
143
+ private fun buildPrepareLicense(nativeId: NativeId, config: ReadableMap): PrepareLicenseCallback? {
144
+ if (config.getMap("widevine")?.hasKey("prepareLicense") != true) {
145
+ return null
159
146
  }
147
+ val prepareLicense = createPrepareCallback(
148
+ nativeId,
149
+ "onPrepareLicense",
150
+ preparedLicenses,
151
+ preparedLicensesCondition,
152
+ )
153
+ return PrepareLicenseCallback(prepareLicense)
160
154
  }
161
155
 
162
156
  /**
@@ -181,10 +175,4 @@ class DrmModule(private val context: ReactApplicationContext) : ReactContextBase
181
175
  Base64.decode(result, Base64.NO_WRAP)
182
176
  }
183
177
  }
184
-
185
- /**
186
- * Helper function that returns the initialized `UIManager` instance.
187
- */
188
- private fun uiManager(): UIManagerModule? =
189
- context.getNativeModule(UIManagerModule::class.java)
190
178
  }