@jwplayer/jwplayer-react-native 1.0.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 (61) hide show
  1. package/.github/CODEOWNERS +2 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/ISSUE_TEMPLATE/question.md +11 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  6. package/CODE_OF_CONDUCT.md +128 -0
  7. package/LICENSE +21 -0
  8. package/README.md +425 -0
  9. package/RNJWPlayer.podspec +44 -0
  10. package/android/.gradle/8.1.1/checksums/checksums.lock +0 -0
  11. package/android/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock +0 -0
  12. package/android/.gradle/8.1.1/dependencies-accessors/gc.properties +0 -0
  13. package/android/.gradle/8.1.1/fileChanges/last-build.bin +0 -0
  14. package/android/.gradle/8.1.1/fileHashes/fileHashes.lock +0 -0
  15. package/android/.gradle/8.1.1/gc.properties +0 -0
  16. package/android/.gradle/8.2/checksums/checksums.lock +0 -0
  17. package/android/.gradle/8.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  18. package/android/.gradle/8.2/dependencies-accessors/gc.properties +0 -0
  19. package/android/.gradle/8.2/fileChanges/last-build.bin +0 -0
  20. package/android/.gradle/8.2/fileHashes/fileHashes.lock +0 -0
  21. package/android/.gradle/8.2/gc.properties +0 -0
  22. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  23. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  24. package/android/.gradle/config.properties +2 -0
  25. package/android/.gradle/vcs-1/gc.properties +0 -0
  26. package/android/.idea/gradle.xml +12 -0
  27. package/android/.idea/migrations.xml +10 -0
  28. package/android/.idea/misc.xml +10 -0
  29. package/android/.idea/vcs.xml +6 -0
  30. package/android/.idea/workspace.xml +54 -0
  31. package/android/build.gradle +110 -0
  32. package/android/local.properties +8 -0
  33. package/android/src/main/AndroidManifest.xml +25 -0
  34. package/android/src/main/java/com/jwplayer/rnjwplayer/ArrayUtil.java +129 -0
  35. package/android/src/main/java/com/jwplayer/rnjwplayer/CastOptionsProvider.java +55 -0
  36. package/android/src/main/java/com/jwplayer/rnjwplayer/MapUtil.java +136 -0
  37. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayer.java +76 -0
  38. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerAds.java +239 -0
  39. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerModule.java +526 -0
  40. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerPackage.java +30 -0
  41. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerView.java +1499 -0
  42. package/android/src/main/java/com/jwplayer/rnjwplayer/RNJWPlayerViewManager.java +171 -0
  43. package/android/src/main/java/com/jwplayer/rnjwplayer/Util.java +219 -0
  44. package/android/src/main/java/com/jwplayer/rnjwplayer/WidevineCallback.java +62 -0
  45. package/badges/license.svg +1 -0
  46. package/badges/version.svg +1 -0
  47. package/docs/legacy_readme.md +634 -0
  48. package/docs/props.md +43 -0
  49. package/docs/types.md +254 -0
  50. package/index.d.ts +564 -0
  51. package/index.js +699 -0
  52. package/ios/RNJWPlayer/RCTConvert+RNJWPlayer.swift +119 -0
  53. package/ios/RNJWPlayer/RNJWPlayer-Bridging-Header.h +5 -0
  54. package/ios/RNJWPlayer/RNJWPlayerAds.swift +260 -0
  55. package/ios/RNJWPlayer/RNJWPlayerModels.swift +149 -0
  56. package/ios/RNJWPlayer/RNJWPlayerView.swift +1837 -0
  57. package/ios/RNJWPlayer/RNJWPlayerViewController.swift +616 -0
  58. package/ios/RNJWPlayer/RNJWPlayerViewManager.m +132 -0
  59. package/ios/RNJWPlayer/RNJWPlayerViewManager.swift +500 -0
  60. package/ios/RNJWPlayer.xcodeproj/project.pbxproj +323 -0
  61. package/package.json +45 -0
@@ -0,0 +1,132 @@
1
+ #if __has_include("React/RCTViewManager.h")
2
+ #import "React/RCTViewManager.h"
3
+ #else
4
+ #import "RCTViewManager.h"
5
+ #endif
6
+
7
+ #import <JWPlayerKit/JWPlayerKit-swift.h>
8
+
9
+ #import "RCTUIManager.h"
10
+
11
+ @interface RCT_EXTERN_MODULE(RNJWPlayerViewManager, RCTViewManager)
12
+
13
+ /* player state events */
14
+ RCT_EXPORT_VIEW_PROPERTY(onTime, RCTDirectEventBlock);
15
+ RCT_EXPORT_VIEW_PROPERTY(onLoaded, RCTDirectEventBlock);
16
+ RCT_EXPORT_VIEW_PROPERTY(onSeek, RCTDirectEventBlock);
17
+ RCT_EXPORT_VIEW_PROPERTY(onSeeked, RCTDirectEventBlock);
18
+ RCT_EXPORT_VIEW_PROPERTY(onRateChanged, RCTDirectEventBlock);
19
+ RCT_EXPORT_VIEW_PROPERTY(onPlaylist, RCTDirectEventBlock);
20
+ RCT_EXPORT_VIEW_PROPERTY(onPlaylistComplete, RCTDirectEventBlock);
21
+ RCT_EXPORT_VIEW_PROPERTY(onBeforeComplete, RCTDirectEventBlock);
22
+ RCT_EXPORT_VIEW_PROPERTY(onComplete, RCTDirectEventBlock);
23
+ RCT_EXPORT_VIEW_PROPERTY(onVisible, RCTDirectEventBlock);
24
+ RCT_EXPORT_VIEW_PROPERTY(onBeforePlay, RCTDirectEventBlock);
25
+ RCT_EXPORT_VIEW_PROPERTY(onAttemptPlay, RCTDirectEventBlock);
26
+ RCT_EXPORT_VIEW_PROPERTY(onPlay, RCTDirectEventBlock);
27
+ RCT_EXPORT_VIEW_PROPERTY(onPause, RCTDirectEventBlock);
28
+ RCT_EXPORT_VIEW_PROPERTY(onBuffer, RCTDirectEventBlock);
29
+ RCT_EXPORT_VIEW_PROPERTY(onUpdateBuffer, RCTDirectEventBlock);
30
+ RCT_EXPORT_VIEW_PROPERTY(onIdle, RCTDirectEventBlock);
31
+ RCT_EXPORT_VIEW_PROPERTY(onPlaylistItem, RCTDirectEventBlock);
32
+
33
+ /* av events */
34
+ RCT_EXPORT_VIEW_PROPERTY(onAudioTracks, RCTDirectEventBlock);
35
+
36
+ /* player events */
37
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerReady, RCTDirectEventBlock);
38
+ RCT_EXPORT_VIEW_PROPERTY(onSetupPlayerError, RCTDirectEventBlock);
39
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerError, RCTDirectEventBlock);
40
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerWarning, RCTDirectEventBlock);
41
+
42
+ /* ad events */
43
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerAdWarning, RCTDirectEventBlock);
44
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerAdError, RCTDirectEventBlock);
45
+ RCT_EXPORT_VIEW_PROPERTY(onAdEvent, RCTDirectEventBlock);
46
+ RCT_EXPORT_VIEW_PROPERTY(onAdTime, RCTDirectEventBlock);
47
+
48
+ /* jwplayer view controller events */
49
+ RCT_EXPORT_VIEW_PROPERTY(onControlBarVisible, RCTDirectEventBlock);
50
+ RCT_EXPORT_VIEW_PROPERTY(onScreenTapped, RCTDirectEventBlock);
51
+ RCT_EXPORT_VIEW_PROPERTY(onFullScreen, RCTDirectEventBlock);
52
+ RCT_EXPORT_VIEW_PROPERTY(onFullScreenRequested, RCTDirectEventBlock);
53
+ RCT_EXPORT_VIEW_PROPERTY(onFullScreenExit, RCTDirectEventBlock);
54
+ RCT_EXPORT_VIEW_PROPERTY(onFullScreenExitRequested, RCTDirectEventBlock);
55
+
56
+ /* jwplayer view events */
57
+ RCT_EXPORT_VIEW_PROPERTY(onPlayerSizeChange, RCTDirectEventBlock);
58
+
59
+ /* casting events */
60
+ RCT_EXPORT_VIEW_PROPERTY(onCastingDevicesAvailable, RCTDirectEventBlock);
61
+ RCT_EXPORT_VIEW_PROPERTY(onConnectedToCastingDevice, RCTDirectEventBlock);
62
+ RCT_EXPORT_VIEW_PROPERTY(onDisconnectedFromCastingDevice, RCTDirectEventBlock);
63
+ RCT_EXPORT_VIEW_PROPERTY(onConnectionTemporarilySuspended, RCTDirectEventBlock);
64
+ RCT_EXPORT_VIEW_PROPERTY(onConnectionRecovered, RCTDirectEventBlock);
65
+ RCT_EXPORT_VIEW_PROPERTY(onConnectionFailed, RCTDirectEventBlock);
66
+ RCT_EXPORT_VIEW_PROPERTY(onCasting, RCTDirectEventBlock);
67
+ RCT_EXPORT_VIEW_PROPERTY(onCastingEnded, RCTDirectEventBlock);
68
+ RCT_EXPORT_VIEW_PROPERTY(onCastingFailed, RCTDirectEventBlock);
69
+
70
+ /* props */
71
+ RCT_EXPORT_VIEW_PROPERTY(config, NSDictionary);
72
+ RCT_EXPORT_VIEW_PROPERTY(controls, BOOL);
73
+
74
+ RCT_EXTERN_METHOD(state: (nonnull NSNumber*) reactTag: (RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
75
+
76
+ RCT_EXTERN_METHOD(pause: (nonnull NSNumber*)reactTag)
77
+
78
+ RCT_EXTERN_METHOD(play: (nonnull NSNumber *)reactTag)
79
+
80
+ RCT_EXTERN_METHOD(stop: (nonnull NSNumber *)reactTag)
81
+
82
+ RCT_EXTERN_METHOD(position: (nonnull NSNumber *)reactTag: (RCTPromiseResolveBlock)resolve: (RCTPromiseRejectBlock)reject)
83
+
84
+ RCT_EXTERN_METHOD(toggleSpeed: (nonnull NSNumber*)reactTag)
85
+
86
+ RCT_EXTERN_METHOD(setSpeed: (nonnull NSNumber*)reactTag: (double)speed)
87
+
88
+ RCT_EXTERN_METHOD(setPlaylistIndex: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
89
+
90
+ RCT_EXTERN_METHOD(seekTo: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)time)
91
+
92
+ RCT_EXTERN_METHOD(setVolume: (nonnull NSNumber *)reactTag :(nonnull NSNumber *)volume)
93
+
94
+ RCT_EXTERN_METHOD(togglePIP: (nonnull NSNumber *)reactTag)
95
+
96
+ RCT_EXTERN_METHOD(setUpCastController: (nonnull NSNumber *)reactTag)
97
+
98
+ RCT_EXTERN_METHOD(presentCastDialog: (nonnull NSNumber *)reactTag)
99
+
100
+ RCT_EXTERN_METHOD(connectedDevice: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
101
+
102
+ RCT_EXTERN_METHOD(availableDevices: (nonnull NSNumber *)reactTag: (RCTPromiseResolveBlock)resolve: (RCTPromiseRejectBlock)reject)
103
+
104
+ RCT_EXTERN_METHOD(castState: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
105
+
106
+ RCT_EXTERN_METHOD(getAudioTracks: (nonnull NSNumber *)reactTag: (RCTPromiseResolveBlock)resolve: (RCTPromiseRejectBlock)reject)
107
+
108
+ RCT_EXTERN_METHOD(getCurrentAudioTrack: (nonnull NSNumber *)reactTag :(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
109
+
110
+ RCT_EXTERN_METHOD(setCurrentAudioTrack: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
111
+
112
+ RCT_EXTERN_METHOD(setControls: (nonnull NSNumber *)reactTag: (BOOL)show)
113
+
114
+ RCT_EXTERN_METHOD(setVisibility: (nonnull NSNumber *)reactTag: (BOOL)visibilty: (nonnull NSArray *)controls)
115
+
116
+ RCT_EXTERN_METHOD(setLockScreenControls: (nonnull NSNumber *)reactTag: (BOOL)show)
117
+
118
+ RCT_EXTERN_METHOD(setCurrentCaptions: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
119
+
120
+ RCT_EXTERN_METHOD(setCurrentCaptions: (nonnull NSNumber *)reactTag: (nonnull NSNumber *)index)
121
+
122
+ RCT_EXTERN_METHOD(setLicenseKey: (nonnull NSNumber *)reactTag: (nonnull NSString *)license)
123
+
124
+ RCT_EXTERN_METHOD(quite)
125
+
126
+ RCT_EXTERN_METHOD(reset)
127
+
128
+ RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSArray *)playlist)
129
+
130
+ RCT_EXTERN_METHOD(setFullscreen: (nonnull NSNumber *)reactTag: (BOOL)fullscreen)
131
+
132
+ @end
@@ -0,0 +1,500 @@
1
+ import AVFoundation
2
+ import React
3
+ import JWPlayerKit
4
+
5
+ @objc(RNJWPlayerViewManager)
6
+ class RNJWPlayerViewManager: RCTViewManager {
7
+
8
+ override func view() -> UIView {
9
+ return RNJWPlayerView()
10
+ }
11
+
12
+ func methodQueue() -> DispatchQueue {
13
+ return bridge.uiManager.methodQueue
14
+ }
15
+
16
+ override class func requiresMainQueueSetup() -> Bool {
17
+ return true
18
+ }
19
+
20
+ @objc func state(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
21
+ self.bridge.uiManager.addUIBlock { (_, viewRegistry) in
22
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
23
+ let error = NSError(domain: "", code: 0, userInfo: nil)
24
+ reject("no_player", "There is no playerViewController or playerView", error)
25
+ return
26
+ }
27
+
28
+ if let playerViewController = view.playerViewController {
29
+ resolve(NSNumber(value: playerViewController.player.getState().rawValue))
30
+ } else if let playerView = view.playerView {
31
+ resolve(NSNumber(value: playerView.player.getState().rawValue))
32
+ } else {
33
+ let error = NSError(domain: "", code: 0, userInfo: nil)
34
+ reject("no_player", "There is no playerView", error)
35
+ }
36
+ }
37
+ }
38
+
39
+ @objc func pause(_ reactTag: NSNumber) {
40
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
41
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
42
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
43
+ return
44
+ }
45
+
46
+ view.userPaused = true
47
+ if let playerView = view.playerView {
48
+ playerView.player.pause()
49
+ } else if let playerViewController = view.playerViewController {
50
+ playerViewController.player.pause()
51
+ }
52
+ }
53
+ }
54
+
55
+ @objc func play(_ reactTag: NSNumber) {
56
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
57
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
58
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
59
+ return
60
+ }
61
+
62
+ if let playerView = view.playerView {
63
+ playerView.player.play()
64
+ } else if let playerViewController = view.playerViewController {
65
+ playerViewController.player.play()
66
+ }
67
+ }
68
+ }
69
+
70
+ @objc func stop(_ reactTag: NSNumber) {
71
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
72
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
73
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
74
+ return
75
+ }
76
+
77
+ view.userPaused = true
78
+ if let playerView = view.playerView {
79
+ playerView.player.stop()
80
+ } else if let playerViewController = view.playerViewController {
81
+ playerViewController.player.stop()
82
+ }
83
+ }
84
+ }
85
+
86
+ @objc func position(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
87
+ print("position")
88
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
89
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
90
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no playerView"])
91
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
92
+ return
93
+ }
94
+
95
+ if let playerView = view.playerView {
96
+ resolve(playerView.player.time.position as NSNumber)
97
+ } else if let playerViewController = view.playerViewController {
98
+ resolve(playerViewController.player.time.position as NSNumber)
99
+ } else {
100
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no playerView"])
101
+ reject("no_player", "There is no playerView", error)
102
+ }
103
+ }
104
+ }
105
+
106
+ @objc func toggleSpeed(_ reactTag: NSNumber) {
107
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
108
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
109
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
110
+ return
111
+ }
112
+
113
+ if let playerView = view.playerView {
114
+ if playerView.player.playbackRate < 2.0 {
115
+ playerView.player.playbackRate += 0.5
116
+ } else {
117
+ playerView.player.playbackRate = 0.5
118
+ }
119
+ } else if let playerViewController = view.playerViewController {
120
+ if playerViewController.player.playbackRate < 2.0 {
121
+ playerViewController.player.playbackRate += 0.5
122
+ } else {
123
+ playerViewController.player.playbackRate = 0.5
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ @objc func setSpeed(_ reactTag: NSNumber, _ speed: Double) {
130
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
131
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
132
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
133
+ return
134
+ }
135
+
136
+ if let playerView = view.playerView {
137
+ playerView.player.playbackRate = speed
138
+ } else if let playerViewController = view.playerViewController {
139
+ playerViewController.player.playbackRate = speed
140
+ }
141
+ }
142
+ }
143
+
144
+ @objc func setPlaylistIndex(_ reactTag: NSNumber, _ index: NSNumber) {
145
+ print("SET PLAY LIST INDEX")
146
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
147
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
148
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
149
+ return
150
+ }
151
+
152
+ if let playerView = view.playerView {
153
+ playerView.player.loadPlayerItemAt(index: index.intValue)
154
+ } else if let playerViewController = view.playerViewController {
155
+ playerViewController.player.loadPlayerItemAt(index: index.intValue)
156
+ }
157
+ }
158
+ }
159
+
160
+ @objc func seekTo(_ reactTag: NSNumber, _ time: NSNumber) {
161
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
162
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
163
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
164
+ return
165
+ }
166
+
167
+ if let playerView = view.playerView {
168
+ playerView.player.seek(to: TimeInterval(time.intValue))
169
+ } else if let playerViewController = view.playerViewController {
170
+ playerViewController.player.seek(to: TimeInterval(time.intValue))
171
+ }
172
+ }
173
+ }
174
+
175
+ @objc func setVolume(_ reactTag: NSNumber, _ volume: Double) {
176
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
177
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
178
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
179
+ return
180
+ }
181
+
182
+ if let playerView = view.playerView {
183
+ playerView.player.volume = volume
184
+ } else if let playerViewController = view.playerViewController {
185
+ playerViewController.player.volume = volume
186
+ }
187
+ }
188
+ }
189
+
190
+
191
+ @objc func togglePIP(_ reactTag: NSNumber) {
192
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
193
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView, let pipController = view.playerView?.pictureInPictureController else {
194
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
195
+ return
196
+ }
197
+
198
+ if pipController.isPictureInPicturePossible {
199
+ if pipController.isPictureInPictureActive {
200
+ pipController.stopPictureInPicture()
201
+ } else {
202
+ pipController.startPictureInPicture()
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ @objc func setUpCastController(_ reactTag: NSNumber) {
209
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
210
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
211
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
212
+ return
213
+ }
214
+
215
+ view.setUpCastController()
216
+ }
217
+ }
218
+
219
+ @objc func presentCastDialog(_ reactTag: NSNumber) {
220
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
221
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
222
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
223
+ return
224
+ }
225
+
226
+ view.presentCastDialog()
227
+ }
228
+ }
229
+
230
+ @objc func connectedDevice(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
231
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
232
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
233
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
234
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
235
+ return
236
+ }
237
+
238
+ if let device = view.connectedDevice() {
239
+ var dict = [String: Any]()
240
+ dict["name"] = device.name
241
+ dict["identifier"] = device.identifier
242
+
243
+ do {
244
+ let data = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
245
+ resolve(String(data: data, encoding: .utf8))
246
+ } catch {
247
+ reject("json_error", "Failed to serialize JSON", error)
248
+ }
249
+ } else {
250
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no connected device"])
251
+ reject("no_connected_device", "There is no connected device", error)
252
+ }
253
+ }
254
+ }
255
+
256
+ @objc func availableDevices(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
257
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
258
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
259
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
260
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
261
+ return
262
+ }
263
+
264
+ if let availableDevices = view.getAvailableDevices() {
265
+ var devicesInfo: [[String: Any]] = []
266
+
267
+ for device in availableDevices {
268
+ var dict = [String: Any]()
269
+ dict["name"] = device.name
270
+ dict["identifier"] = device.identifier
271
+ devicesInfo.append(dict)
272
+ }
273
+
274
+ do {
275
+ let data = try JSONSerialization.data(withJSONObject: devicesInfo, options: .prettyPrinted)
276
+ resolve(String(data: data, encoding: .utf8))
277
+ } catch {
278
+ reject("json_error", "Failed to serialize JSON", error)
279
+ }
280
+ } else {
281
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There are no available devices"])
282
+ reject("no_available_device", "There are no available devices", error)
283
+ }
284
+ }
285
+ }
286
+
287
+ @objc func castState(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
288
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
289
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
290
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
291
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
292
+ return
293
+ }
294
+
295
+ resolve(view.castState)
296
+ }
297
+ }
298
+
299
+ @objc func getAudioTracks(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
300
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
301
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
302
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
303
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
304
+ return
305
+ }
306
+
307
+ let audioTracks: [Any]? = view.playerView?.player.audioTracks ?? view.playerViewController?.player.audioTracks
308
+
309
+ if let audioTracks = audioTracks as? [[String: Any]] {
310
+ var results: [[String: Any]] = []
311
+ for track in audioTracks {
312
+ if let language = track["language"], let autoSelect = track["autoselect"],
313
+ let defaultTrack = track["defaulttrack"], let name = track["name"],
314
+ let groupId = track["groupid"] {
315
+ let trackDict: [String: Any] = [
316
+ "language": language,
317
+ "autoSelect": autoSelect,
318
+ "defaultTrack": defaultTrack,
319
+ "name": name,
320
+ "groupId": groupId
321
+ ]
322
+ results.append(trackDict)
323
+ }
324
+ }
325
+ resolve(results)
326
+ } else {
327
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There are no audio tracks"])
328
+ reject("no_audio_tracks", "There are no audio tracks", error)
329
+ }
330
+ }
331
+ }
332
+
333
+ @objc func getCurrentAudioTrack(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
334
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
335
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
336
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
337
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
338
+ return
339
+ }
340
+
341
+ if let playerView = view.playerView {
342
+ resolve(NSNumber(value: playerView.player.currentAudioTrack))
343
+ } else if let playerViewController = view.playerViewController {
344
+ resolve(NSNumber(value: playerViewController.player.currentAudioTrack))
345
+ } else {
346
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
347
+ reject("no_player", "There is no player", error)
348
+ }
349
+ }
350
+ }
351
+
352
+ @objc func setCurrentAudioTrack(_ reactTag: NSNumber, _ index: NSNumber) {
353
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
354
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
355
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
356
+ return
357
+ }
358
+
359
+ if let playerView = view.playerView {
360
+ playerView.player.currentAudioTrack = index.intValue
361
+ } else if let playerViewController = view.playerViewController {
362
+ playerViewController.player.currentAudioTrack = index.intValue
363
+ }
364
+ }
365
+ }
366
+
367
+ @objc func setControls(_ reactTag: NSNumber, _ show: Bool) {
368
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
369
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
370
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
371
+ return
372
+ }
373
+
374
+ if let playerViewController = view.playerViewController {
375
+ view.toggleUIGroup(view: playerViewController.view, name: "JWPlayerKit.InterfaceView", ofSubview: nil, show: show)
376
+ }
377
+ }
378
+ }
379
+
380
+ @objc func setVisibility(_ reactTag: NSNumber, _ visibility: Bool, _ controls: [String]) {
381
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
382
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
383
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
384
+ return
385
+ }
386
+
387
+ if view.playerViewController != nil {
388
+ view.setVisibility(isVisible: visibility, forControls: controls)
389
+ }
390
+ }
391
+ }
392
+
393
+ @objc func setLockScreenControls(_ reactTag: NSNumber, _ show: Bool) {
394
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
395
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
396
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
397
+ return
398
+ }
399
+
400
+ if let playerViewController = view.playerViewController {
401
+ playerViewController.enableLockScreenControls = show
402
+ }
403
+ }
404
+ }
405
+
406
+ @objc func setCurrentCaptions(_ reactTag: NSNumber, _ index: NSNumber) {
407
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
408
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
409
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
410
+ return
411
+ }
412
+
413
+ if let playerView = view.playerView {
414
+ playerView.player.currentCaptionsTrack = index.intValue + 1
415
+ } else if let playerViewController = view.playerViewController {
416
+ playerViewController.player.currentCaptionsTrack = index.intValue + 1
417
+ }
418
+ }
419
+ }
420
+
421
+ @objc func setLicenseKey(_ reactTag: NSNumber, _ license: String) {
422
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
423
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
424
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
425
+ return
426
+ }
427
+
428
+ view.setLicense(license: license)
429
+ }
430
+ }
431
+
432
+ @objc func quite() {
433
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
434
+ for (_, view) in viewRegistry ?? [:] {
435
+ if let rnjwView = view as? RNJWPlayerView {
436
+ if let playerView = rnjwView.playerView {
437
+ playerView.player.pause()
438
+ playerView.player.stop()
439
+ } else if let playerViewController = rnjwView.playerViewController {
440
+ playerViewController.player.pause()
441
+ playerViewController.player.stop()
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+
448
+ @objc func reset() {
449
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
450
+ for (_, view) in viewRegistry ?? [:] {
451
+ if let rnjwView = view as? RNJWPlayerView {
452
+ rnjwView.startDeinitProcess()
453
+ }
454
+ }
455
+ }
456
+ }
457
+
458
+ @objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: [Any]) {
459
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
460
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
461
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
462
+ return
463
+ }
464
+
465
+ var playlistArray = [JWPlayerItem]()
466
+
467
+ for item in playlist {
468
+ if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
469
+ playlistArray.append(playerItem)
470
+ }
471
+ }
472
+
473
+ if let playerView = view.playerView {
474
+ playerView.player.loadPlaylist(items: playlistArray)
475
+ } else if let playerViewController = view.playerViewController {
476
+ playerViewController.player.loadPlaylist(items: playlistArray)
477
+ }
478
+ }
479
+ }
480
+
481
+ @objc func setFullscreen(_ reactTag: NSNumber, _ fullscreen: Bool) {
482
+ self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
483
+ guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
484
+ print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
485
+ return
486
+ }
487
+
488
+ if let playerViewController = view.playerViewController {
489
+ if fullscreen {
490
+ playerViewController.transitionToFullScreen(animated: true, completion: nil)
491
+ } else {
492
+ playerViewController.dismissFullScreen(animated: true, completion: nil)
493
+ }
494
+ } else {
495
+ print("Invalid view returned from registry, expecting RNJWPlayerViewController, got: \(view)")
496
+ }
497
+ }
498
+ }
499
+
500
+ }