@jwplayer/jwplayer-react-native 1.0.2 → 1.1.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.
@@ -16,15 +16,38 @@ class RNJWPlayerViewManager: RCTViewManager {
16
16
  override class func requiresMainQueueSetup() -> Bool {
17
17
  return true
18
18
  }
19
-
19
+
20
+ private func getPlayerView(reactTag: NSNumber) -> RNJWPlayerView? {
21
+ guard let bridge = self.bridge else {
22
+ print("❌ RNJWPlayerViewManager: Bridge is nil")
23
+ return nil
24
+ }
25
+
26
+ let uiManager = bridge.uiManager
27
+
28
+ // ✅ Check Fabric first (New Architecture)
29
+ if let view = uiManager?.view(forReactTag: reactTag) as? RNJWPlayerView {
30
+ return view
31
+ }
32
+
33
+ // ✅ Check Legacy (Old Architecture) and add explicit type annotation
34
+ if let viewRegistry = uiManager?.value(forKey: "viewRegistry") as? [NSNumber: UIView],
35
+ let view = viewRegistry[reactTag] as? RNJWPlayerView {
36
+ return view
37
+ }
38
+
39
+ print("❌ Invalid view returned for tag \(reactTag)")
40
+ return nil
41
+ }
42
+
20
43
  @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 {
44
+ DispatchQueue.main.async {
45
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
23
46
  let error = NSError(domain: "", code: 0, userInfo: nil)
24
47
  reject("no_player", "There is no playerViewController or playerView", error)
25
48
  return
26
49
  }
27
-
50
+
28
51
  if let playerViewController = view.playerViewController {
29
52
  resolve(NSNumber(value: playerViewController.player.getState().rawValue))
30
53
  } else if let playerView = view.playerView {
@@ -37,12 +60,12 @@ class RNJWPlayerViewManager: RCTViewManager {
37
60
  }
38
61
 
39
62
  @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]))")
63
+ DispatchQueue.main.async {
64
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
65
+ print(" Failed to pause: RNJWPlayerView not found for tag \(reactTag)")
43
66
  return
44
67
  }
45
-
68
+
46
69
  view.userPaused = true
47
70
  if let playerView = view.playerView {
48
71
  playerView.player.pause()
@@ -53,12 +76,13 @@ class RNJWPlayerViewManager: RCTViewManager {
53
76
  }
54
77
 
55
78
  @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]))")
79
+ DispatchQueue.main.async {
80
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
81
+ print(" Failed to play: RNJWPlayerView not found for tag \(reactTag)")
59
82
  return
60
83
  }
61
-
84
+
85
+ view.userPaused = false
62
86
  if let playerView = view.playerView {
63
87
  playerView.player.play()
64
88
  } else if let playerViewController = view.playerViewController {
@@ -66,14 +90,14 @@ class RNJWPlayerViewManager: RCTViewManager {
66
90
  }
67
91
  }
68
92
  }
69
-
93
+
70
94
  @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]))")
95
+ DispatchQueue.main.async {
96
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
97
+ print(" Failed to stop: RNJWPlayerView not found for tag \(reactTag)")
74
98
  return
75
99
  }
76
-
100
+
77
101
  view.userPaused = true
78
102
  if let playerView = view.playerView {
79
103
  playerView.player.stop()
@@ -82,16 +106,15 @@ class RNJWPlayerViewManager: RCTViewManager {
82
106
  }
83
107
  }
84
108
  }
85
-
109
+
86
110
  @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 {
111
+ DispatchQueue.main.async {
112
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
90
113
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no playerView"])
91
114
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
92
115
  return
93
116
  }
94
-
117
+
95
118
  if let playerView = view.playerView {
96
119
  resolve(playerView.player.time.position as NSNumber)
97
120
  } else if let playerViewController = view.playerViewController {
@@ -102,14 +125,14 @@ class RNJWPlayerViewManager: RCTViewManager {
102
125
  }
103
126
  }
104
127
  }
105
-
128
+
106
129
  @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]))")
130
+ DispatchQueue.main.async {
131
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
132
+ print("Invalid view returned from registry, expecting RNJWPlayerView.")
110
133
  return
111
134
  }
112
-
135
+
113
136
  if let playerView = view.playerView {
114
137
  if playerView.player.playbackRate < 2.0 {
115
138
  playerView.player.playbackRate += 0.5
@@ -125,14 +148,14 @@ class RNJWPlayerViewManager: RCTViewManager {
125
148
  }
126
149
  }
127
150
  }
128
-
151
+
129
152
  @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]))")
153
+ DispatchQueue.main.async {
154
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
155
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
133
156
  return
134
157
  }
135
-
158
+
136
159
  if let playerView = view.playerView {
137
160
  playerView.player.playbackRate = speed
138
161
  } else if let playerViewController = view.playerViewController {
@@ -140,15 +163,14 @@ class RNJWPlayerViewManager: RCTViewManager {
140
163
  }
141
164
  }
142
165
  }
143
-
166
+
144
167
  @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]))")
168
+ DispatchQueue.main.async {
169
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
170
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
149
171
  return
150
172
  }
151
-
173
+
152
174
  if let playerView = view.playerView {
153
175
  playerView.player.loadPlayerItemAt(index: index.intValue)
154
176
  } else if let playerViewController = view.playerViewController {
@@ -156,14 +178,14 @@ class RNJWPlayerViewManager: RCTViewManager {
156
178
  }
157
179
  }
158
180
  }
159
-
181
+
160
182
  @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]))")
183
+ DispatchQueue.main.async {
184
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
185
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
164
186
  return
165
187
  }
166
-
188
+
167
189
  if let playerView = view.playerView {
168
190
  playerView.player.seek(to: TimeInterval(time.intValue))
169
191
  } else if let playerViewController = view.playerViewController {
@@ -173,12 +195,12 @@ class RNJWPlayerViewManager: RCTViewManager {
173
195
  }
174
196
 
175
197
  @objc func setVolume(_ reactTag: NSNumber, _ volume: NSNumber) {
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]))")
198
+ DispatchQueue.main.async {
199
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
200
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
179
201
  return
180
202
  }
181
-
203
+
182
204
  if let playerView = view.playerView {
183
205
  playerView.player.volume = volume.doubleValue
184
206
  } else if let playerViewController = view.playerViewController {
@@ -186,15 +208,14 @@ class RNJWPlayerViewManager: RCTViewManager {
186
208
  }
187
209
  }
188
210
  }
189
-
190
-
211
+
191
212
  @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]))")
213
+ DispatchQueue.main.async {
214
+ guard let view = self.getPlayerView(reactTag: reactTag), let pipController = view.playerView?.pictureInPictureController else {
215
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
195
216
  return
196
217
  }
197
-
218
+
198
219
  if pipController.isPictureInPicturePossible {
199
220
  if pipController.isPictureInPictureActive {
200
221
  pipController.stopPictureInPicture()
@@ -205,42 +226,63 @@ class RNJWPlayerViewManager: RCTViewManager {
205
226
  }
206
227
  }
207
228
 
208
- #if USE_GOOGLE_CAST
209
- @objc func setUpCastController(_ reactTag: NSNumber) {
229
+ @objc func resolveNextPlaylistItem(_ reactTag: NSNumber, _ playlistItem: NSDictionary) {
210
230
  self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
211
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
212
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
231
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
232
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
213
233
  return
214
234
  }
235
+
236
+ if let completion = view.onBeforeNextPlaylistItemCompletion {
237
+ do {
238
+ let item = try view.getPlayerItem(item: playlistItem as! [String: Any])
239
+ completion(item)
240
+ } catch {
241
+ print("Error creating JWPlayerItem: \(error)")
242
+ }
243
+ view.onBeforeNextPlaylistItemCompletion = nil
244
+ } else {
245
+ print("Warning: resolveNextPlaylistItem called but no completion handler was set OR completion handler was already called")
246
+ }
247
+ }
248
+ }
215
249
 
250
+ #if USE_GOOGLE_CAST
251
+ @objc func setUpCastController(_ reactTag: NSNumber) {
252
+ DispatchQueue.main.async {
253
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
254
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
255
+ return
256
+ }
257
+
216
258
  view.setUpCastController()
217
259
  }
218
260
  }
219
-
261
+
220
262
  @objc func presentCastDialog(_ reactTag: NSNumber) {
221
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
222
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
223
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
263
+ DispatchQueue.main.async {
264
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
265
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
224
266
  return
225
267
  }
226
-
268
+
227
269
  view.presentCastDialog()
228
270
  }
229
271
  }
230
-
272
+
231
273
  @objc func connectedDevice(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
232
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
233
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
274
+ DispatchQueue.main.async {
275
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
234
276
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
235
277
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
236
278
  return
237
279
  }
238
-
280
+
239
281
  if let device = view.connectedDevice() {
240
282
  var dict = [String: Any]()
241
283
  dict["name"] = device.name
242
284
  dict["identifier"] = device.identifier
243
-
285
+
244
286
  do {
245
287
  let data = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
246
288
  resolve(String(data: data, encoding: .utf8))
@@ -253,25 +295,25 @@ class RNJWPlayerViewManager: RCTViewManager {
253
295
  }
254
296
  }
255
297
  }
256
-
298
+
257
299
  @objc func availableDevices(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
258
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
259
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
300
+ DispatchQueue.main.async {
301
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
260
302
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
261
303
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
262
304
  return
263
305
  }
264
-
306
+
265
307
  if let availableDevices = view.getAvailableDevices() {
266
308
  var devicesInfo: [[String: Any]] = []
267
-
309
+
268
310
  for device in availableDevices {
269
311
  var dict = [String: Any]()
270
312
  dict["name"] = device.name
271
313
  dict["identifier"] = device.identifier
272
314
  devicesInfo.append(dict)
273
315
  }
274
-
316
+
275
317
  do {
276
318
  let data = try JSONSerialization.data(withJSONObject: devicesInfo, options: .prettyPrinted)
277
319
  resolve(String(data: data, encoding: .utf8))
@@ -284,46 +326,44 @@ class RNJWPlayerViewManager: RCTViewManager {
284
326
  }
285
327
  }
286
328
  }
287
-
329
+
288
330
  @objc func castState(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
289
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
290
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
331
+ DispatchQueue.main.async {
332
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
291
333
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
292
334
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
293
335
  return
294
336
  }
295
-
337
+
296
338
  resolve(view.castState)
297
339
  }
298
340
  }
299
341
  #endif
300
-
342
+
301
343
  @objc func getAudioTracks(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
302
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
303
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
344
+ DispatchQueue.main.async {
345
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
304
346
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
305
347
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
306
348
  return
307
349
  }
308
-
309
- let audioTracks: [Any]? = view.playerView?.player.audioTracks ?? view.playerViewController?.player.audioTracks
310
-
311
- if let audioTracks = audioTracks as? [[String: Any]] {
350
+
351
+ let audioTracks: [JWMediaSelectionOption]? = view.playerView?.player.audioTracks ?? view.playerViewController?.player.audioTracks
352
+
353
+ // V4 tracks object instead of the V3 JSON object of old
354
+ if let audioTracks = audioTracks {
312
355
  var results: [[String: Any]] = []
313
356
  for track in audioTracks {
314
- if let language = track["language"], let autoSelect = track["autoselect"],
315
- let defaultTrack = track["defaulttrack"], let name = track["name"],
316
- let groupId = track["groupid"] {
357
+ let track = track as JWMediaSelectionOption
317
358
  let trackDict: [String: Any] = [
318
- "language": language,
319
- "autoSelect": autoSelect,
320
- "defaultTrack": defaultTrack,
321
- "name": name,
322
- "groupId": groupId
359
+ "language": track.extendedLanguageTag ?? "UNKNOWN", // Intentionally defaulting to a non-spec language if none found
360
+ // "autoSelect": autoSelect, // not available in V4
361
+ "defaultTrack": track.defaultOption,
362
+ "name": track.name
363
+ // "groupId": groupId // not available in V4
323
364
  ]
324
365
  results.append(trackDict)
325
366
  }
326
- }
327
367
  resolve(results)
328
368
  } else {
329
369
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There are no audio tracks"])
@@ -333,13 +373,13 @@ class RNJWPlayerViewManager: RCTViewManager {
333
373
  }
334
374
 
335
375
  @objc func getCurrentAudioTrack(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
336
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
337
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
376
+ DispatchQueue.main.async {
377
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
338
378
  let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
339
379
  reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
340
380
  return
341
381
  }
342
-
382
+
343
383
  if let playerView = view.playerView {
344
384
  resolve(NSNumber(value: playerView.player.currentAudioTrack))
345
385
  } else if let playerViewController = view.playerViewController {
@@ -350,14 +390,14 @@ class RNJWPlayerViewManager: RCTViewManager {
350
390
  }
351
391
  }
352
392
  }
353
-
393
+
354
394
  @objc func setCurrentAudioTrack(_ reactTag: NSNumber, _ index: NSNumber) {
355
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
356
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
357
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
395
+ DispatchQueue.main.async {
396
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
397
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
358
398
  return
359
399
  }
360
-
400
+
361
401
  if let playerView = view.playerView {
362
402
  playerView.player.currentAudioTrack = index.intValue
363
403
  } else if let playerViewController = view.playerViewController {
@@ -367,126 +407,164 @@ class RNJWPlayerViewManager: RCTViewManager {
367
407
  }
368
408
 
369
409
  @objc func setControls(_ reactTag: NSNumber, _ show: Bool) {
370
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
371
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
372
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
410
+ DispatchQueue.main.async {
411
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
412
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
373
413
  return
374
414
  }
375
-
415
+
376
416
  if let playerViewController = view.playerViewController {
377
417
  view.toggleUIGroup(view: playerViewController.view, name: "JWPlayerKit.InterfaceView", ofSubview: nil, show: show)
378
418
  }
379
419
  }
380
420
  }
381
-
421
+
382
422
  @objc func setVisibility(_ reactTag: NSNumber, _ visibility: Bool, _ controls: [String]) {
383
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
384
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
385
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
423
+ DispatchQueue.main.async {
424
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
425
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
386
426
  return
387
427
  }
388
-
428
+
389
429
  if view.playerViewController != nil {
390
430
  view.setVisibility(isVisible: visibility, forControls: controls)
391
431
  }
392
432
  }
393
433
  }
394
-
434
+
395
435
  @objc func setLockScreenControls(_ reactTag: NSNumber, _ show: Bool) {
396
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
397
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
398
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
436
+ DispatchQueue.main.async {
437
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
438
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
399
439
  return
400
440
  }
401
-
441
+
402
442
  if let playerViewController = view.playerViewController {
403
443
  playerViewController.enableLockScreenControls = show
404
444
  }
405
445
  }
406
446
  }
407
-
447
+
408
448
  @objc func setCurrentCaptions(_ reactTag: NSNumber, _ index: NSNumber) {
409
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
410
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
411
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
449
+ DispatchQueue.main.async {
450
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
451
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
412
452
  return
413
453
  }
414
-
454
+
455
+ do {
456
+ if let playerView = view.playerView {
457
+ try playerView.player.setCaptionTrack(index: index.intValue)
458
+ } else if let playerViewController = view.playerViewController {
459
+ try playerViewController.player.setCaptionTrack(index: index.intValue)
460
+ }
461
+ } catch {
462
+ print("Error setting caption track: \(error)")
463
+ }
464
+ }
465
+ }
466
+
467
+ @objc func getCurrentCaptions(_ reactTag: NSNumber, _ resolve: @escaping RCTPromiseResolveBlock, _ reject: @escaping RCTPromiseRejectBlock) {
468
+ DispatchQueue.main.async {
469
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
470
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
471
+ reject("no_player", "Invalid view returned from registry, expecting RNJWPlayerView", error)
472
+ return
473
+ }
474
+
415
475
  if let playerView = view.playerView {
416
- playerView.player.currentCaptionsTrack = index.intValue + 1
476
+ resolve(NSNumber(value: playerView.player.currentCaptionsTrack))
417
477
  } else if let playerViewController = view.playerViewController {
418
- playerViewController.player.currentCaptionsTrack = index.intValue + 1
478
+ resolve(NSNumber(value: playerViewController.player.currentCaptionsTrack))
479
+ } else {
480
+ let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "There is no player"])
481
+ reject("no_player", "There is no player", error)
419
482
  }
420
483
  }
421
484
  }
422
-
485
+
423
486
  @objc func setLicenseKey(_ reactTag: NSNumber, _ license: String) {
424
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
425
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
426
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
487
+ DispatchQueue.main.async {
488
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
489
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
427
490
  return
428
491
  }
429
-
492
+
430
493
  view.setLicense(license: license)
431
494
  }
432
495
  }
433
-
434
- @objc func quite() {
435
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
436
- for (_, view) in viewRegistry ?? [:] {
437
- if let rnjwView = view as? RNJWPlayerView {
438
- if let playerView = rnjwView.playerView {
439
- playerView.player.pause()
440
- playerView.player.stop()
441
- } else if let playerViewController = rnjwView.playerViewController {
442
- playerViewController.player.pause()
443
- playerViewController.player.stop()
496
+
497
+ private func performActionOnAllPlayers(_ action: @escaping (RNJWPlayerView) -> Void) {
498
+ DispatchQueue.main.async {
499
+ guard let bridge = self.bridge else { return }
500
+
501
+ let uiManager = bridge.uiManager
502
+ if let viewRegistry = uiManager?.value(forKey: "viewRegistry") as? [NSNumber: UIView] {
503
+ for (reactTag, view) in viewRegistry {
504
+ if let playerView = self.getPlayerView(reactTag: reactTag) {
505
+ action(playerView)
444
506
  }
445
507
  }
446
508
  }
447
509
  }
448
510
  }
449
511
 
450
- @objc func reset() {
451
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
452
- for (_, view) in viewRegistry ?? [:] {
453
- if let rnjwView = view as? RNJWPlayerView {
454
- rnjwView.startDeinitProcess()
455
- }
512
+ @objc func quite() {
513
+ performActionOnAllPlayers { view in
514
+ if let playerView = view.playerView {
515
+ playerView.player.pause()
516
+ playerView.player.stop()
517
+ } else if let playerViewController = view.playerViewController {
518
+ playerViewController.player.pause()
519
+ playerViewController.player.stop()
456
520
  }
457
521
  }
458
522
  }
459
523
 
460
- @objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: [Any]) {
461
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
462
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
463
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
524
+ @objc func reset() {
525
+ performActionOnAllPlayers { view in
526
+ view.startDeinitProcess()
527
+ }
528
+ }
529
+
530
+ @objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: Any) {
531
+ DispatchQueue.main.async {
532
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
533
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
464
534
  return
465
535
  }
466
-
536
+
467
537
  var playlistArray = [JWPlayerItem]()
468
-
469
- for item in playlist {
470
- if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
471
- playlistArray.append(playerItem)
538
+
539
+ if let playlistArrayInput = playlist as? [[String: Any]] {
540
+ for item in playlistArrayInput {
541
+ if let playerItem = try? view.getPlayerItem(item: item) {
542
+ playlistArray.append(playerItem)
543
+ }
544
+ }
545
+
546
+ if let playerView = view.playerView {
547
+ playerView.player.loadPlaylist(items: playlistArray)
548
+ } else if let playerViewController = view.playerViewController {
549
+ playerViewController.player.loadPlaylist(items: playlistArray)
550
+ }
551
+ } else if let playlistString = playlist as? String, let url = URL(string: playlistString) {
552
+ if let playerView = view.playerView {
553
+ playerView.player.loadPlaylist(url: url)
554
+ } else if let playerViewController = view.playerViewController {
555
+ playerViewController.player.loadPlaylist(url: url)
472
556
  }
473
- }
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
557
  }
480
558
  }
481
559
  }
482
-
560
+
483
561
  @objc func setFullscreen(_ reactTag: NSNumber, _ fullscreen: Bool) {
484
- self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
485
- guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
486
- print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
562
+ DispatchQueue.main.async {
563
+ guard let view = self.getPlayerView(reactTag: reactTag) else {
564
+ print("Invalid view returned from registry, expecting RNJWPlayerView")
487
565
  return
488
566
  }
489
-
567
+
490
568
  if let playerViewController = view.playerViewController {
491
569
  if fullscreen {
492
570
  playerViewController.transitionToFullScreen(animated: true, completion: nil)
@@ -494,9 +572,9 @@ class RNJWPlayerViewManager: RCTViewManager {
494
572
  playerViewController.dismissFullScreen(animated: true, completion: nil)
495
573
  }
496
574
  } else {
497
- print("Invalid view returned from registry, expecting RNJWPlayerViewController, got: \(view)")
575
+ print("Invalid view returned from registry, expecting RNJWPlayerViewController")
498
576
  }
499
577
  }
500
578
  }
501
-
579
+
502
580
  }