bitmovin-player-react-native 0.40.0 → 0.42.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 +45 -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/ios/RCTConvert+BitmovinPlayer.swift +29 -14
- package/lib/index.d.mts +150 -13
- package/lib/index.d.ts +150 -13
- package/lib/index.js +109 -32
- package/lib/index.mjs +99 -23
- package/package.json +1 -1
- package/src/audioTrack.ts +7 -0
- package/src/decoder/decoderConfig.ts +103 -0
- package/src/decoder/index.ts +66 -0
- package/src/index.ts +3 -0
- package/src/mediaControlConfig.ts +2 -0
- package/src/mediaTrackRole.ts +29 -0
- package/src/playbackConfig.ts +9 -0
- package/src/player.ts +28 -6
- package/src/subtitleFormat.ts +26 -0
- package/src/subtitleTrack.ts +7 -26
- 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.90.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.112.0+jason'
|
|
109
|
+
implementation 'com.bitmovin.player:player-media-session:3.112.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
|
|
@@ -32,6 +34,7 @@ import com.bitmovin.player.api.event.data.CastPayload
|
|
|
32
34
|
import com.bitmovin.player.api.event.data.SeekPosition
|
|
33
35
|
import com.bitmovin.player.api.live.LiveConfig
|
|
34
36
|
import com.bitmovin.player.api.media.AdaptationConfig
|
|
37
|
+
import com.bitmovin.player.api.media.MediaTrackRole
|
|
35
38
|
import com.bitmovin.player.api.media.MediaType
|
|
36
39
|
import com.bitmovin.player.api.media.audio.AudioTrack
|
|
37
40
|
import com.bitmovin.player.api.media.subtitle.SubtitleTrack
|
|
@@ -206,7 +209,6 @@ fun ReadableMap.toTweaksConfig(): TweaksConfig = TweaksConfig().apply {
|
|
|
206
209
|
withBoolean("useDrmSessionForClearPeriods") { useDrmSessionForClearPeriods = it }
|
|
207
210
|
withBoolean("useDrmSessionForClearSources") { useDrmSessionForClearSources = it }
|
|
208
211
|
withBoolean("useFiletypeExtractorFallbackForHls") { useFiletypeExtractorFallbackForHls = it }
|
|
209
|
-
withBoolean("preferSoftwareDecodingForAds") { preferSoftwareDecodingForAds = it }
|
|
210
212
|
withStringArray("forceReuseVideoCodecReasons") {
|
|
211
213
|
forceReuseVideoCodecReasons = it
|
|
212
214
|
.filterNotNull()
|
|
@@ -558,6 +560,7 @@ fun AudioTrack.toJson(): WritableMap = Arguments.createMap().apply {
|
|
|
558
560
|
putBoolean("isDefault", isDefault)
|
|
559
561
|
putString("identifier", id)
|
|
560
562
|
putString("language", language)
|
|
563
|
+
putArray("roles", roles.mapToReactArray { it.toJson() })
|
|
561
564
|
}
|
|
562
565
|
|
|
563
566
|
/**
|
|
@@ -595,6 +598,7 @@ fun SubtitleTrack.toJson(): WritableMap = Arguments.createMap().apply {
|
|
|
595
598
|
putString("language", language)
|
|
596
599
|
putBoolean("isForced", isForced)
|
|
597
600
|
putString("format", mimeType?.textMimeTypeToJson())
|
|
601
|
+
putArray("roles", roles.mapToReactArray { it.toJson() })
|
|
598
602
|
}
|
|
599
603
|
|
|
600
604
|
/**
|
|
@@ -949,3 +953,43 @@ private fun CastPayload.toJson(): WritableMap = Arguments.createMap().apply {
|
|
|
949
953
|
}
|
|
950
954
|
|
|
951
955
|
private fun WritableMap.putStringIfNotNull(name: String, value: String?) = value?.let { putString(name, value) }
|
|
956
|
+
|
|
957
|
+
fun DecoderContext.toJson(): ReadableMap = Arguments.createMap().apply {
|
|
958
|
+
putString("mediaType", mediaType.name)
|
|
959
|
+
putBoolean("isAd", isAd)
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
fun List<MediaCodecInfo>.toJson(): ReadableArray = Arguments.createArray().apply {
|
|
963
|
+
forEach {
|
|
964
|
+
pushMap(it.toJson())
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
fun MediaCodecInfo.toJson(): ReadableMap = Arguments.createMap().apply {
|
|
969
|
+
putString("name", name)
|
|
970
|
+
putBoolean("isSoftware", isSoftware)
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
fun ReadableArray.toMediaCodecInfoList(): List<MediaCodecInfo> {
|
|
974
|
+
if (size() <= 0) {
|
|
975
|
+
return emptyList()
|
|
976
|
+
}
|
|
977
|
+
val mediaCodecInfoList = mutableListOf<MediaCodecInfo>()
|
|
978
|
+
(0 until size()).forEach {
|
|
979
|
+
val info = getMap(it).toMediaCodecInfo() ?: return@forEach
|
|
980
|
+
mediaCodecInfoList.add(info)
|
|
981
|
+
}
|
|
982
|
+
return mediaCodecInfoList
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
fun ReadableMap.toMediaCodecInfo(): MediaCodecInfo? {
|
|
986
|
+
val name = getString("name") ?: return null
|
|
987
|
+
val isSoftware = getBooleanOrNull("isSoftware") ?: return null
|
|
988
|
+
return MediaCodecInfo(name, isSoftware)
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
fun MediaTrackRole.toJson(): WritableMap = Arguments.createMap().apply {
|
|
992
|
+
putString("id", id)
|
|
993
|
+
putString("schemeIdUri", schemeIdUri)
|
|
994
|
+
putString("value", value)
|
|
995
|
+
}
|
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
|
|
@@ -561,13 +561,20 @@ extension RCTConvert {
|
|
|
561
561
|
guard let audioTrack else {
|
|
562
562
|
return nil
|
|
563
563
|
}
|
|
564
|
-
|
|
564
|
+
var audioTrackDict: [String: Any?] = [
|
|
565
565
|
"url": audioTrack.url?.absoluteString,
|
|
566
566
|
"label": audioTrack.label,
|
|
567
567
|
"isDefault": audioTrack.isDefaultTrack,
|
|
568
568
|
"identifier": audioTrack.identifier,
|
|
569
569
|
"language": audioTrack.language
|
|
570
570
|
]
|
|
571
|
+
audioTrackDict["roles"] = audioTrack.characteristics.map { characteristic in
|
|
572
|
+
[
|
|
573
|
+
"schemeIdUri": "urn:hls:characteristic",
|
|
574
|
+
"value": characteristic
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
return audioTrackDict
|
|
571
578
|
}
|
|
572
579
|
|
|
573
580
|
/**
|
|
@@ -641,26 +648,34 @@ extension RCTConvert {
|
|
|
641
648
|
guard let subtitleTrack else {
|
|
642
649
|
return nil
|
|
643
650
|
}
|
|
644
|
-
|
|
651
|
+
var subtitleTrackDict: [String: Any?] = [
|
|
645
652
|
"url": subtitleTrack.url?.absoluteString,
|
|
646
653
|
"label": subtitleTrack.label,
|
|
647
654
|
"isDefault": subtitleTrack.isDefaultTrack,
|
|
648
655
|
"identifier": subtitleTrack.identifier,
|
|
649
656
|
"language": subtitleTrack.language,
|
|
650
657
|
"isForced": subtitleTrack.isForced,
|
|
651
|
-
"format": {
|
|
652
|
-
switch subtitleTrack.format {
|
|
653
|
-
case .cea:
|
|
654
|
-
return "cea"
|
|
655
|
-
case .webVtt:
|
|
656
|
-
return "vtt"
|
|
657
|
-
case .ttml:
|
|
658
|
-
return "ttml"
|
|
659
|
-
case .srt:
|
|
660
|
-
return "srt"
|
|
661
|
-
}
|
|
662
|
-
}(),
|
|
663
658
|
]
|
|
659
|
+
switch subtitleTrack.format {
|
|
660
|
+
case .cea:
|
|
661
|
+
subtitleTrackDict["format"] = "cea"
|
|
662
|
+
case .webVtt:
|
|
663
|
+
subtitleTrackDict["format"] = "vtt"
|
|
664
|
+
case .ttml:
|
|
665
|
+
subtitleTrackDict["format"] = "ttml"
|
|
666
|
+
case .srt:
|
|
667
|
+
subtitleTrackDict["format"] = "srt"
|
|
668
|
+
default:
|
|
669
|
+
break
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
subtitleTrackDict["roles"] = subtitleTrack.characteristics.map { characteristic in
|
|
673
|
+
[
|
|
674
|
+
"schemeIdUri": "urn:hls:characteristic",
|
|
675
|
+
"value": characteristic
|
|
676
|
+
]
|
|
677
|
+
}
|
|
678
|
+
return subtitleTrackDict
|
|
664
679
|
}
|
|
665
680
|
|
|
666
681
|
/**
|