bitmovin-player-react-native 0.1.0 → 0.2.1

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 (44) hide show
  1. package/README.md +163 -1
  2. package/RNBitmovinPlayer.podspec +3 -3
  3. package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +191 -0
  4. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +116 -101
  5. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +69 -38
  6. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +10 -26
  7. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
  8. package/android/src/main/java/com/bitmovin/player/reactnative/Registry.kt +11 -0
  9. package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +178 -0
  10. package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +20 -0
  11. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +128 -1
  12. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Events.kt +11 -2
  13. package/ios/DrmModule.m +16 -0
  14. package/ios/DrmModule.swift +442 -0
  15. package/ios/Event+JSON.swift +31 -0
  16. package/ios/PlayerModule.m +21 -25
  17. package/ios/PlayerModule.swift +122 -120
  18. package/ios/RCTConvert+BitmovinPlayer.swift +131 -12
  19. package/ios/RNPlayerView+PlayerListener.swift +12 -0
  20. package/ios/RNPlayerView.swift +5 -3
  21. package/ios/RNPlayerViewManager.m +3 -1
  22. package/ios/RNPlayerViewManager.swift +4 -21
  23. package/ios/Registry.swift +5 -0
  24. package/ios/SourceModule.m +30 -0
  25. package/ios/SourceModule.swift +187 -0
  26. package/ios/UuidModule.m +9 -0
  27. package/ios/UuidModule.swift +23 -0
  28. package/lib/index.d.ts +670 -235
  29. package/lib/index.js +257 -106
  30. package/lib/index.mjs +260 -112
  31. package/package.json +5 -4
  32. package/src/components/PlayerView/events.ts +24 -18
  33. package/src/components/PlayerView/index.tsx +29 -26
  34. package/src/drm/fairplayConfig.ts +90 -0
  35. package/src/drm/index.ts +178 -0
  36. package/src/drm/widevineConfig.ts +37 -0
  37. package/src/events.ts +67 -6
  38. package/src/hooks/useProxy.ts +19 -15
  39. package/src/index.ts +5 -3
  40. package/src/nativeInstance.ts +64 -0
  41. package/src/player.ts +51 -42
  42. package/src/source.ts +88 -8
  43. package/src/subtitleTrack.ts +60 -0
  44. package/src/utils.ts +15 -0
@@ -2,24 +2,19 @@ package com.bitmovin.player.reactnative
2
2
 
3
3
  import com.bitmovin.player.api.Player
4
4
  import com.bitmovin.player.reactnative.converter.JsonConverter
5
- import com.facebook.react.bridge.Promise
6
- import com.facebook.react.bridge.ReadableMap
7
- import com.facebook.react.bridge.ReactMethod
8
- import com.facebook.react.bridge.ReactApplicationContext
9
- import com.facebook.react.bridge.ReactContextBaseJavaModule
10
- import com.facebook.react.module.annotations.ReactModule;
5
+ import com.facebook.react.bridge.*
6
+ import com.facebook.react.module.annotations.ReactModule
11
7
  import com.facebook.react.uimanager.UIManagerModule
12
- import java.util.UUID
13
8
 
14
9
  @ReactModule(name = PlayerModule.name)
15
10
  class PlayerModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
16
11
  /**
17
- * In-memory mapping of `id` <-> `Player`.
12
+ * In-memory mapping from `nativeId`s to `Player` instances.
18
13
  */
19
- private var registry: MutableMap<String, Player> = mutableMapOf()
14
+ private val players: Registry<Player> = mutableMapOf()
20
15
 
21
16
  /**
22
- * Exported module name to JS.
17
+ * JS exported module name.
23
18
  */
24
19
  companion object {
25
20
  const val name = "PlayerModule"
@@ -27,184 +22,180 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
27
22
  override fun getName() = PlayerModule.name
28
23
 
29
24
  /**
30
- * Fetch the `Player` instance with id equal to `playerId` inside this module's `registry`.
31
- * @param playerId Target player to look inside registry.
25
+ * Fetches the `Player` instance associated with `nativeId` from the internal players.
26
+ * @param nativeId `Player` instance ID.
27
+ * @return The associated `Player` instance or `null`.
32
28
  */
33
- fun getPlayer(playerId: String?): Player? {
34
- if (playerId == null) {
29
+ fun getPlayer(nativeId: NativeId?): Player? {
30
+ if (nativeId == null) {
35
31
  return null
36
32
  }
37
- return registry[playerId]
33
+ return players[nativeId]
38
34
  }
39
35
 
40
36
  /**
41
- * Synchronously generate a random UUID for `Player`s native id when no `nativeId` is provided
42
- * by the user.
43
- * @return Random UUID RFC 4122 version 4.
44
- */
45
- @ReactMethod(isBlockingSynchronousMethod = true)
46
- fun generateUUIDv4(): String = UUID.randomUUID().toString()
47
-
48
- /**
49
- * Create a new `Player` instance for the given `config` if no one exists already.
50
- * @param config Player configuration options sent from JS.
37
+ * Creates a new `Player` instance inside the internal players using the provided `config` object.
38
+ * @param config `PlayerConfig` object received from JS.
51
39
  */
52
40
  @ReactMethod
53
- fun initWithConfig(playerId: String, config: ReadableMap?) {
41
+ fun initWithConfig(nativeId: NativeId, config: ReadableMap?) {
54
42
  uiManager()?.addUIBlock {
55
- if (!registry.containsKey(playerId)) {
56
- JsonConverter.toPlayerConfig(config)?.let {
57
- registry[playerId] = Player.create(context, it)
43
+ if (!players.containsKey(nativeId)) {
44
+ JsonConverter.toPlayerConfig(config).let {
45
+ players[nativeId] = Player.create(context, it)
58
46
  }
59
47
  }
60
48
  }
61
49
  }
62
50
 
63
51
  /**
64
- * Load the source of the given `playerId` with `config` options from JS.
65
- * @param playerId Target player.
52
+ * Load the source of the given `nativeId` with `config` options from JS.
53
+ * @param nativeId Target player.
66
54
  * @param config Source configuration options from JS.
67
55
  */
68
56
  @ReactMethod
69
- fun loadSource(playerId: String, config: ReadableMap?) {
57
+ fun loadSource(nativeId: NativeId, sourceNativeId: String) {
70
58
  uiManager()?.addUIBlock {
71
- JsonConverter.toSourceConfig(config)?.let {
72
- registry[playerId]?.load(it)
59
+ sourceModule()?.getSource(sourceNativeId)?.let {
60
+ players[nativeId]?.load(it)
73
61
  }
74
62
  }
75
63
  }
76
64
 
77
65
  /**
78
- * Call `.unload()` on `playerId`'s player.
79
- * @param playerId Target player Id.
66
+ * Call `.unload()` on `nativeId`'s player.
67
+ * @param nativeId Target player Id.
80
68
  */
81
69
  @ReactMethod
82
- fun unload(playerId: String) {
70
+ fun unload(nativeId: NativeId) {
83
71
  uiManager()?.addUIBlock {
84
- registry[playerId]?.unload()
72
+ players[nativeId]?.unload()
85
73
  }
86
74
  }
87
75
 
88
76
  /**
89
- * Call `.play()` on `playerId`'s player.
90
- * @param playerId Target player Id.
77
+ * Call `.play()` on `nativeId`'s player.
78
+ * @param nativeId Target player Id.
91
79
  */
92
80
  @ReactMethod
93
- fun play(playerId: String) {
81
+ fun play(nativeId: NativeId) {
94
82
  uiManager()?.addUIBlock {
95
- registry[playerId]?.play()
83
+ players[nativeId]?.play()
96
84
  }
97
85
  }
98
86
 
99
87
  /**
100
- * Call `.pause()` on `playerId`'s player.
101
- * @param playerId Target player Id.
88
+ * Call `.pause()` on `nativeId`'s player.
89
+ * @param nativeId Target player Id.
102
90
  */
103
91
  @ReactMethod
104
- fun pause(playerId: String) {
92
+ fun pause(nativeId: NativeId) {
105
93
  uiManager()?.addUIBlock {
106
- registry[playerId]?.pause()
94
+ players[nativeId]?.pause()
107
95
  }
108
96
  }
109
97
 
110
98
  /**
111
- * Call `.seek(time:)` on `playerId`'s player.
112
- * @param playerId Target player Id.
99
+ * Call `.seek(time:)` on `nativeId`'s player.
100
+ * @param nativeId Target player Id.
113
101
  * @param time Seek time in seconds.
114
102
  */
115
103
  @ReactMethod
116
- fun seek(playerId: String, time: Double) {
104
+ fun seek(nativeId: NativeId, time: Double) {
117
105
  uiManager()?.addUIBlock {
118
- registry[playerId]?.seek(time)
106
+ players[nativeId]?.seek(time)
119
107
  }
120
108
  }
121
109
 
122
110
  /**
123
- * Call `.mute()` on `playerId`'s player.
124
- * @param playerId Target player Id.
111
+ * Call `.mute()` on `nativeId`'s player.
112
+ * @param nativeId Target player Id.
125
113
  */
126
114
  @ReactMethod
127
- fun mute(playerId: String) {
115
+ fun mute(nativeId: NativeId) {
128
116
  uiManager()?.addUIBlock {
129
- registry[playerId]?.mute()
117
+ players[nativeId]?.mute()
130
118
  }
131
119
  }
132
120
 
133
121
  /**
134
- * Call `.unmute()` on `playerId`'s player.
135
- * @param playerId Target player Id.
122
+ * Call `.unmute()` on `nativeId`'s player.
123
+ * @param nativeId Target player Id.
136
124
  */
137
125
  @ReactMethod
138
- fun unmute(playerId: String) {
126
+ fun unmute(nativeId: NativeId) {
139
127
  uiManager()?.addUIBlock {
140
- registry[playerId]?.unmute()
128
+ players[nativeId]?.unmute()
141
129
  }
142
130
  }
143
131
 
144
132
  /**
145
- * Call `.destroy()` on `playerId`'s player.
146
- * @param playerId Target player Id.
133
+ * Call `.destroy()` on `nativeId`'s player.
134
+ * @param nativeId Target player Id.
147
135
  */
148
136
  @ReactMethod
149
- fun destroy(playerId: String) {
137
+ fun destroy(nativeId: NativeId) {
150
138
  uiManager()?.addUIBlock {
151
- registry[playerId]?.destroy()
139
+ players[nativeId]?.let {
140
+ it.destroy()
141
+ players.remove(nativeId)
142
+ }
152
143
  }
153
144
  }
154
145
 
155
146
  /**
156
- * Call `.setVolume(volume:)` on `playerId`'s player.
157
- * @param playerId Target player Id.
147
+ * Call `.setVolume(volume:)` on `nativeId`'s player.
148
+ * @param nativeId Target player Id.
158
149
  * @param volume Volume level integer between 0 to 100.
159
150
  */
160
151
  @ReactMethod
161
- fun setVolume(playerId: String, volume: Int) {
152
+ fun setVolume(nativeId: NativeId, volume: Int) {
162
153
  uiManager()?.addUIBlock {
163
- registry[playerId]?.volume = volume
154
+ players[nativeId]?.volume = volume
164
155
  }
165
156
  }
166
157
 
167
158
  /**
168
- * Resolve `playerId`'s current volume.
169
- * @param playerId Target player Id.
159
+ * Resolve `nativeId`'s current volume.
160
+ * @param nativeId Target player Id.
170
161
  * @param promise JS promise object.
171
162
  */
172
163
  @ReactMethod
173
- fun getVolume(playerId: String, promise: Promise) {
164
+ fun getVolume(nativeId: NativeId, promise: Promise) {
174
165
  uiManager()?.addUIBlock {
175
- promise.resolve(registry[playerId]?.volume)
166
+ promise.resolve(players[nativeId]?.volume)
176
167
  }
177
168
  }
178
169
 
179
170
  /**
180
- * Resolve the source of `playerId`'s player.
181
- * @param playerId Target player Id.
171
+ * Resolve the source of `nativeId`'s player.
172
+ * @param nativeId Target player Id.
182
173
  * @param promise JS promise object.
183
174
  */
184
175
  @ReactMethod
185
- fun source(playerId: String, promise: Promise) {
176
+ fun source(nativeId: NativeId, promise: Promise) {
186
177
  uiManager()?.addUIBlock {
187
- promise.resolve(JsonConverter.fromSource(registry[playerId]?.source))
178
+ promise.resolve(JsonConverter.fromSource(players[nativeId]?.source))
188
179
  }
189
180
  }
190
181
 
191
182
  /**
192
- * Resolve `playerId`'s current playback time.
193
- * @param playerId Target player Id.
183
+ * Resolve `nativeId`'s current playback time.
184
+ * @param nativeId Target player Id.
194
185
  * @param promise JS promise object.
195
186
  */
196
187
  @ReactMethod
197
- fun currentTime(playerId: String, mode: String?, promise: Promise) {
188
+ fun currentTime(nativeId: NativeId, mode: String?, promise: Promise) {
198
189
  uiManager()?.addUIBlock {
199
190
  var timeOffset: Double = 0.0
200
191
  if (mode != null) {
201
192
  timeOffset = if (mode == "relative") {
202
- registry[playerId]?.playbackTimeOffsetToRelativeTime ?: 0.0
193
+ players[nativeId]?.playbackTimeOffsetToRelativeTime ?: 0.0
203
194
  } else {
204
- registry[playerId]?.playbackTimeOffsetToAbsoluteTime ?: 0.0
195
+ players[nativeId]?.playbackTimeOffsetToAbsoluteTime ?: 0.0
205
196
  }
206
197
  }
207
- val currentTime = registry[playerId]?.currentTime
198
+ val currentTime = players[nativeId]?.currentTime
208
199
  if (currentTime != null) {
209
200
  promise.resolve(currentTime + timeOffset)
210
201
  }
@@ -212,62 +203,80 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
212
203
  }
213
204
 
214
205
  /**
215
- * Resolve `playerId`'s current source duration.
216
- * @param playerId Target player Id.
206
+ * Resolve `nativeId`'s current source duration.
207
+ * @param nativeId Target player Id.
217
208
  * @param promise JS promise object.
218
209
  */
219
210
  @ReactMethod
220
- fun duration(playerId: String, promise: Promise) {
211
+ fun duration(nativeId: NativeId, promise: Promise) {
221
212
  uiManager()?.addUIBlock {
222
- promise.resolve(registry[playerId]?.duration)
213
+ promise.resolve(players[nativeId]?.duration)
223
214
  }
224
215
  }
225
216
 
226
217
  /**
227
- * Resolve `playerId`'s current muted state.
228
- * @param playerId Target player Id.
218
+ * Resolve `nativeId`'s current muted state.
219
+ * @param nativeId Target player Id.
229
220
  * @param promise JS promise object.
230
221
  */
231
222
  @ReactMethod
232
- fun isMuted(playerId: String, promise: Promise) {
223
+ fun isMuted(nativeId: NativeId, promise: Promise) {
233
224
  uiManager()?.addUIBlock {
234
- promise.resolve(registry[playerId]?.isMuted)
225
+ promise.resolve(players[nativeId]?.isMuted)
235
226
  }
236
227
  }
237
228
 
238
229
  /**
239
- * Resolve `playerId`'s current playing state.
240
- * @param playerId Target player Id.
230
+ * Resolve `nativeId`'s current playing state.
231
+ * @param nativeId Target player Id.
241
232
  * @param promise JS promise object.
242
233
  */
243
234
  @ReactMethod
244
- fun isPlaying(playerId: String, promise: Promise) {
235
+ fun isPlaying(nativeId: NativeId, promise: Promise) {
245
236
  uiManager()?.addUIBlock {
246
- promise.resolve(registry[playerId]?.isPlaying)
237
+ promise.resolve(players[nativeId]?.isPlaying)
247
238
  }
248
239
  }
249
240
 
250
241
  /**
251
- * Resolve `playerId`'s current paused state.
252
- * @param playerId Target player Id.
242
+ * Resolve `nativeId`'s current paused state.
243
+ * @param nativeId Target player Id.
253
244
  * @param promise JS promise object.
254
245
  */
255
246
  @ReactMethod
256
- fun isPaused(playerId: String, promise: Promise) {
247
+ fun isPaused(nativeId: NativeId, promise: Promise) {
257
248
  uiManager()?.addUIBlock {
258
- promise.resolve(registry[playerId]?.isPaused)
249
+ promise.resolve(players[nativeId]?.isPaused)
259
250
  }
260
251
  }
261
252
 
262
253
  /**
263
- * Resolve `playerId`'s current live state.
264
- * @param playerId Target player Id.
254
+ * Resolve `nativeId`'s current live state.
255
+ * @param nativeId Target player Id.
265
256
  * @param promise JS promise object.
266
257
  */
267
258
  @ReactMethod
268
- fun isLive(playerId: String, promise: Promise) {
259
+ fun isLive(nativeId: NativeId, promise: Promise) {
269
260
  uiManager()?.addUIBlock {
270
- promise.resolve(registry[playerId]?.isLive)
261
+ promise.resolve(players[nativeId]?.isLive)
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Resolve `nativeId`'s player available subtitle tracks.
267
+ * @param nativeId Target player Id.
268
+ * @param promise JS promise object.
269
+ */
270
+ @ReactMethod
271
+ fun getAvailableSubtitles(nativeId: NativeId, promise: Promise) {
272
+ uiManager()?.addUIBlock {
273
+ val subtitleTracks = Arguments.createArray()
274
+ players[nativeId]?.source?.availableSubtitleTracks?.let { tracks ->
275
+ tracks.forEach {
276
+ subtitleTracks.pushMap(JsonConverter.fromSubtitleTrack(it))
277
+ }
278
+ }
279
+ promise.resolve(subtitleTracks)
271
280
  }
272
281
  }
273
282
 
@@ -276,4 +285,10 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
276
285
  */
277
286
  private fun uiManager(): UIManagerModule? =
278
287
  context.getNativeModule(UIManagerModule::class.java)
279
- }
288
+
289
+ /**
290
+ * Helper function that returns the initialized `SourceModule` instance.
291
+ */
292
+ private fun sourceModule(): SourceModule? =
293
+ context.getNativeModule(SourceModule::class.java)
294
+ }
@@ -195,54 +195,85 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
195
195
  emitEvent("sourceWarning", it)
196
196
  }
197
197
 
198
+ /**
199
+ * `onSubtitleAdded` event callback.
200
+ */
201
+ private val onSubtitleAdded: (SourceEvent.SubtitleTrackAdded) -> Unit = {
202
+ emitEvent("subtitleAdded", it)
203
+ }
204
+
205
+ /**
206
+ * `onSubtitleChanged` event callback.
207
+ */
208
+ private val onSubtitleChanged: (SourceEvent.SubtitleTrackChanged) -> Unit = {
209
+ emitEvent("subtitleChanged", it)
210
+ }
211
+
212
+ /**
213
+ * `onSubtitleRemoved` event callback.
214
+ */
215
+ private val onSubtitleRemoved: (SourceEvent.SubtitleTrackRemoved) -> Unit = {
216
+ emitEvent("subtitleRemoved", it)
217
+ }
218
+
198
219
  /**
199
220
  * Start listening and emitting player events as bubbling events to the js side.
200
221
  */
201
222
  fun startBubblingEvents() {
202
- player?.on(onEvent)
203
- player?.on(onPlayerError)
204
- player?.on(onPlayerWarning)
205
- player?.on(onDestroy)
206
- player?.on(onMuted)
207
- player?.on(onUnmuted)
208
- player?.on(onReady)
209
- player?.on(onPaused)
210
- player?.on(onPlay)
211
- player?.on(onPlaying)
212
- player?.on(onPlaybackFinished)
213
- player?.on(onSeek)
214
- player?.on(onSeeked)
215
- player?.on(onTimeChanged)
216
- player?.on(onSourceLoad)
217
- player?.on(onSourceLoaded)
218
- player?.on(onSourceUnloaded)
219
- player?.on(onSourceError)
220
- player?.on(onSourceWarning)
223
+ player?.apply {
224
+ on(onEvent)
225
+ on(onPlayerError)
226
+ on(onPlayerWarning)
227
+ on(onDestroy)
228
+ on(onMuted)
229
+ on(onUnmuted)
230
+ on(onReady)
231
+ on(onPaused)
232
+ on(onPlay)
233
+ on(onPlaying)
234
+ on(onPlaybackFinished)
235
+ on(onSeek)
236
+ on(onSeeked)
237
+ on(onTimeChanged)
238
+ on(onSourceLoad)
239
+ on(onSourceLoaded)
240
+ on(onSourceUnloaded)
241
+ on(onSourceError)
242
+ on(onSourceWarning)
243
+ on(onSubtitleAdded)
244
+ on(onSubtitleChanged)
245
+ on(onSubtitleRemoved)
246
+ }
221
247
  }
222
248
 
223
249
  /**
224
250
  * Stop listening for player events and cease to emit bubbling events.
225
251
  */
226
252
  fun stopBubblingEvents() {
227
- player?.off(onEvent)
228
- player?.off(onPlayerError)
229
- player?.off(onPlayerWarning)
230
- player?.off(onDestroy)
231
- player?.off(onMuted)
232
- player?.off(onUnmuted)
233
- player?.off(onReady)
234
- player?.off(onPaused)
235
- player?.off(onPlay)
236
- player?.off(onPlaying)
237
- player?.off(onPlaybackFinished)
238
- player?.off(onSeek)
239
- player?.off(onSeeked)
240
- player?.off(onTimeChanged)
241
- player?.off(onSourceLoad)
242
- player?.off(onSourceLoaded)
243
- player?.off(onSourceUnloaded)
244
- player?.off(onSourceError)
245
- player?.off(onSourceWarning)
253
+ player?.apply {
254
+ off(onEvent)
255
+ off(onPlayerError)
256
+ off(onPlayerWarning)
257
+ off(onDestroy)
258
+ off(onMuted)
259
+ off(onUnmuted)
260
+ off(onReady)
261
+ off(onPaused)
262
+ off(onPlay)
263
+ off(onPlaying)
264
+ off(onPlaybackFinished)
265
+ off(onSeek)
266
+ off(onSeeked)
267
+ off(onTimeChanged)
268
+ off(onSourceLoad)
269
+ off(onSourceLoaded)
270
+ off(onSourceUnloaded)
271
+ off(onSourceError)
272
+ off(onSourceWarning)
273
+ off(onSubtitleAdded)
274
+ off(onSubtitleChanged)
275
+ off(onSubtitleRemoved)
276
+ }
246
277
  }
247
278
 
248
279
  /**
@@ -1,11 +1,12 @@
1
1
  package com.bitmovin.player.reactnative
2
2
 
3
+ import android.os.Handler
4
+ import android.os.Looper
3
5
  import android.view.ViewGroup.LayoutParams
4
6
  import com.bitmovin.player.PlayerView
5
7
  import com.facebook.react.bridge.*
6
8
  import com.facebook.react.uimanager.SimpleViewManager
7
9
  import com.facebook.react.uimanager.ThemedReactContext
8
- import com.facebook.react.uimanager.UIManagerModule
9
10
 
10
11
  class RNPlayerViewManager(private val context: ReactApplicationContext) : SimpleViewManager<RNPlayerView>() {
11
12
  /**
@@ -13,7 +14,6 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
13
14
  */
14
15
  enum class Commands {
15
16
  ATTACH_PLAYER,
16
- DETACH_PLAYER,
17
17
  }
18
18
 
19
19
  /**
@@ -51,6 +51,9 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
51
51
  "sourceUnloaded" to "onSourceUnloaded",
52
52
  "sourceError" to "onSourceError",
53
53
  "sourceWarning" to "onSourceWarning",
54
+ "subtitleAdded" to "onSubtitleAdded",
55
+ "subtitleChanged" to "onSubtitleChanged",
56
+ "subtitleRemoved" to "onSubtitleRemoved",
54
57
  )
55
58
 
56
59
  /**
@@ -72,13 +75,12 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
72
75
  * @return map between names (used in js) and command ids (used in native code).
73
76
  */
74
77
  override fun getCommandsMap(): MutableMap<String, Int> = mutableMapOf(
75
- "attachPlayer" to Commands.ATTACH_PLAYER.ordinal,
76
- "detachPlayer" to Commands.DETACH_PLAYER.ordinal,
78
+ "attachPlayer" to Commands.ATTACH_PLAYER.ordinal
77
79
  )
78
80
 
79
81
  /**
80
82
  * Callback triggered in response to command dispatches from the js side.
81
- * @param root Root native view of the targeted component.
83
+ * @param view Root native view of the targeted component.
82
84
  * @param commandId Command number identifier. It's a number even though RN sends it as a string.
83
85
  * @param args Arguments list sent from the js side.
84
86
  */
@@ -87,7 +89,6 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
87
89
  commandId?.toInt()?.let {
88
90
  when (it) {
89
91
  Commands.ATTACH_PLAYER.ordinal -> attachPlayer(view, args?.getString(1))
90
- Commands.DETACH_PLAYER.ordinal -> detachPlayer(view, args?.getString(1))
91
92
  else -> {}
92
93
  }
93
94
  }
@@ -98,8 +99,8 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
98
99
  * @param view Target `RNPlayerView`.
99
100
  * @param playerId `Player` instance id inside `PlayerModule`'s registry.
100
101
  */
101
- private fun attachPlayer(view: RNPlayerView, playerId: String?) {
102
- uiManager()?.addUIBlock {
102
+ private fun attachPlayer(view: RNPlayerView, playerId: NativeId?) {
103
+ Handler(Looper.getMainLooper()).post {
103
104
  val player = getPlayerModule()?.getPlayer(playerId)
104
105
  if (view.playerView != null) {
105
106
  view.player = player
@@ -114,26 +115,9 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
114
115
  }
115
116
  }
116
117
 
117
- /**
118
- * Stop sending `Player` bubbling events from `PlayerView`.
119
- * @param view Target `RNPlayerView`.
120
- * @param playerId `Player` instance id inside `PlayerModule`'s registry.
121
- */
122
- private fun detachPlayer(view: RNPlayerView, playerId: String?) {
123
- uiManager()?.addUIBlock {
124
- view.stopBubblingEvents()
125
- }
126
- }
127
-
128
118
  /**
129
119
  * Helper function that gets the instantiated `PlayerModule` from modules registry.
130
120
  */
131
121
  private fun getPlayerModule(): PlayerModule? =
132
122
  context.getNativeModule(PlayerModule::class.java)
133
-
134
- /**
135
- * Helper function that returns the initialized `UIManager` instance.
136
- */
137
- private fun uiManager(): UIManagerModule? =
138
- context.getNativeModule(UIManagerModule::class.java)
139
- }
123
+ }
@@ -17,7 +17,10 @@ class RNPlayerViewPackage : ReactPackage {
17
17
  */
18
18
  override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
19
19
  return mutableListOf(
20
+ UuidModule(reactContext),
20
21
  PlayerModule(reactContext),
22
+ SourceModule(reactContext),
23
+ DrmModule(reactContext),
21
24
  RNPlayerViewManager(reactContext),
22
25
  )
23
26
  }
@@ -0,0 +1,11 @@
1
+ package com.bitmovin.player.reactnative
2
+
3
+ /**
4
+ * Represents the `UUID` string used as index for a certain registry object.
5
+ */
6
+ typealias NativeId = String
7
+
8
+ /**
9
+ * Represents an in memory storage facility that associates an object of type `T` with a certain `NativeId`.
10
+ */
11
+ typealias Registry<T> = MutableMap<NativeId, T>