bitmovin-player-react-native 0.3.1 → 0.5.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 (56) hide show
  1. package/README.md +486 -24
  2. package/RNBitmovinPlayer.podspec +5 -1
  3. package/android/build.gradle +8 -5
  4. package/android/src/main/java/com/bitmovin/player/reactnative/AnalyticsModule.kt +154 -0
  5. package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +4 -5
  6. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +41 -5
  7. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +318 -2
  8. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +70 -9
  9. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
  10. package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +4 -5
  11. package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +3 -1
  12. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +389 -0
  13. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Any.kt +27 -0
  14. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +8 -0
  15. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableArray.kt +19 -2
  16. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/String.kt +8 -0
  17. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/WritableMap.kt +19 -0
  18. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerBridge.kt +37 -0
  19. package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerModule.kt +73 -0
  20. package/android/src/main/java/com/bitmovin/player/reactnative/ui/RNPictureInPictureHandler.kt +191 -0
  21. package/ios/AnalyticsModule.m +14 -0
  22. package/ios/AnalyticsModule.swift +180 -0
  23. package/ios/AudioSessionModule.m +10 -0
  24. package/ios/AudioSessionModule.swift +65 -0
  25. package/ios/Event+JSON.swift +134 -0
  26. package/ios/FullscreenHandlerBridge.swift +33 -0
  27. package/ios/FullscreenHandlerModule.m +9 -0
  28. package/ios/FullscreenHandlerModule.swift +71 -0
  29. package/ios/PlayerModule.m +6 -0
  30. package/ios/PlayerModule.swift +44 -0
  31. package/ios/RCTConvert+BitmovinPlayer.swift +382 -0
  32. package/ios/RNPlayerView+PlayerListener.swift +56 -0
  33. package/ios/RNPlayerView+UserInterfaceListener.swift +35 -0
  34. package/ios/RNPlayerView.swift +22 -0
  35. package/ios/RNPlayerViewManager.m +24 -1
  36. package/ios/RNPlayerViewManager.swift +23 -1
  37. package/lib/index.d.ts +1013 -150
  38. package/lib/index.js +251 -48
  39. package/lib/index.mjs +231 -34
  40. package/package.json +1 -1
  41. package/src/advertising.ts +155 -0
  42. package/src/analytics/collector.ts +97 -0
  43. package/src/analytics/config.ts +218 -0
  44. package/src/analytics/index.ts +2 -0
  45. package/src/audioSession.ts +47 -0
  46. package/src/components/PlayerView/events.ts +49 -3
  47. package/src/components/PlayerView/index.tsx +68 -11
  48. package/src/components/PlayerView/native.ts +4 -1
  49. package/src/events.ts +255 -0
  50. package/src/index.ts +4 -0
  51. package/src/media.ts +33 -0
  52. package/src/player.ts +57 -1
  53. package/src/source.ts +4 -0
  54. package/src/styleConfig.ts +87 -0
  55. package/src/ui/fullscreenhandler.ts +19 -0
  56. package/src/ui/fullscreenhandlerbridge.ts +59 -0
@@ -161,3 +161,137 @@ extension SubtitleChangedEvent {
161
161
  ]
162
162
  }
163
163
  }
164
+
165
+ extension AdBreakFinishedEvent {
166
+ func toJSON() -> [AnyHashable: Any] {
167
+ [
168
+ "name": name,
169
+ "timestamp": timestamp,
170
+ "adBreak": RCTConvert.toJson(adBreak: adBreak)
171
+ ]
172
+ }
173
+ }
174
+
175
+ extension AdBreakStartedEvent {
176
+ func toJSON() -> [AnyHashable: Any] {
177
+ [
178
+ "name": name,
179
+ "timestamp": timestamp,
180
+ "adBreak": RCTConvert.toJson(adBreak: adBreak)
181
+ ]
182
+ }
183
+ }
184
+
185
+ extension AdClickedEvent {
186
+ func toJSON() -> [AnyHashable: Any] {
187
+ [
188
+ "name": name,
189
+ "timestamp": timestamp,
190
+ "clickThroughUrl": clickThroughUrl
191
+ ]
192
+ }
193
+ }
194
+
195
+ extension AdErrorEvent {
196
+ func toJSON() -> [AnyHashable: Any] {
197
+ [
198
+ "name": name,
199
+ "timestamp": timestamp,
200
+ "adConfig": RCTConvert.toJson(adConfig: adConfig),
201
+ "adItem": RCTConvert.toJson(adItem: adItem),
202
+ "code": code,
203
+ "message": message
204
+ ]
205
+ }
206
+ }
207
+
208
+ extension AdFinishedEvent {
209
+ func toJSON() -> [AnyHashable: Any] {
210
+ [
211
+ "name": name,
212
+ "timestamp": timestamp,
213
+ "ad": RCTConvert.toJson(ad: ad)
214
+ ]
215
+ }
216
+ }
217
+
218
+ extension AdManifestLoadEvent {
219
+ func toJSON() -> [AnyHashable: Any] {
220
+ [
221
+ "name": name,
222
+ "timestamp": timestamp,
223
+ "adBreak": RCTConvert.toJson(adBreak: adBreak),
224
+ "adConfig": RCTConvert.toJson(adConfig: adConfig)
225
+ ]
226
+ }
227
+ }
228
+
229
+ extension AdManifestLoadedEvent {
230
+ func toJSON() -> [AnyHashable: Any] {
231
+ [
232
+ "name": name,
233
+ "timestamp": timestamp,
234
+ "adBreak": RCTConvert.toJson(adBreak: adBreak),
235
+ "adConfig": RCTConvert.toJson(adConfig: adConfig),
236
+ "downloadTime": downloadTime
237
+ ]
238
+ }
239
+ }
240
+
241
+ extension AdQuartileEvent {
242
+ func toJSON() -> [AnyHashable: Any] {
243
+ [
244
+ "name": name,
245
+ "timestamp": timestamp,
246
+ "quartile": RCTConvert.toJson(adQuartile: adQuartile)
247
+ ]
248
+ }
249
+ }
250
+
251
+ extension AdScheduledEvent {
252
+ func toJSON() -> [AnyHashable: Any] {
253
+ [
254
+ "name": name,
255
+ "timestamp": timestamp,
256
+ "numberOfAds": numberOfAds
257
+ ]
258
+ }
259
+ }
260
+
261
+ extension AdSkippedEvent {
262
+ func toJSON() -> [AnyHashable: Any] {
263
+ [
264
+ "name": name,
265
+ "timestamp": timestamp,
266
+ "ad": RCTConvert.toJson(ad: ad)
267
+ ]
268
+ }
269
+ }
270
+
271
+ extension AdStartedEvent {
272
+ func toJSON() -> [AnyHashable: Any] {
273
+ [
274
+ "name": name,
275
+ "timestamp": timestamp,
276
+ "ad": RCTConvert.toJson(ad: ad),
277
+ "clickThroughUrl": clickThroughUrl?.absoluteString,
278
+ "clientType": RCTConvert.toJson(adSourceType: clientType),
279
+ "duration": duration,
280
+ "indexInQueue": indexInQueue,
281
+ "position": position,
282
+ "skipOffset": skipOffset,
283
+ "timeOffset": timeOffset
284
+ ]
285
+ }
286
+ }
287
+
288
+ extension VideoDownloadQualityChangedEvent {
289
+ func toJSON() -> [AnyHashable: Any] {
290
+ [
291
+ "newVideoQuality": RCTConvert.toJson(videoQuality: videoQualityNew),
292
+ "oldVideoQuality": RCTConvert.toJson(videoQuality: videoQualityOld),
293
+ "name": name,
294
+ "timestamp": timestamp
295
+ ]
296
+ }
297
+ }
@@ -0,0 +1,33 @@
1
+ import BitmovinPlayer
2
+
3
+ class FullscreenHandlerBridge: NSObject, FullscreenHandler {
4
+ var isFullscreen = false
5
+
6
+ private let nativeId: NativeId
7
+ private let bridge: RCTBridge
8
+
9
+ init(_ nativeId: NativeId, bridge: RCTBridge) {
10
+ self.nativeId = nativeId
11
+ self.bridge = bridge
12
+ super.init()
13
+ }
14
+
15
+ func onFullscreenRequested() {
16
+ guard let fullscreenHandlerModule = getFullscreenHandlerModule() else {
17
+ return
18
+ }
19
+ fullscreenHandlerModule.onFullscreenRequested(nativeId: nativeId)
20
+ }
21
+
22
+ func onFullscreenExitRequested() {
23
+ guard let fullscreenHandlerModule = getFullscreenHandlerModule() else {
24
+ return
25
+ }
26
+ fullscreenHandlerModule.onFullscreenExitRequested(nativeId: nativeId)
27
+ }
28
+
29
+ /// Fetches the initialized `FullscreenHandlerModule` instance on RN's bridge object.
30
+ private func getFullscreenHandlerModule() -> FullscreenHandlerModule? {
31
+ bridge.module(for: FullscreenHandlerModule.self) as? FullscreenHandlerModule
32
+ }
33
+ }
@@ -0,0 +1,9 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RCT_EXTERN_REMAP_MODULE(FullscreenHandlerModule, FullscreenHandlerModule, NSObject)
4
+
5
+ RCT_EXTERN_METHOD(destroy:(NSString *)nativeId)
6
+
7
+ RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(onFullscreenChanged:(NSString *)nativeId isFullscreenEnabled:(BOOL)isFullscreenEnabled)
8
+ RCT_EXTERN_METHOD(registerHandler:(NSString *)nativeId)
9
+ @end
@@ -0,0 +1,71 @@
1
+ import BitmovinPlayer
2
+
3
+ @objc(FullscreenHandlerModule)
4
+ class FullscreenHandlerModule: NSObject, RCTBridgeModule {
5
+ /// React bridge reference.
6
+ @objc var bridge: RCTBridge!
7
+
8
+ /// JS module name.
9
+ static func moduleName() -> String! {
10
+ "FullscreenHandlerModule"
11
+ }
12
+
13
+ /// Module requires main thread initialization.
14
+ static func requiresMainQueueSetup() -> Bool {
15
+ true
16
+ }
17
+
18
+ /// Use `UIManager.addBlock` to enqueue module methods on UI thread.
19
+ var methodQueue: DispatchQueue! {
20
+ bridge.uiManager.methodQueue
21
+ }
22
+
23
+ /// In-memory mapping from `nativeId`s to `FullscreenHandler` instances.
24
+ private var fullscreenHandlers: Registry<FullscreenHandlerBridge> = [:]
25
+
26
+ /// Dispatch group used for blocking thread while waiting for state change
27
+ private let fullscreenChangeDispatchGroup = DispatchGroup()
28
+
29
+ /**
30
+ Fetches the `FullscreenHandlerBridge` instance associated with `nativeId` from internal fullscreenHandlers.
31
+ - Parameter nativeId: `FullscreenHandlerBridge` instance ID.
32
+ - Returns: The associated `FullscreenHandlerBridge` instance or `nil`.
33
+ */
34
+ @objc func retrieve(_ nativeId: NativeId) -> FullscreenHandlerBridge? {
35
+ fullscreenHandlers[nativeId]
36
+ }
37
+
38
+ /**
39
+ Removes the `FullscreenHandlerBridge` instance associated with `nativeId` from `fullscreenHandlers`.
40
+ - Parameter nativeId Instance to be disposed.
41
+ */
42
+ @objc(destroy:)
43
+ func destroy(_ nativeId: NativeId) {
44
+ fullscreenHandlers.removeValue(forKey: nativeId)
45
+ }
46
+
47
+ @objc(onFullscreenChanged:isFullscreenEnabled:)
48
+ func onFullscreenChanged(_ nativeId: NativeId, isFullscreenEnabled: Bool) -> Any? {
49
+ fullscreenHandlers[nativeId]?.isFullscreen = isFullscreenEnabled
50
+ fullscreenChangeDispatchGroup.leave()
51
+ return nil
52
+ }
53
+
54
+ @objc(registerHandler:)
55
+ func registerHandler(_ nativeId: NativeId) {
56
+ guard fullscreenHandlers[nativeId] == nil else { return }
57
+ fullscreenHandlers[nativeId] = FullscreenHandlerBridge(nativeId, bridge: bridge)
58
+ }
59
+
60
+ func onFullscreenRequested(nativeId: NativeId) {
61
+ fullscreenChangeDispatchGroup.enter()
62
+ bridge.enqueueJSCall("FullscreenBridge-\(nativeId)", method: "enterFullscreen", args: []) {}
63
+ fullscreenChangeDispatchGroup.wait()
64
+ }
65
+
66
+ func onFullscreenExitRequested(nativeId: NativeId) {
67
+ fullscreenChangeDispatchGroup.enter()
68
+ bridge.enqueueJSCall("FullscreenBridge-\(nativeId)", method: "exitFullscreen", args: []) {}
69
+ fullscreenChangeDispatchGroup.wait()
70
+ }
71
+ }
@@ -53,5 +53,11 @@ RCT_EXTERN_METHOD(
53
53
  getAvailableSubtitles:(NSString *)nativeId
54
54
  resolver:(RCTPromiseResolveBlock)resolve
55
55
  rejecter:(RCTPromiseRejectBlock)reject)
56
+ RCT_EXTERN_METHOD(scheduleAd:(NSString *)nativeId adItemJson:(nullable id)adItemJson)
57
+ RCT_EXTERN_METHOD(skipAd:(NSString *)nativeId)
58
+ RCT_EXTERN_METHOD(
59
+ isAd:(NSString *)nativeId
60
+ resolver:(RCTPromiseResolveBlock)resolve
61
+ rejecter:(RCTPromiseRejectBlock)reject)
56
62
 
57
63
  @end
@@ -346,4 +346,48 @@ class PlayerModule: NSObject, RCTBridgeModule {
346
346
  resolve(subtitlesJson ?? [])
347
347
  }
348
348
  }
349
+
350
+ /**
351
+ Schedules an `AdItem` in the `nativeId`'s associated player.
352
+ - Parameter nativeId: Target player id.
353
+ - Parameter adItemJson: Json representation of the `AdItem` to be scheduled.
354
+ */
355
+ @objc(scheduleAd:adItemJson:)
356
+ func scheduleAd(_ nativeId: NativeId, adItemJson: Any?) {
357
+ guard let adItem = RCTConvert.adItem(adItemJson) else {
358
+ return
359
+ }
360
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
361
+ self?.players[nativeId]?.scheduleAd(adItem: adItem)
362
+ }
363
+ }
364
+
365
+ /**
366
+ Skips the current ad in `nativeId`'s associated player.
367
+ Has no effect if the current ad is not skippable or if no ad is being played back.
368
+ - Parameter nativeId: Target player id.
369
+ */
370
+ @objc(skipAd:)
371
+ func skipAd(_ nativeId: NativeId) {
372
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
373
+ self?.players[nativeId]?.skipAd()
374
+ }
375
+ }
376
+
377
+ /**
378
+ Returns `true` while an ad is being played back or when main content playback has been paused for ad playback.
379
+ - Parameter nativeId: Target player id.
380
+ - Parameter resolver: JS promise resolver.
381
+ - Parameter rejecter: JS promise rejecter.
382
+ */
383
+ @objc(isAd:resolver:rejecter:)
384
+ func isAd(
385
+ _ nativeId: NativeId,
386
+ resolver resolve: @escaping RCTPromiseResolveBlock,
387
+ rejecter reject: @escaping RCTPromiseRejectBlock
388
+ ) {
389
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
390
+ resolve(self?.players[nativeId]?.isAd)
391
+ }
392
+ }
349
393
  }