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.
- package/README.md +163 -1
- package/RNBitmovinPlayer.podspec +3 -3
- package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +191 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +116 -101
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +69 -38
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +10 -26
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/Registry.kt +11 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +178 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +20 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +128 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Events.kt +11 -2
- package/ios/DrmModule.m +16 -0
- package/ios/DrmModule.swift +442 -0
- package/ios/Event+JSON.swift +31 -0
- package/ios/PlayerModule.m +21 -25
- package/ios/PlayerModule.swift +122 -120
- package/ios/RCTConvert+BitmovinPlayer.swift +131 -12
- package/ios/RNPlayerView+PlayerListener.swift +12 -0
- package/ios/RNPlayerView.swift +5 -3
- package/ios/RNPlayerViewManager.m +3 -1
- package/ios/RNPlayerViewManager.swift +4 -21
- package/ios/Registry.swift +5 -0
- package/ios/SourceModule.m +30 -0
- package/ios/SourceModule.swift +187 -0
- package/ios/UuidModule.m +9 -0
- package/ios/UuidModule.swift +23 -0
- package/lib/index.d.ts +670 -235
- package/lib/index.js +257 -106
- package/lib/index.mjs +260 -112
- package/package.json +5 -4
- package/src/components/PlayerView/events.ts +24 -18
- package/src/components/PlayerView/index.tsx +29 -26
- package/src/drm/fairplayConfig.ts +90 -0
- package/src/drm/index.ts +178 -0
- package/src/drm/widevineConfig.ts +37 -0
- package/src/events.ts +67 -6
- package/src/hooks/useProxy.ts +19 -15
- package/src/index.ts +5 -3
- package/src/nativeInstance.ts +64 -0
- package/src/player.ts +51 -42
- package/src/source.ts +88 -8
- package/src/subtitleTrack.ts +60 -0
- 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
|
|
6
|
-
import com.facebook.react.
|
|
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
|
|
12
|
+
* In-memory mapping from `nativeId`s to `Player` instances.
|
|
18
13
|
*/
|
|
19
|
-
private
|
|
14
|
+
private val players: Registry<Player> = mutableMapOf()
|
|
20
15
|
|
|
21
16
|
/**
|
|
22
|
-
*
|
|
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
|
-
*
|
|
31
|
-
* @param
|
|
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(
|
|
34
|
-
if (
|
|
29
|
+
fun getPlayer(nativeId: NativeId?): Player? {
|
|
30
|
+
if (nativeId == null) {
|
|
35
31
|
return null
|
|
36
32
|
}
|
|
37
|
-
return
|
|
33
|
+
return players[nativeId]
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
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(
|
|
41
|
+
fun initWithConfig(nativeId: NativeId, config: ReadableMap?) {
|
|
54
42
|
uiManager()?.addUIBlock {
|
|
55
|
-
if (!
|
|
56
|
-
JsonConverter.toPlayerConfig(config)
|
|
57
|
-
|
|
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 `
|
|
65
|
-
* @param
|
|
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(
|
|
57
|
+
fun loadSource(nativeId: NativeId, sourceNativeId: String) {
|
|
70
58
|
uiManager()?.addUIBlock {
|
|
71
|
-
|
|
72
|
-
|
|
59
|
+
sourceModule()?.getSource(sourceNativeId)?.let {
|
|
60
|
+
players[nativeId]?.load(it)
|
|
73
61
|
}
|
|
74
62
|
}
|
|
75
63
|
}
|
|
76
64
|
|
|
77
65
|
/**
|
|
78
|
-
* Call `.unload()` on `
|
|
79
|
-
* @param
|
|
66
|
+
* Call `.unload()` on `nativeId`'s player.
|
|
67
|
+
* @param nativeId Target player Id.
|
|
80
68
|
*/
|
|
81
69
|
@ReactMethod
|
|
82
|
-
fun unload(
|
|
70
|
+
fun unload(nativeId: NativeId) {
|
|
83
71
|
uiManager()?.addUIBlock {
|
|
84
|
-
|
|
72
|
+
players[nativeId]?.unload()
|
|
85
73
|
}
|
|
86
74
|
}
|
|
87
75
|
|
|
88
76
|
/**
|
|
89
|
-
* Call `.play()` on `
|
|
90
|
-
* @param
|
|
77
|
+
* Call `.play()` on `nativeId`'s player.
|
|
78
|
+
* @param nativeId Target player Id.
|
|
91
79
|
*/
|
|
92
80
|
@ReactMethod
|
|
93
|
-
fun play(
|
|
81
|
+
fun play(nativeId: NativeId) {
|
|
94
82
|
uiManager()?.addUIBlock {
|
|
95
|
-
|
|
83
|
+
players[nativeId]?.play()
|
|
96
84
|
}
|
|
97
85
|
}
|
|
98
86
|
|
|
99
87
|
/**
|
|
100
|
-
* Call `.pause()` on `
|
|
101
|
-
* @param
|
|
88
|
+
* Call `.pause()` on `nativeId`'s player.
|
|
89
|
+
* @param nativeId Target player Id.
|
|
102
90
|
*/
|
|
103
91
|
@ReactMethod
|
|
104
|
-
fun pause(
|
|
92
|
+
fun pause(nativeId: NativeId) {
|
|
105
93
|
uiManager()?.addUIBlock {
|
|
106
|
-
|
|
94
|
+
players[nativeId]?.pause()
|
|
107
95
|
}
|
|
108
96
|
}
|
|
109
97
|
|
|
110
98
|
/**
|
|
111
|
-
* Call `.seek(time:)` on `
|
|
112
|
-
* @param
|
|
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(
|
|
104
|
+
fun seek(nativeId: NativeId, time: Double) {
|
|
117
105
|
uiManager()?.addUIBlock {
|
|
118
|
-
|
|
106
|
+
players[nativeId]?.seek(time)
|
|
119
107
|
}
|
|
120
108
|
}
|
|
121
109
|
|
|
122
110
|
/**
|
|
123
|
-
* Call `.mute()` on `
|
|
124
|
-
* @param
|
|
111
|
+
* Call `.mute()` on `nativeId`'s player.
|
|
112
|
+
* @param nativeId Target player Id.
|
|
125
113
|
*/
|
|
126
114
|
@ReactMethod
|
|
127
|
-
fun mute(
|
|
115
|
+
fun mute(nativeId: NativeId) {
|
|
128
116
|
uiManager()?.addUIBlock {
|
|
129
|
-
|
|
117
|
+
players[nativeId]?.mute()
|
|
130
118
|
}
|
|
131
119
|
}
|
|
132
120
|
|
|
133
121
|
/**
|
|
134
|
-
* Call `.unmute()` on `
|
|
135
|
-
* @param
|
|
122
|
+
* Call `.unmute()` on `nativeId`'s player.
|
|
123
|
+
* @param nativeId Target player Id.
|
|
136
124
|
*/
|
|
137
125
|
@ReactMethod
|
|
138
|
-
fun unmute(
|
|
126
|
+
fun unmute(nativeId: NativeId) {
|
|
139
127
|
uiManager()?.addUIBlock {
|
|
140
|
-
|
|
128
|
+
players[nativeId]?.unmute()
|
|
141
129
|
}
|
|
142
130
|
}
|
|
143
131
|
|
|
144
132
|
/**
|
|
145
|
-
* Call `.destroy()` on `
|
|
146
|
-
* @param
|
|
133
|
+
* Call `.destroy()` on `nativeId`'s player.
|
|
134
|
+
* @param nativeId Target player Id.
|
|
147
135
|
*/
|
|
148
136
|
@ReactMethod
|
|
149
|
-
fun destroy(
|
|
137
|
+
fun destroy(nativeId: NativeId) {
|
|
150
138
|
uiManager()?.addUIBlock {
|
|
151
|
-
|
|
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 `
|
|
157
|
-
* @param
|
|
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(
|
|
152
|
+
fun setVolume(nativeId: NativeId, volume: Int) {
|
|
162
153
|
uiManager()?.addUIBlock {
|
|
163
|
-
|
|
154
|
+
players[nativeId]?.volume = volume
|
|
164
155
|
}
|
|
165
156
|
}
|
|
166
157
|
|
|
167
158
|
/**
|
|
168
|
-
* Resolve `
|
|
169
|
-
* @param
|
|
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(
|
|
164
|
+
fun getVolume(nativeId: NativeId, promise: Promise) {
|
|
174
165
|
uiManager()?.addUIBlock {
|
|
175
|
-
promise.resolve(
|
|
166
|
+
promise.resolve(players[nativeId]?.volume)
|
|
176
167
|
}
|
|
177
168
|
}
|
|
178
169
|
|
|
179
170
|
/**
|
|
180
|
-
* Resolve the source of `
|
|
181
|
-
* @param
|
|
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(
|
|
176
|
+
fun source(nativeId: NativeId, promise: Promise) {
|
|
186
177
|
uiManager()?.addUIBlock {
|
|
187
|
-
promise.resolve(JsonConverter.fromSource(
|
|
178
|
+
promise.resolve(JsonConverter.fromSource(players[nativeId]?.source))
|
|
188
179
|
}
|
|
189
180
|
}
|
|
190
181
|
|
|
191
182
|
/**
|
|
192
|
-
* Resolve `
|
|
193
|
-
* @param
|
|
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(
|
|
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
|
-
|
|
193
|
+
players[nativeId]?.playbackTimeOffsetToRelativeTime ?: 0.0
|
|
203
194
|
} else {
|
|
204
|
-
|
|
195
|
+
players[nativeId]?.playbackTimeOffsetToAbsoluteTime ?: 0.0
|
|
205
196
|
}
|
|
206
197
|
}
|
|
207
|
-
val 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 `
|
|
216
|
-
* @param
|
|
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(
|
|
211
|
+
fun duration(nativeId: NativeId, promise: Promise) {
|
|
221
212
|
uiManager()?.addUIBlock {
|
|
222
|
-
promise.resolve(
|
|
213
|
+
promise.resolve(players[nativeId]?.duration)
|
|
223
214
|
}
|
|
224
215
|
}
|
|
225
216
|
|
|
226
217
|
/**
|
|
227
|
-
* Resolve `
|
|
228
|
-
* @param
|
|
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(
|
|
223
|
+
fun isMuted(nativeId: NativeId, promise: Promise) {
|
|
233
224
|
uiManager()?.addUIBlock {
|
|
234
|
-
promise.resolve(
|
|
225
|
+
promise.resolve(players[nativeId]?.isMuted)
|
|
235
226
|
}
|
|
236
227
|
}
|
|
237
228
|
|
|
238
229
|
/**
|
|
239
|
-
* Resolve `
|
|
240
|
-
* @param
|
|
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(
|
|
235
|
+
fun isPlaying(nativeId: NativeId, promise: Promise) {
|
|
245
236
|
uiManager()?.addUIBlock {
|
|
246
|
-
promise.resolve(
|
|
237
|
+
promise.resolve(players[nativeId]?.isPlaying)
|
|
247
238
|
}
|
|
248
239
|
}
|
|
249
240
|
|
|
250
241
|
/**
|
|
251
|
-
* Resolve `
|
|
252
|
-
* @param
|
|
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(
|
|
247
|
+
fun isPaused(nativeId: NativeId, promise: Promise) {
|
|
257
248
|
uiManager()?.addUIBlock {
|
|
258
|
-
promise.resolve(
|
|
249
|
+
promise.resolve(players[nativeId]?.isPaused)
|
|
259
250
|
}
|
|
260
251
|
}
|
|
261
252
|
|
|
262
253
|
/**
|
|
263
|
-
* Resolve `
|
|
264
|
-
* @param
|
|
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(
|
|
259
|
+
fun isLive(nativeId: NativeId, promise: Promise) {
|
|
269
260
|
uiManager()?.addUIBlock {
|
|
270
|
-
promise.resolve(
|
|
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?.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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?.
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
|
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:
|
|
102
|
-
|
|
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>
|