@jwplayer/jwplayer-react-native 1.0.2 → 1.0.3

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.
@@ -85,6 +85,8 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
85
85
  @objc var onCasting: RCTDirectEventBlock?
86
86
  @objc var onCastingEnded: RCTDirectEventBlock?
87
87
  @objc var onCastingFailed: RCTDirectEventBlock?
88
+ @objc var onCaptionsChanged: RCTDirectEventBlock?
89
+ @objc var onCaptionsList: RCTDirectEventBlock?
88
90
 
89
91
  init() {
90
92
  super.init(frame: CGRect(x: 20, y: 0, width: UIScreen.main.bounds.width - 40, height: 300))
@@ -299,7 +301,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
299
301
  }
300
302
 
301
303
  if backgroundAudioEnabled || pipEnabled {
302
- let category = config["category"] as? String
304
+ let category = config["category"] != nil ? config["category"] as? String : "playback" // default category for playback
303
305
  let categoryOptions = config["categoryOptions"] as? [String]
304
306
  let mode = config["mode"] as? String
305
307
 
@@ -960,12 +962,12 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
960
962
  }
961
963
 
962
964
  func jwplayer(_ player:JWPlayer, failedWithError code:UInt, message:String) {
963
- self.onPlayerError?(["error": message])
965
+ self.onPlayerError?(["error": message, "errorCode": code])
964
966
  playerFailed = true
965
967
  }
966
968
 
967
969
  func jwplayer(_ player:JWPlayer, failedWithSetupError code:UInt, message:String) {
968
- self.onSetupPlayerError?(["error": message])
970
+ self.onSetupPlayerError?(["errorMessage": message, "errorCode": code])
969
971
  playerFailed = true
970
972
  }
971
973
 
@@ -979,7 +981,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
979
981
 
980
982
 
981
983
  func jwplayer(_ player:JWPlayer, encounteredAdWarning code:UInt, message:String) {
982
- self.onPlayerAdWarning?(["warning": message])
984
+ self.onPlayerAdWarning?(["warning": message, "code": code])
983
985
  }
984
986
 
985
987
 
@@ -1179,10 +1181,6 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
1179
1181
 
1180
1182
  // MARK: - JWPlayer State Delegate
1181
1183
 
1182
- func jwplayerContentIsBuffering(_ player:JWPlayer) {
1183
- self.onBuffer?([:])
1184
- }
1185
-
1186
1184
  func jwplayer(_ player:JWPlayer, isBufferingWithReason reason:JWBufferReason) {
1187
1185
  self.onBuffer?([:])
1188
1186
  }
@@ -1233,6 +1231,10 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
1233
1231
  func jwplayerContentDidComplete(_ player:JWPlayer) {
1234
1232
  self.onComplete?([:])
1235
1233
  }
1234
+
1235
+ func jwplayerContentIsBuffering(_ player: any JWPlayerKit.JWPlayer) {
1236
+
1237
+ }
1236
1238
 
1237
1239
  func jwplayer(_ player:JWPlayer, didLoadPlaylistItem item:JWPlayerItem, at index:UInt) {
1238
1240
  // var sourceDict: [String: Any] = [:]
@@ -1400,7 +1402,7 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
1400
1402
  }
1401
1403
 
1402
1404
  func jwplayer(_ player:JWPlayer, captionTrackChanged index:Int) {
1403
-
1405
+ self.onCaptionsChanged?(["index": index])
1404
1406
  }
1405
1407
 
1406
1408
  func jwplayer(_ player: JWPlayer, visualQualityChanged currentVisualQuality: JWVisualQuality) {
@@ -1416,7 +1418,15 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
1416
1418
  }
1417
1419
 
1418
1420
  func jwplayer(_ player:JWPlayer, updatedCaptionList options:[JWMediaSelectionOption]) {
1419
-
1421
+ var tracks: [[String: Any]] = []
1422
+ for track in player.captionsTracks {
1423
+ var dict: [String: Any] = [:]
1424
+ dict["label"] = track.name
1425
+ dict["default"] = track.defaultOption
1426
+ tracks.append(dict)
1427
+ }
1428
+ let currentIndex = player.currentCaptionsTrack
1429
+ self.onCaptionsList?(["index": currentIndex, "tracks": tracks])
1420
1430
  }
1421
1431
 
1422
1432
  // MARK: - JWPlayer audio session && interruption handling
@@ -1518,29 +1528,32 @@ class RNJWPlayerView : UIView, JWPlayerDelegate, JWPlayerStateDelegate, JWAdDele
1518
1528
  }
1519
1529
 
1520
1530
  var options: AVAudioSession.CategoryOptions = []
1521
- if categoryOptions.contains("MixWithOthers") {
1522
- options.insert(.mixWithOthers)
1523
- }
1524
- if categoryOptions.contains("DuckOthers") {
1525
- options.insert(.duckOthers)
1526
- }
1527
- if categoryOptions.contains("AllowBluetooth") {
1528
- options.insert(.allowBluetooth)
1529
- }
1530
- if categoryOptions.contains("InterruptSpokenAudioAndMix") {
1531
- options.insert(.interruptSpokenAudioAndMixWithOthers)
1532
- }
1533
- if categoryOptions.contains("AllowBluetoothA2DP") {
1534
- options.insert(.allowBluetoothA2DP)
1535
- }
1536
- if categoryOptions.contains("AllowAirPlay") {
1537
- options.insert(.allowAirPlay)
1538
- }
1539
- if categoryOptions.contains("OverrideMutedMicrophone") {
1540
- if #available(iOS 14.5, *) {
1541
- options.insert(.overrideMutedMicrophoneInterruption)
1542
- } else {
1543
- // Handle the case for earlier versions if needed
1531
+ // If the user doesn't specify any options
1532
+ if categoryOptions != nil {
1533
+ if categoryOptions.contains("MixWithOthers") {
1534
+ options.insert(.mixWithOthers)
1535
+ }
1536
+ if categoryOptions.contains("DuckOthers") {
1537
+ options.insert(.duckOthers)
1538
+ }
1539
+ if categoryOptions.contains("AllowBluetooth") {
1540
+ options.insert(.allowBluetooth)
1541
+ }
1542
+ if categoryOptions.contains("InterruptSpokenAudioAndMix") {
1543
+ options.insert(.interruptSpokenAudioAndMixWithOthers)
1544
+ }
1545
+ if categoryOptions.contains("AllowBluetoothA2DP") {
1546
+ options.insert(.allowBluetoothA2DP)
1547
+ }
1548
+ if categoryOptions.contains("AllowAirPlay") {
1549
+ options.insert(.allowAirPlay)
1550
+ }
1551
+ if categoryOptions.contains("OverrideMutedMicrophone") {
1552
+ if #available(iOS 14.5, *) {
1553
+ options.insert(.overrideMutedMicrophoneInterruption)
1554
+ } else {
1555
+ // Handle the case for earlier versions if needed
1556
+ }
1544
1557
  }
1545
1558
  }
1546
1559
 
@@ -55,13 +55,13 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
55
55
 
56
56
  override func jwplayer(_ player:JWPlayer, failedWithError code:UInt, message:String) {
57
57
  super.jwplayer(player, failedWithError:code, message:message)
58
- parentView?.onPlayerError?(["error": message])
58
+ parentView?.onPlayerError?(["error": message, "errorCode": code])
59
59
  parentView?.playerFailed = true
60
60
  }
61
61
 
62
62
  override func jwplayer(_ player:JWPlayer, failedWithSetupError code:UInt, message:String) {
63
63
  super.jwplayer(player, failedWithSetupError:code, message:message)
64
- parentView?.onSetupPlayerError?(["error": message])
64
+ parentView?.onSetupPlayerError?(["errorMessage": message, "errorCode": code])
65
65
  parentView?.playerFailed = true
66
66
  }
67
67
 
@@ -78,7 +78,7 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
78
78
 
79
79
  override func jwplayer(_ player:JWPlayer, encounteredAdWarning code:UInt, message:String) {
80
80
  super.jwplayer(player, encounteredAdWarning:code, message:message)
81
- parentView?.onPlayerAdWarning?(["warning": message])
81
+ parentView?.onPlayerAdWarning?(["warning": message, "code": code])
82
82
  }
83
83
 
84
84
 
@@ -263,11 +263,6 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
263
263
 
264
264
  // MARK: - JWPlayer State Delegate
265
265
 
266
- override func jwplayerContentIsBuffering(_ player:JWPlayer) {
267
- super.jwplayerContentIsBuffering(player)
268
- parentView?.onBuffer?([:])
269
- }
270
-
271
266
  override func jwplayer(_ player:JWPlayer, isBufferingWithReason reason:JWBufferReason) {
272
267
  super.jwplayer(player, isBufferingWithReason:reason)
273
268
  parentView?.onBuffer?([:])
@@ -588,6 +583,7 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
588
583
 
589
584
  override func jwplayer(_ player:JWPlayer, captionTrackChanged index:Int) {
590
585
  super.jwplayer(player, captionTrackChanged:index)
586
+ parentView.onCaptionsChanged?(["index": index])
591
587
  }
592
588
 
593
589
  override func jwplayer(_ player:JWPlayer, qualityLevelChanged currentLevel:Int) {
@@ -600,6 +596,16 @@ class RNJWPlayerViewController : JWPlayerViewController, JWPlayerViewControllerD
600
596
 
601
597
  override func jwplayer(_ player:JWPlayer, updatedCaptionList options:[JWMediaSelectionOption]) {
602
598
  super.jwplayer(player, updatedCaptionList:options)
599
+
600
+ var tracks: [[String: Any]] = []
601
+ for track in player.captionsTracks {
602
+ var dict: [String: Any] = [:]
603
+ dict["label"] = track.name
604
+ dict["default"] = track.defaultOption
605
+ tracks.append(dict)
606
+ }
607
+ let currentIndex = player.currentCaptionsTrack
608
+ parentView.onCaptionsList?(["index": currentIndex, "tracks": tracks])
603
609
  }
604
610
 
605
611
  override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
@@ -32,6 +32,8 @@ RCT_EXPORT_VIEW_PROPERTY(onPlaylistItem, RCTDirectEventBlock);
32
32
 
33
33
  /* av events */
34
34
  RCT_EXPORT_VIEW_PROPERTY(onAudioTracks, RCTDirectEventBlock);
35
+ RCT_EXPORT_VIEW_PROPERTY(onCaptionsChanged, RCTDirectEventBlock);
36
+ RCT_EXPORT_VIEW_PROPERTY(onCaptionsList, RCTDirectEventBlock);
35
37
 
36
38
  /* player events */
37
39
  RCT_EXPORT_VIEW_PROPERTY(onPlayerReady, RCTDirectEventBlock);
@@ -121,7 +123,7 @@ RCT_EXTERN_METHOD(setLockScreenControls: (nonnull NSNumber *)reactTag: (BOOL)sho
121
123
 
122
124
  RCT_EXTERN_METHOD(setCurrentCaptions: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
123
125
 
124
- RCT_EXTERN_METHOD(setCurrentCaptions: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
126
+ RCT_EXTERN_METHOD(getCurrentCaptions: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
125
127
 
126
128
  RCT_EXTERN_METHOD(setLicenseKey: (nonnull NSNumber *)reactTag: (nonnull NSString *)license)
127
129
 
@@ -131,6 +133,8 @@ RCT_EXTERN_METHOD(reset)
131
133
 
132
134
  RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSArray *)playlist)
133
135
 
136
+ RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSString *)playlist)
137
+
134
138
  RCT_EXTERN_METHOD(setFullscreen: (nonnull NSNumber *)reactTag: (BOOL)fullscreen)
135
139
 
136
140
  @end
@@ -412,10 +412,33 @@ class RNJWPlayerViewManager: RCTViewManager {
412
412
  return
413
413
  }
414
414
 
415
+ do {
416
+ if let playerView = view.playerView {
417
+ try playerView.player.setCaptionTrack(index: index.intValue)
418
+ } else if let playerViewController = view.playerViewController {
419
+ try playerViewController.player.setCaptionTrack(index: index.intValue)
420
+ }
421
+ } catch {
422
+ print("Error setting caption track: \(error)")
423
+ }
424
+ }
425
+ }
426
+
427
+ @objc func getCurrentCaptions(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
428
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
429
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
430
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
431
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
432
+ return
433
+ }
434
+
415
435
  if let playerView = view.playerView {
416
- playerView.player.currentCaptionsTrack = index.intValue + 1
436
+ resolve(NSNumber(value: playerView.player.currentCaptionsTrack))
417
437
  } else if let playerViewController = view.playerViewController {
418
- playerViewController.player.currentCaptionsTrack = index.intValue + 1
438
+ resolve(NSNumber(value: playerViewController.player.currentCaptionsTrack))
439
+ } else {
440
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
441
+ reject("no_player", "There is no player", error)
419
442
  }
420
443
  }
421
444
  }
@@ -457,7 +480,7 @@ class RNJWPlayerViewManager: RCTViewManager {
457
480
  }
458
481
  }
459
482
 
460
- @objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: [Any]) {
483
+ @objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: Any) {
461
484
  self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
462
485
  guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
463
486
  print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
@@ -466,17 +489,28 @@ class RNJWPlayerViewManager: RCTViewManager {
466
489
 
467
490
  var playlistArray = [JWPlayerItem]()
468
491
 
469
- for item in playlist {
470
- if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
471
- playlistArray.append(playerItem)
492
+ if playlist is NSArray {
493
+ for item in playlist as! [Any] {
494
+ // TODO Update this to better parse JWP Playlist Items:
495
+ // awaiting JWP SDK exposure of JWJSONParser.playlist
496
+ if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
497
+ playlistArray.append(playerItem)
498
+ }
499
+ }
500
+
501
+ if let playerView = view.playerView {
502
+ playerView.player.loadPlaylist(items: playlistArray)
503
+ } else if let playerViewController = view.playerViewController {
504
+ playerViewController.player.loadPlaylist(items: playlistArray)
505
+ }
506
+ } else {
507
+ if let playerView = view.playerView {
508
+ playerView.player.loadPlaylist(url: URL(string: playlist as! String)!)
509
+ } else if let playerViewController = view.playerViewController {
510
+ playerViewController.player.loadPlaylist(url: URL(string: playlist as! String)!)
472
511
  }
473
512
  }
474
-
475
- if let playerView = view.playerView {
476
- playerView.player.loadPlaylist(items: playlistArray)
477
- } else if let playerViewController = view.playerViewController {
478
- playerViewController.player.loadPlaylist(items: playlistArray)
479
- }
513
+
480
514
  }
481
515
  }
482
516
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwplayer/jwplayer-react-native",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "React-native Android/iOS plugin for JWPlayer SDK (https://www.jwplayer.com/)",
5
5
  "main": "index.js",
6
6
  "types": "./index.d.ts",