@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.
- package/README.md +1 -0
- package/RNJWPlayer.podspec +3 -3
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +510 -458
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +141 -24
- package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +8 -0
- package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +26 -7
- package/badges/version.svg +1 -1
- package/index.d.ts +36 -7
- package/index.js +18 -0
- package/ios/RNJWPlayer/RNJWPlayerView.swift +46 -33
- package/ios/RNJWPlayer/RNJWPlayerViewController.swift +14 -8
- package/ios/RNJWPlayer/RNJWPlayerViewManager.m +5 -1
- package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +46 -12
- package/jwplayer-jwplayer-react-native-1.0.3.tgz +0 -0
- package/package.json +1 -1
|
@@ -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?(["
|
|
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
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
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?(["
|
|
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(
|
|
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
|
|
436
|
+
resolve(NSNumber(value: playerView.player.currentCaptionsTrack))
|
|
417
437
|
} else if let playerViewController = view.playerViewController {
|
|
418
|
-
playerViewController.player.currentCaptionsTrack
|
|
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:
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
|
|
Binary file
|