@picsa/capacitor-video-player 7.1.0 → 7.2.2

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 (69) hide show
  1. package/CapacitorVideoPlayer.podspec +17 -17
  2. package/LICENSE +21 -21
  3. package/android/build.gradle +71 -71
  4. package/android/src/main/AndroidManifest.xml +3 -3
  5. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/CapacitorVideoPlayer.java +71 -71
  6. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/CapacitorVideoPlayerPlugin.java +1256 -1256
  7. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/FullscreenExoPlayerFragment.java +1595 -1595
  8. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/Notifications/MyRunnable.java +21 -21
  9. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/Notifications/NotificationCenter.java +61 -61
  10. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/PickerVideo/AdapterVideoList.java +47 -47
  11. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/PickerVideo/ModelVideo.java +49 -49
  12. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/PickerVideo/PickerVideoFragment.java +119 -119
  13. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/PickerVideo/VideoRecyclerViewHolder.java +65 -65
  14. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/Utilities/FilesUtils.java +101 -101
  15. package/android/src/main/java/com/jeep/plugin/capacitor/capacitorvideoplayer/Utilities/FragmentUtils.java +32 -32
  16. package/android/src/main/res/drawable/bg_round_rect_white_50.xml +9 -9
  17. package/android/src/main/res/drawable/bg_rounded_rectangle_white_corner_rounded.xml +10 -10
  18. package/android/src/main/res/drawable/exo_close_btn.xml +11 -11
  19. package/android/src/main/res/drawable/gradient_transparent_middle.xml +12 -12
  20. package/android/src/main/res/drawable/ic_arrow_left.xml +5 -5
  21. package/android/src/main/res/drawable/ic_baseline_lq.xml +7 -7
  22. package/android/src/main/res/drawable/ic_exo_icon_fastforward.xml +35 -35
  23. package/android/src/main/res/drawable/ic_exo_icon_pause.xml +26 -26
  24. package/android/src/main/res/drawable/ic_exo_icon_play.xml +36 -36
  25. package/android/src/main/res/drawable/ic_exo_icon_rewind.xml +35 -35
  26. package/android/src/main/res/drawable/ic_expand.xml +5 -5
  27. package/android/src/main/res/drawable/ic_fit.xml +5 -5
  28. package/android/src/main/res/drawable/ic_image_background.xml +12 -12
  29. package/android/src/main/res/drawable/ic_img_16_9_background.xml +10 -10
  30. package/android/src/main/res/drawable/ic_img_9_16_background.xml +10 -10
  31. package/android/src/main/res/drawable/ic_outline_lock.xml +5 -5
  32. package/android/src/main/res/drawable/ic_outline_lock_open.xml +5 -5
  33. package/android/src/main/res/drawable/ic_pip_white.xml +5 -5
  34. package/android/src/main/res/drawable/ic_views.xml +18 -18
  35. package/android/src/main/res/drawable/ic_zoom.xml +5 -5
  36. package/android/src/main/res/layout/bridge_layout_main.xml +15 -15
  37. package/android/src/main/res/layout/exo_playback_control_view.xml +289 -289
  38. package/android/src/main/res/layout/exoplayer_layout_youtube.xml +361 -361
  39. package/android/src/main/res/layout/fragment_fs_exoplayer.xml +50 -50
  40. package/android/src/main/res/layout/fragment_picker_video.xml +21 -21
  41. package/android/src/main/res/layout/row_video.xml +76 -76
  42. package/android/src/main/res/values/colors.xml +14 -14
  43. package/android/src/main/res/values/strings.xml +3 -3
  44. package/android/src/main/res/values/styles.xml +3 -3
  45. package/dist/docs.json +14 -14
  46. package/ios/Plugin/CapacitorVideoPlayer.swift +63 -63
  47. package/ios/Plugin/CapacitorVideoPlayerPlugin.h +10 -10
  48. package/ios/Plugin/CapacitorVideoPlayerPlugin.m +22 -22
  49. package/ios/Plugin/CapacitorVideoPlayerPlugin.swift +631 -631
  50. package/ios/Plugin/Extensions/CapacitorVideoPlayerPlugin.AVPlayerViewController.swift +59 -59
  51. package/ios/Plugin/Extensions/CapacitorVideoPlayerPlugin.File.swift +126 -126
  52. package/ios/Plugin/Extensions/CapacitorVideoPlayerPlugin.Fullscreen.swift +94 -94
  53. package/ios/Plugin/Extensions/CapacitorVideoPlayerPlugin.Notifications.swift +140 -140
  54. package/ios/Plugin/Extensions/CapacitorVideoPlayerPlugin.Observers.swift +180 -180
  55. package/ios/Plugin/Info.plist +24 -24
  56. package/ios/Plugin/VideoPicker/VideoHelper.swift +127 -127
  57. package/ios/Plugin/VideoPicker/VideoPickerViewController.swift +144 -144
  58. package/ios/Plugin/VideoPlayer/Extensions/AVURLAsset.swift +18 -18
  59. package/ios/Plugin/VideoPlayer/Extensions/AllOrientationAVPlayerController.swift +12 -12
  60. package/ios/Plugin/VideoPlayer/Extensions/CMTime.swift +23 -23
  61. package/ios/Plugin/VideoPlayer/Extensions/LandscapeAVPlayerController.swift +12 -12
  62. package/ios/Plugin/VideoPlayer/Extensions/Notification.Name.swift +18 -18
  63. package/ios/Plugin/VideoPlayer/Extensions/PortraitAVPlayerController.swift +12 -12
  64. package/ios/Plugin/VideoPlayer/Extensions/View.swift +54 -54
  65. package/ios/Plugin/VideoPlayer/FullScreenVideoPlayerView.swift +601 -601
  66. package/ios/Plugin/VideoPlayer/Models/Video.swift +28 -28
  67. package/ios/Plugin/VideoPlayer/Models/VideoModel.swift +42 -42
  68. package/package.json +92 -92
  69. package/readme.md +196 -190
@@ -1,632 +1,632 @@
1
- import Foundation
2
- import Capacitor
3
- import AVKit
4
- import UIKit
5
-
6
- /**
7
- * Please read the Capacitor iOS Plugin Development Guide
8
- * here: https://capacitorjs.com/docs/plugins/ios
9
- */
10
- @objc(CapacitorVideoPlayerPlugin)
11
- // swiftlint:disable file_length
12
- // swiftlint:disable type_body_length
13
- public class CapacitorVideoPlayerPlugin: CAPPlugin {
14
- public var call: CAPPluginCall?
15
- public var videoPlayer: AVPlayerViewController?
16
- public var bgPlayer: AVPlayer?
17
- public let implementation = CapacitorVideoPlayer()
18
- var videoPlayerFullScreenView: FullScreenVideoPlayerView?
19
- var audioSession: AVAudioSession?
20
- var mode: String?
21
- var exitOnEnd: Bool = true
22
- var loopOnEnd: Bool = false
23
- var pipEnabled: Bool = true
24
- var backModeEnabled: Bool = true
25
- var showControls: Bool = true
26
- var displayMode: String = "all"
27
- var headers: [String: String]?
28
- var title: String?
29
- var smallTitle: String?
30
- var artwork: String?
31
- var fsPlayerId: String = "fullscreen"
32
- var videoRate: Float = 1.0
33
- var playObserver: Any?
34
- var pauseObserver: Any?
35
- var endObserver: Any?
36
- var readyObserver: Any?
37
- var fsDismissObserver: Any?
38
- var backgroundObserver: Any?
39
- var foregroundObserver: Any?
40
- var vpInternalObserver: Any?
41
- let rateList: [Float] = [0.25, 0.5, 0.75, 1.0, 2.0, 4.0]
42
-
43
- override public func load() {
44
- self.addObserversToNotificationCenter()
45
- if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad),
46
- #available(iOS 13.0, *) {
47
- isPIPModeAvailable = true
48
- } else if #available(iOS 14.0, *) {
49
- isPIPModeAvailable = true
50
- }
51
- }
52
- deinit {
53
- NotificationCenter.default.removeObserver(playObserver as Any)
54
- NotificationCenter.default.removeObserver(pauseObserver as Any)
55
- NotificationCenter.default.removeObserver(endObserver as Any)
56
- NotificationCenter.default.removeObserver(readyObserver as Any)
57
- NotificationCenter.default.removeObserver(fsDismissObserver as Any)
58
- NotificationCenter.default.removeObserver(backgroundObserver as Any)
59
- NotificationCenter.default.removeObserver(foregroundObserver as Any)
60
- NotificationCenter.default.removeObserver(vpInternalObserver as Any)
61
- }
62
-
63
- @objc func echo(_ call: CAPPluginCall) {
64
- let value = call.getString("value") ?? ""
65
- call.resolve([
66
- "value": implementation.echo(value)
67
- ])
68
- }
69
-
70
- // MARK: - Init player(s)
71
-
72
- // swiftlint:disable function_body_length
73
- // swiftlint:disable cyclomatic_complexity
74
- @objc func initPlayer(_ call: CAPPluginCall) {
75
- self.call = call
76
- guard let mode = call.options["mode"] as? String else {
77
- let error: String = "Must provide a Mode " +
78
- "(fullscreen/embedded)"
79
- call.resolve([ "result": false, "method": "initPlayer",
80
- "message": error])
81
-
82
- return
83
- }
84
- guard let playerId = call.options["playerId"] as? String else {
85
- let error: String = "Must provide a PlayerId"
86
- call.resolve([ "result": false, "method": "initPlayer",
87
- "message": error])
88
- return
89
- }
90
- var mRate: Float = 1.0
91
- if let sRate = call.options["rate"] as? Float {
92
- if rateList.contains(sRate) {
93
- mRate = sRate
94
- }
95
- }
96
- var exitOnEnd: Bool = true
97
- if let sexitOnEnd = call.options["exitOnEnd"] as? Bool {
98
- exitOnEnd = sexitOnEnd
99
- }
100
- var loopOnEnd: Bool = false
101
- if let sloopOnEnd = call.options["loopOnEnd"] as? Bool {
102
- if !exitOnEnd {
103
- loopOnEnd = sloopOnEnd
104
- }
105
- }
106
- var headers: [String: String]?
107
- if let sheaders = call.options["headers"] as? [String: String] {
108
- headers = sheaders
109
- }
110
- var pipEnabled: Bool = true
111
- if let spipEnabled = call.options["pipEnabled"] as? Bool {
112
- pipEnabled = spipEnabled
113
- }
114
- var bkModeEnabled: Bool = true
115
- if let sbkModeEnabled = call.options["bkmodeEnabled"] as? Bool {
116
- bkModeEnabled = sbkModeEnabled
117
- }
118
- var shControls: Bool = true
119
- if let shoControls = call.options["showControls"] as? Bool {
120
- shControls = shoControls
121
- }
122
- var disMode: String = "all"
123
- if let dispMode = call.options["displayMode"] as? String {
124
- disMode = dispMode
125
- }
126
- var title: String?
127
- if let stitle = call.options["title"] as? String {
128
- title = stitle
129
- }
130
- var smallTitle: String?
131
- if let ssmallTitle = call.options["smallTitle"] as? String {
132
- smallTitle = ssmallTitle
133
- }
134
- var artwork: String?
135
- if let sartwork = call.options["artwork"] as? String {
136
- artwork = sartwork
137
- }
138
- self.fsPlayerId = playerId
139
- self.mode = mode
140
- self.videoRate = mRate
141
- self.exitOnEnd = exitOnEnd
142
- self.loopOnEnd = loopOnEnd
143
- self.pipEnabled = pipEnabled
144
- self.headers = headers
145
- if !self.pipEnabled {isPIPModeAvailable = false}
146
- self.backModeEnabled = bkModeEnabled
147
- self.showControls = shControls
148
- self.displayMode = disMode
149
- self.title = title
150
- self.smallTitle = smallTitle
151
- self.artwork = artwork
152
- if mode == "fullscreen" {
153
- guard let videoPath = call.options["url"] as? String else {
154
- let error: String = "Must provide a video url"
155
- print(error)
156
- call.resolve([ "result": false, "method": "initPlayer", "message": error])
157
- return
158
- }
159
- var subTitlePath: String = ""
160
- if let stPath = call.options["subtitle"] as? String {
161
- subTitlePath = stPath
162
- }
163
- var subTitleLanguage: String = ""
164
- if let stLanguage = call.options["language"] as? String {
165
- subTitleLanguage = stLanguage
166
- }
167
-
168
- let subTitleOptions: [String: Any] = call.getObject("subtitleOptions") ?? [:]
169
-
170
- if videoPath == "internal" {
171
- DispatchQueue.main.async { [weak self] in
172
- if let videoPickerViewController =
173
- self?.implementation.pickVideoFromInternal(
174
- rate: self?.videoRate ?? 1.0,
175
- exitOnEnd: self?.exitOnEnd ?? true,
176
- loopOnEnd: self?.loopOnEnd ?? false,
177
- pipEnabled: self?.pipEnabled ?? true,
178
- backModeEnabled: self?.backModeEnabled ?? true,
179
- showControls: self?.showControls ?? true,
180
- displayMode: self?.displayMode ?? "all") {
181
- self?.bridge?.viewController?.present(
182
- videoPickerViewController,
183
- animated: true, completion: {return})
184
- }
185
- }
186
-
187
- } else {
188
- let dictUrl: [String: Any] =
189
- getURLFromFilePath(filePath: videoPath)
190
- if let message = dictUrl["message"] as? String {
191
- if message.count > 0 {
192
- call.resolve([ "result": false, "method": "initPlayer",
193
- "message": message])
194
- return
195
- }
196
- }
197
- guard let url = dictUrl["url"] as? URL else {
198
- call.resolve([ "result": false, "method": "initPlayer",
199
- "message": "url not defined"])
200
- return
201
- }
202
- var subTitle: URL?
203
- if subTitlePath.count > 0 {
204
-
205
- let dictSubTitle: [String: Any] =
206
- getURLFromFilePath(filePath: subTitlePath)
207
- if let message = dictSubTitle["message"] as? String {
208
- if message.count > 0 {
209
- call.resolve([ "result": false, "method": "initPlayer",
210
- "message": message])
211
- return
212
- }
213
- }
214
- guard let sturl = dictSubTitle["url"] as? URL else {
215
- call.resolve([ "result": false, "method": "initPlayer",
216
- "message": "subtitle url not defined"])
217
- return
218
- }
219
- subTitle = sturl
220
- }
221
- guard let call = self.call else { return }
222
- self.createVideoPlayerFullscreenView(
223
- call: call, videoUrl: url, rate: videoRate,
224
- exitOnEnd: exitOnEnd, loopOnEnd: loopOnEnd,
225
- pipEnabled: pipEnabled,
226
- backModeEnabled: backModeEnabled,
227
- showControls: showControls,
228
- displayMode: displayMode,
229
- subTitleUrl: subTitle,
230
- subTitleLanguage: subTitleLanguage,
231
- subTitleOptions: subTitleOptions,
232
- headers: headers,
233
- title: title,
234
- smallTitle: smallTitle,
235
- artwork: artwork)
236
-
237
- }
238
- } else {
239
- call.resolve([ "result": false,
240
- "method": "initPlayer",
241
- "message": "Not implemented"])
242
- return
243
- }
244
- }
245
- // swiftlint:enable function_body_length
246
- // swiftlint:enable cyclomatic_complexity
247
-
248
- // MARK: - Play the given player
249
-
250
- @objc func isPlaying(_ call: CAPPluginCall) {
251
- self.call = call
252
- guard let playerId = call.options["playerId"] as? String else {
253
- let error: String = "Must provide a playerId"
254
- print(error)
255
- call.resolve([ "result": false, "method": "isPlaying", "message": error])
256
- return
257
- }
258
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
259
-
260
- if let playerView = self.videoPlayerFullScreenView {
261
- DispatchQueue.main.async {
262
- let isPlaying: Bool = playerView.isPlaying
263
- call.resolve([ "result": true, "method": "isPlaying", "value": isPlaying])
264
- return
265
- }
266
- } else {
267
- let error: String = "Fullscreen player not found"
268
- print(error)
269
- call.resolve([ "result": false, "method": "isPlaying", "message": error])
270
- return
271
- }
272
- }
273
- }
274
- // MARK: - Play the given player
275
-
276
- @objc func play(_ call: CAPPluginCall) {
277
- self.call = call
278
- guard let playerId = call.options["playerId"] as? String else {
279
- let error: String = "Must provide a playerId"
280
- print(error)
281
- call.resolve([ "result": false, "method": "play", "message": error])
282
- return
283
- }
284
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
285
-
286
- if let playerView = self.videoPlayerFullScreenView {
287
- DispatchQueue.main.async {
288
- playerView.play()
289
- call.resolve([ "result": true, "method": "play", "value": true])
290
- return
291
- }
292
- } else {
293
- let error: String = "Fullscreen player not found"
294
- print(error)
295
- call.resolve([ "result": false, "method": "play", "message": error])
296
- return
297
- }
298
- }
299
- }
300
-
301
- // MARK: - Pause the given player
302
-
303
- @objc func pause(_ call: CAPPluginCall) {
304
- self.call = call
305
-
306
- guard let playerId = call.options["playerId"] as? String else {
307
- let error: String = "Must provide a playerId"
308
- print(error)
309
- call.resolve([ "result": false, "method": "pause", "message": error])
310
- return
311
- }
312
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
313
- if let playerView = self.videoPlayerFullScreenView {
314
- DispatchQueue.main.async {
315
- playerView.pause()
316
- call.resolve([ "result": true, "method": "pause", "value": true])
317
- return
318
- }
319
- } else {
320
- let error: String = "Fullscreen player not found"
321
- print(error)
322
- call.resolve([ "result": false, "method": "pause", "message": error])
323
- return
324
- }
325
- }
326
- }
327
-
328
- // MARK: - get Duration for the given player
329
-
330
- @objc func getDuration(_ call: CAPPluginCall) {
331
- self.call = call
332
-
333
- guard let playerId = call.options["playerId"] as? String else {
334
- let error: String = "Must provide a playerId"
335
- print(error)
336
- call.resolve([ "result": false, "method": "getDuration", "message": error])
337
- return
338
- }
339
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
340
- if let playerView = self.videoPlayerFullScreenView {
341
- DispatchQueue.main.async {
342
- let duration: Double = playerView.getDuration()
343
- call.resolve([ "result": true, "method": "getDuration", "value": duration])
344
- return
345
- }
346
- } else {
347
- let error: String = "Fullscreen playerId not found"
348
- print(error)
349
- call.resolve([ "result": false, "method": "getDuration", "message": error])
350
- return
351
- }
352
- }
353
- }
354
-
355
- // MARK: - get CurrentTime for the given player
356
-
357
- @objc func getCurrentTime(_ call: CAPPluginCall) {
358
- self.call = call
359
-
360
- guard let playerId = call.options["playerId"] as? String else {
361
- let error: String = "Must provide a playerId"
362
- print(error)
363
- call.resolve([ "result": false, "method": "getCurrentTime", "message": error])
364
- return
365
- }
366
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
367
- if let playerView = self.videoPlayerFullScreenView {
368
- DispatchQueue.main.async {
369
- let currentTime: Double = playerView.getCurrentTime()
370
- call.resolve([ "result": true, "method": "getCurrentTime",
371
- "value": currentTime])
372
- return
373
- }
374
- } else {
375
- let error: String = "Fullscreen playerId not found"
376
- print(error)
377
- call.resolve([ "result": false, "method": "getCurrentTime", "message": error])
378
- return
379
- }
380
-
381
- }
382
- }
383
-
384
- // MARK: - set CurrentTime for the given player
385
-
386
- @objc func setCurrentTime(_ call: CAPPluginCall) {
387
- self.call = call
388
-
389
- guard let playerId = call.options["playerId"] as? String else {
390
- let error: String = "Must provide a playerId"
391
- print(error)
392
- call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
393
- return
394
- }
395
- guard let seekTime = call.options["seektime"] as? Double else {
396
- let error: String = "Must provide a time in second"
397
- print(error)
398
- call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
399
- return
400
- }
401
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
402
- if let playerView = self.videoPlayerFullScreenView {
403
- DispatchQueue.main.async {
404
- playerView.setCurrentTime(time: seekTime)
405
- call.resolve([ "result": true, "method": "setCurrentTime",
406
- "value": seekTime])
407
- return
408
- }
409
- } else {
410
- let error: String = "Fullscreen playerId not found"
411
- print(error)
412
- call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
413
- return
414
- }
415
- }
416
- }
417
-
418
- // MARK: - get Volume for the given player
419
-
420
- @objc func getVolume(_ call: CAPPluginCall) {
421
- self.call = call
422
-
423
- guard let playerId = call.options["playerId"] as? String else {
424
- let error: String = "Must provide a playerId"
425
- print(error)
426
- call.resolve([ "result": false, "method": "getVolume", "message": error])
427
- return
428
- }
429
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
430
- if let playerView = self.videoPlayerFullScreenView {
431
- DispatchQueue.main.async {
432
- let volume: Float = playerView.getVolume()
433
- call.resolve([ "result": true, "method": "getVolume", "value": volume])
434
- return
435
- }
436
- } else {
437
- let error: String = "Fullscreen playerId not found"
438
- print(error)
439
- call.resolve([ "result": false, "method": "getVolume", "message": error])
440
- return
441
- }
442
- }
443
- }
444
-
445
- // MARK: - set Volume for the given player
446
-
447
- @objc func setVolume(_ call: CAPPluginCall) {
448
- self.call = call
449
-
450
- guard let playerId = call.options["playerId"] as? String else {
451
- let error: String = "Must provide a playerId"
452
- print(error)
453
- call.resolve([ "result": false, "method": "setVolume", "message": error])
454
- return
455
- }
456
- guard let volume = call.options["volume"] as? Float else {
457
- let error: String = "Must provide a volume value"
458
- print(error)
459
- call.resolve([ "result": false, "method": "setVolume", "message": error])
460
-
461
- return
462
- }
463
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
464
- if let playerView = self.videoPlayerFullScreenView {
465
- DispatchQueue.main.async {
466
- playerView.setVolume(volume: volume)
467
- call.resolve([ "result": true, "method": "setVolume", "value": volume])
468
- return
469
- }
470
- } else {
471
- let error: String = "Fullscreen playerId not found"
472
- print(error)
473
- call.resolve([ "result": false, "method": "setVolume", "message": error])
474
- return
475
- }
476
- }
477
-
478
- }
479
-
480
- // MARK: - get Muted for the given player
481
-
482
- @objc func getMuted(_ call: CAPPluginCall) {
483
- self.call = call
484
-
485
- guard let playerId = call.options["playerId"] as? String else {
486
- let error: String = "Must provide a playerId"
487
- print(error)
488
- call.resolve([ "result": false, "method": "getMuted", "message": error])
489
- return
490
- }
491
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
492
- if let playerView = self.videoPlayerFullScreenView {
493
- DispatchQueue.main.async {
494
- let muted: Bool = playerView.getMuted()
495
- call.resolve([ "result": true, "method": "getMuted", "value": muted])
496
- return
497
- }
498
- } else {
499
- let error: String = "Fullscreen playerId not found"
500
- print(error)
501
- call.resolve([ "result": false, "method": "getMuted", "message": error])
502
- return
503
- }
504
- }
505
- }
506
-
507
- // MARK: - set Muted for the given player
508
-
509
- @objc func setMuted(_ call: CAPPluginCall) {
510
- self.call = call
511
-
512
- guard let playerId = call.options["playerId"] as? String else {
513
- let error: String = "Must provide a playerId"
514
- print(error)
515
- call.resolve([ "result": false, "method": "setMuted", "message": error])
516
- return
517
- }
518
- guard let muted = call.options["muted"] as? Bool else {
519
- let error: String = "Must provide a boolean true/false"
520
- print(error)
521
- call.resolve([ "result": false, "method": "setMuted", "message": error])
522
- return
523
- }
524
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
525
- if let playerView = self.videoPlayerFullScreenView {
526
- DispatchQueue.main.async {
527
- playerView.setMuted(muted: muted)
528
- call.resolve([ "result": true, "method": "setMuted", "value": muted])
529
- return
530
- }
531
- } else {
532
- let error: String = "Fullscreen playerId not found"
533
- print(error)
534
- call.resolve([ "result": false, "method": "setMuted", "message": error])
535
- return
536
- }
537
- }
538
- }
539
-
540
- // MARK: - Stop all player(s) playing
541
-
542
- @objc func stopAllPlayers(_ call: CAPPluginCall) {
543
- self.call = call
544
- if self.mode == "fullscreen" {
545
- if let playerView = self.videoPlayerFullScreenView {
546
- DispatchQueue.main.async {
547
- if playerView.isPlaying {
548
- playerView.pause()
549
- }
550
- call.resolve([ "result": true, "method": "stopAllPlayers", "value": true])
551
- return
552
- }
553
- } else {
554
- let error: String = "Fullscreen player not found"
555
- print(error)
556
- call.resolve([ "result": false, "method": "stopAllPlayers", "message": error])
557
- return
558
- }
559
-
560
- }
561
- }
562
-
563
- // MARK: - get Rate for the given player
564
-
565
- @objc func getRate(_ call: CAPPluginCall) {
566
- self.call = call
567
-
568
- guard let playerId = call.options["playerId"] as? String else {
569
- let error: String = "Must provide a playerId"
570
- print(error)
571
- call.resolve([ "result": false, "method": "getRate", "message": error])
572
- return
573
- }
574
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
575
- if let playerView = self.videoPlayerFullScreenView {
576
- DispatchQueue.main.async {
577
- let rate: Float = playerView.getRate()
578
- call.resolve([ "result": true, "method": "getRate", "value": rate])
579
- return
580
- }
581
- } else {
582
- let error: String = "Fullscreen playerId not found"
583
- print(error)
584
- call.resolve([ "result": false, "method": "getRate", "message": error])
585
- return
586
- }
587
- }
588
- }
589
-
590
- // MARK: - set Rate for the given player
591
-
592
- @objc func setRate(_ call: CAPPluginCall) {
593
- self.call = call
594
-
595
- guard let playerId = call.options["playerId"] as? String else {
596
- let error: String = "Must provide a playerId"
597
- print(error)
598
- call.resolve([ "result": false, "method": "setRate", "message": error])
599
- return
600
- }
601
- guard let rate = call.options["rate"] as? Float else {
602
- let error: String = "Must provide a rate value"
603
- print(error)
604
- call.resolve([ "result": false, "method": "setRate", "message": error])
605
-
606
- return
607
- }
608
- self.videoRate = rateList.contains(rate) ? rate : 1.0
609
-
610
- if self.mode == "fullscreen" && self.fsPlayerId == playerId {
611
- if let playerView = self.videoPlayerFullScreenView {
612
- //34567890123456789012345678901234567890
613
- DispatchQueue.main.async {
614
- playerView.setRate(rate: self.videoRate)
615
- call.resolve([ "result": true, "method": "setRate",
616
- "value": self.videoRate])
617
- return
618
- }
619
- } else {
620
- let error: String = "Fullscreen playerId not found"
621
- print(error)
622
- call.resolve([ "result": false, "method": "setRate", "message": error])
623
- return
624
- }
625
- }
626
-
627
- }
628
-
629
- }
630
-
631
- // swiftlint:enable type_body_length
1
+ import Foundation
2
+ import Capacitor
3
+ import AVKit
4
+ import UIKit
5
+
6
+ /**
7
+ * Please read the Capacitor iOS Plugin Development Guide
8
+ * here: https://capacitorjs.com/docs/plugins/ios
9
+ */
10
+ @objc(CapacitorVideoPlayerPlugin)
11
+ // swiftlint:disable file_length
12
+ // swiftlint:disable type_body_length
13
+ public class CapacitorVideoPlayerPlugin: CAPPlugin {
14
+ public var call: CAPPluginCall?
15
+ public var videoPlayer: AVPlayerViewController?
16
+ public var bgPlayer: AVPlayer?
17
+ public let implementation = CapacitorVideoPlayer()
18
+ var videoPlayerFullScreenView: FullScreenVideoPlayerView?
19
+ var audioSession: AVAudioSession?
20
+ var mode: String?
21
+ var exitOnEnd: Bool = true
22
+ var loopOnEnd: Bool = false
23
+ var pipEnabled: Bool = true
24
+ var backModeEnabled: Bool = true
25
+ var showControls: Bool = true
26
+ var displayMode: String = "all"
27
+ var headers: [String: String]?
28
+ var title: String?
29
+ var smallTitle: String?
30
+ var artwork: String?
31
+ var fsPlayerId: String = "fullscreen"
32
+ var videoRate: Float = 1.0
33
+ var playObserver: Any?
34
+ var pauseObserver: Any?
35
+ var endObserver: Any?
36
+ var readyObserver: Any?
37
+ var fsDismissObserver: Any?
38
+ var backgroundObserver: Any?
39
+ var foregroundObserver: Any?
40
+ var vpInternalObserver: Any?
41
+ let rateList: [Float] = [0.25, 0.5, 0.75, 1.0, 2.0, 4.0]
42
+
43
+ override public func load() {
44
+ self.addObserversToNotificationCenter()
45
+ if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad),
46
+ #available(iOS 13.0, *) {
47
+ isPIPModeAvailable = true
48
+ } else if #available(iOS 14.0, *) {
49
+ isPIPModeAvailable = true
50
+ }
51
+ }
52
+ deinit {
53
+ NotificationCenter.default.removeObserver(playObserver as Any)
54
+ NotificationCenter.default.removeObserver(pauseObserver as Any)
55
+ NotificationCenter.default.removeObserver(endObserver as Any)
56
+ NotificationCenter.default.removeObserver(readyObserver as Any)
57
+ NotificationCenter.default.removeObserver(fsDismissObserver as Any)
58
+ NotificationCenter.default.removeObserver(backgroundObserver as Any)
59
+ NotificationCenter.default.removeObserver(foregroundObserver as Any)
60
+ NotificationCenter.default.removeObserver(vpInternalObserver as Any)
61
+ }
62
+
63
+ @objc func echo(_ call: CAPPluginCall) {
64
+ let value = call.getString("value") ?? ""
65
+ call.resolve([
66
+ "value": implementation.echo(value)
67
+ ])
68
+ }
69
+
70
+ // MARK: - Init player(s)
71
+
72
+ // swiftlint:disable function_body_length
73
+ // swiftlint:disable cyclomatic_complexity
74
+ @objc func initPlayer(_ call: CAPPluginCall) {
75
+ self.call = call
76
+ guard let mode = call.options["mode"] as? String else {
77
+ let error: String = "Must provide a Mode " +
78
+ "(fullscreen/embedded)"
79
+ call.resolve([ "result": false, "method": "initPlayer",
80
+ "message": error])
81
+
82
+ return
83
+ }
84
+ guard let playerId = call.options["playerId"] as? String else {
85
+ let error: String = "Must provide a PlayerId"
86
+ call.resolve([ "result": false, "method": "initPlayer",
87
+ "message": error])
88
+ return
89
+ }
90
+ var mRate: Float = 1.0
91
+ if let sRate = call.options["rate"] as? Float {
92
+ if rateList.contains(sRate) {
93
+ mRate = sRate
94
+ }
95
+ }
96
+ var exitOnEnd: Bool = true
97
+ if let sexitOnEnd = call.options["exitOnEnd"] as? Bool {
98
+ exitOnEnd = sexitOnEnd
99
+ }
100
+ var loopOnEnd: Bool = false
101
+ if let sloopOnEnd = call.options["loopOnEnd"] as? Bool {
102
+ if !exitOnEnd {
103
+ loopOnEnd = sloopOnEnd
104
+ }
105
+ }
106
+ var headers: [String: String]?
107
+ if let sheaders = call.options["headers"] as? [String: String] {
108
+ headers = sheaders
109
+ }
110
+ var pipEnabled: Bool = true
111
+ if let spipEnabled = call.options["pipEnabled"] as? Bool {
112
+ pipEnabled = spipEnabled
113
+ }
114
+ var bkModeEnabled: Bool = true
115
+ if let sbkModeEnabled = call.options["bkmodeEnabled"] as? Bool {
116
+ bkModeEnabled = sbkModeEnabled
117
+ }
118
+ var shControls: Bool = true
119
+ if let shoControls = call.options["showControls"] as? Bool {
120
+ shControls = shoControls
121
+ }
122
+ var disMode: String = "all"
123
+ if let dispMode = call.options["displayMode"] as? String {
124
+ disMode = dispMode
125
+ }
126
+ var title: String?
127
+ if let stitle = call.options["title"] as? String {
128
+ title = stitle
129
+ }
130
+ var smallTitle: String?
131
+ if let ssmallTitle = call.options["smallTitle"] as? String {
132
+ smallTitle = ssmallTitle
133
+ }
134
+ var artwork: String?
135
+ if let sartwork = call.options["artwork"] as? String {
136
+ artwork = sartwork
137
+ }
138
+ self.fsPlayerId = playerId
139
+ self.mode = mode
140
+ self.videoRate = mRate
141
+ self.exitOnEnd = exitOnEnd
142
+ self.loopOnEnd = loopOnEnd
143
+ self.pipEnabled = pipEnabled
144
+ self.headers = headers
145
+ if !self.pipEnabled {isPIPModeAvailable = false}
146
+ self.backModeEnabled = bkModeEnabled
147
+ self.showControls = shControls
148
+ self.displayMode = disMode
149
+ self.title = title
150
+ self.smallTitle = smallTitle
151
+ self.artwork = artwork
152
+ if mode == "fullscreen" {
153
+ guard let videoPath = call.options["url"] as? String else {
154
+ let error: String = "Must provide a video url"
155
+ print(error)
156
+ call.resolve([ "result": false, "method": "initPlayer", "message": error])
157
+ return
158
+ }
159
+ var subTitlePath: String = ""
160
+ if let stPath = call.options["subtitle"] as? String {
161
+ subTitlePath = stPath
162
+ }
163
+ var subTitleLanguage: String = ""
164
+ if let stLanguage = call.options["language"] as? String {
165
+ subTitleLanguage = stLanguage
166
+ }
167
+
168
+ let subTitleOptions: [String: Any] = call.getObject("subtitleOptions") ?? [:]
169
+
170
+ if videoPath == "internal" {
171
+ DispatchQueue.main.async { [weak self] in
172
+ if let videoPickerViewController =
173
+ self?.implementation.pickVideoFromInternal(
174
+ rate: self?.videoRate ?? 1.0,
175
+ exitOnEnd: self?.exitOnEnd ?? true,
176
+ loopOnEnd: self?.loopOnEnd ?? false,
177
+ pipEnabled: self?.pipEnabled ?? true,
178
+ backModeEnabled: self?.backModeEnabled ?? true,
179
+ showControls: self?.showControls ?? true,
180
+ displayMode: self?.displayMode ?? "all") {
181
+ self?.bridge?.viewController?.present(
182
+ videoPickerViewController,
183
+ animated: true, completion: {return})
184
+ }
185
+ }
186
+
187
+ } else {
188
+ let dictUrl: [String: Any] =
189
+ getURLFromFilePath(filePath: videoPath)
190
+ if let message = dictUrl["message"] as? String {
191
+ if message.count > 0 {
192
+ call.resolve([ "result": false, "method": "initPlayer",
193
+ "message": message])
194
+ return
195
+ }
196
+ }
197
+ guard let url = dictUrl["url"] as? URL else {
198
+ call.resolve([ "result": false, "method": "initPlayer",
199
+ "message": "url not defined"])
200
+ return
201
+ }
202
+ var subTitle: URL?
203
+ if subTitlePath.count > 0 {
204
+
205
+ let dictSubTitle: [String: Any] =
206
+ getURLFromFilePath(filePath: subTitlePath)
207
+ if let message = dictSubTitle["message"] as? String {
208
+ if message.count > 0 {
209
+ call.resolve([ "result": false, "method": "initPlayer",
210
+ "message": message])
211
+ return
212
+ }
213
+ }
214
+ guard let sturl = dictSubTitle["url"] as? URL else {
215
+ call.resolve([ "result": false, "method": "initPlayer",
216
+ "message": "subtitle url not defined"])
217
+ return
218
+ }
219
+ subTitle = sturl
220
+ }
221
+ guard let call = self.call else { return }
222
+ self.createVideoPlayerFullscreenView(
223
+ call: call, videoUrl: url, rate: videoRate,
224
+ exitOnEnd: exitOnEnd, loopOnEnd: loopOnEnd,
225
+ pipEnabled: pipEnabled,
226
+ backModeEnabled: backModeEnabled,
227
+ showControls: showControls,
228
+ displayMode: displayMode,
229
+ subTitleUrl: subTitle,
230
+ subTitleLanguage: subTitleLanguage,
231
+ subTitleOptions: subTitleOptions,
232
+ headers: headers,
233
+ title: title,
234
+ smallTitle: smallTitle,
235
+ artwork: artwork)
236
+
237
+ }
238
+ } else {
239
+ call.resolve([ "result": false,
240
+ "method": "initPlayer",
241
+ "message": "Not implemented"])
242
+ return
243
+ }
244
+ }
245
+ // swiftlint:enable function_body_length
246
+ // swiftlint:enable cyclomatic_complexity
247
+
248
+ // MARK: - Play the given player
249
+
250
+ @objc func isPlaying(_ call: CAPPluginCall) {
251
+ self.call = call
252
+ guard let playerId = call.options["playerId"] as? String else {
253
+ let error: String = "Must provide a playerId"
254
+ print(error)
255
+ call.resolve([ "result": false, "method": "isPlaying", "message": error])
256
+ return
257
+ }
258
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
259
+
260
+ if let playerView = self.videoPlayerFullScreenView {
261
+ DispatchQueue.main.async {
262
+ let isPlaying: Bool = playerView.isPlaying
263
+ call.resolve([ "result": true, "method": "isPlaying", "value": isPlaying])
264
+ return
265
+ }
266
+ } else {
267
+ let error: String = "Fullscreen player not found"
268
+ print(error)
269
+ call.resolve([ "result": false, "method": "isPlaying", "message": error])
270
+ return
271
+ }
272
+ }
273
+ }
274
+ // MARK: - Play the given player
275
+
276
+ @objc func play(_ call: CAPPluginCall) {
277
+ self.call = call
278
+ guard let playerId = call.options["playerId"] as? String else {
279
+ let error: String = "Must provide a playerId"
280
+ print(error)
281
+ call.resolve([ "result": false, "method": "play", "message": error])
282
+ return
283
+ }
284
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
285
+
286
+ if let playerView = self.videoPlayerFullScreenView {
287
+ DispatchQueue.main.async {
288
+ playerView.play()
289
+ call.resolve([ "result": true, "method": "play", "value": true])
290
+ return
291
+ }
292
+ } else {
293
+ let error: String = "Fullscreen player not found"
294
+ print(error)
295
+ call.resolve([ "result": false, "method": "play", "message": error])
296
+ return
297
+ }
298
+ }
299
+ }
300
+
301
+ // MARK: - Pause the given player
302
+
303
+ @objc func pause(_ call: CAPPluginCall) {
304
+ self.call = call
305
+
306
+ guard let playerId = call.options["playerId"] as? String else {
307
+ let error: String = "Must provide a playerId"
308
+ print(error)
309
+ call.resolve([ "result": false, "method": "pause", "message": error])
310
+ return
311
+ }
312
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
313
+ if let playerView = self.videoPlayerFullScreenView {
314
+ DispatchQueue.main.async {
315
+ playerView.pause()
316
+ call.resolve([ "result": true, "method": "pause", "value": true])
317
+ return
318
+ }
319
+ } else {
320
+ let error: String = "Fullscreen player not found"
321
+ print(error)
322
+ call.resolve([ "result": false, "method": "pause", "message": error])
323
+ return
324
+ }
325
+ }
326
+ }
327
+
328
+ // MARK: - get Duration for the given player
329
+
330
+ @objc func getDuration(_ call: CAPPluginCall) {
331
+ self.call = call
332
+
333
+ guard let playerId = call.options["playerId"] as? String else {
334
+ let error: String = "Must provide a playerId"
335
+ print(error)
336
+ call.resolve([ "result": false, "method": "getDuration", "message": error])
337
+ return
338
+ }
339
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
340
+ if let playerView = self.videoPlayerFullScreenView {
341
+ DispatchQueue.main.async {
342
+ let duration: Double = playerView.getDuration()
343
+ call.resolve([ "result": true, "method": "getDuration", "value": duration])
344
+ return
345
+ }
346
+ } else {
347
+ let error: String = "Fullscreen playerId not found"
348
+ print(error)
349
+ call.resolve([ "result": false, "method": "getDuration", "message": error])
350
+ return
351
+ }
352
+ }
353
+ }
354
+
355
+ // MARK: - get CurrentTime for the given player
356
+
357
+ @objc func getCurrentTime(_ call: CAPPluginCall) {
358
+ self.call = call
359
+
360
+ guard let playerId = call.options["playerId"] as? String else {
361
+ let error: String = "Must provide a playerId"
362
+ print(error)
363
+ call.resolve([ "result": false, "method": "getCurrentTime", "message": error])
364
+ return
365
+ }
366
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
367
+ if let playerView = self.videoPlayerFullScreenView {
368
+ DispatchQueue.main.async {
369
+ let currentTime: Double = playerView.getCurrentTime()
370
+ call.resolve([ "result": true, "method": "getCurrentTime",
371
+ "value": currentTime])
372
+ return
373
+ }
374
+ } else {
375
+ let error: String = "Fullscreen playerId not found"
376
+ print(error)
377
+ call.resolve([ "result": false, "method": "getCurrentTime", "message": error])
378
+ return
379
+ }
380
+
381
+ }
382
+ }
383
+
384
+ // MARK: - set CurrentTime for the given player
385
+
386
+ @objc func setCurrentTime(_ call: CAPPluginCall) {
387
+ self.call = call
388
+
389
+ guard let playerId = call.options["playerId"] as? String else {
390
+ let error: String = "Must provide a playerId"
391
+ print(error)
392
+ call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
393
+ return
394
+ }
395
+ guard let seekTime = call.options["seektime"] as? Double else {
396
+ let error: String = "Must provide a time in second"
397
+ print(error)
398
+ call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
399
+ return
400
+ }
401
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
402
+ if let playerView = self.videoPlayerFullScreenView {
403
+ DispatchQueue.main.async {
404
+ playerView.setCurrentTime(time: seekTime)
405
+ call.resolve([ "result": true, "method": "setCurrentTime",
406
+ "value": seekTime])
407
+ return
408
+ }
409
+ } else {
410
+ let error: String = "Fullscreen playerId not found"
411
+ print(error)
412
+ call.resolve([ "result": false, "method": "setCurrentTime", "message": error])
413
+ return
414
+ }
415
+ }
416
+ }
417
+
418
+ // MARK: - get Volume for the given player
419
+
420
+ @objc func getVolume(_ call: CAPPluginCall) {
421
+ self.call = call
422
+
423
+ guard let playerId = call.options["playerId"] as? String else {
424
+ let error: String = "Must provide a playerId"
425
+ print(error)
426
+ call.resolve([ "result": false, "method": "getVolume", "message": error])
427
+ return
428
+ }
429
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
430
+ if let playerView = self.videoPlayerFullScreenView {
431
+ DispatchQueue.main.async {
432
+ let volume: Float = playerView.getVolume()
433
+ call.resolve([ "result": true, "method": "getVolume", "value": volume])
434
+ return
435
+ }
436
+ } else {
437
+ let error: String = "Fullscreen playerId not found"
438
+ print(error)
439
+ call.resolve([ "result": false, "method": "getVolume", "message": error])
440
+ return
441
+ }
442
+ }
443
+ }
444
+
445
+ // MARK: - set Volume for the given player
446
+
447
+ @objc func setVolume(_ call: CAPPluginCall) {
448
+ self.call = call
449
+
450
+ guard let playerId = call.options["playerId"] as? String else {
451
+ let error: String = "Must provide a playerId"
452
+ print(error)
453
+ call.resolve([ "result": false, "method": "setVolume", "message": error])
454
+ return
455
+ }
456
+ guard let volume = call.options["volume"] as? Float else {
457
+ let error: String = "Must provide a volume value"
458
+ print(error)
459
+ call.resolve([ "result": false, "method": "setVolume", "message": error])
460
+
461
+ return
462
+ }
463
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
464
+ if let playerView = self.videoPlayerFullScreenView {
465
+ DispatchQueue.main.async {
466
+ playerView.setVolume(volume: volume)
467
+ call.resolve([ "result": true, "method": "setVolume", "value": volume])
468
+ return
469
+ }
470
+ } else {
471
+ let error: String = "Fullscreen playerId not found"
472
+ print(error)
473
+ call.resolve([ "result": false, "method": "setVolume", "message": error])
474
+ return
475
+ }
476
+ }
477
+
478
+ }
479
+
480
+ // MARK: - get Muted for the given player
481
+
482
+ @objc func getMuted(_ call: CAPPluginCall) {
483
+ self.call = call
484
+
485
+ guard let playerId = call.options["playerId"] as? String else {
486
+ let error: String = "Must provide a playerId"
487
+ print(error)
488
+ call.resolve([ "result": false, "method": "getMuted", "message": error])
489
+ return
490
+ }
491
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
492
+ if let playerView = self.videoPlayerFullScreenView {
493
+ DispatchQueue.main.async {
494
+ let muted: Bool = playerView.getMuted()
495
+ call.resolve([ "result": true, "method": "getMuted", "value": muted])
496
+ return
497
+ }
498
+ } else {
499
+ let error: String = "Fullscreen playerId not found"
500
+ print(error)
501
+ call.resolve([ "result": false, "method": "getMuted", "message": error])
502
+ return
503
+ }
504
+ }
505
+ }
506
+
507
+ // MARK: - set Muted for the given player
508
+
509
+ @objc func setMuted(_ call: CAPPluginCall) {
510
+ self.call = call
511
+
512
+ guard let playerId = call.options["playerId"] as? String else {
513
+ let error: String = "Must provide a playerId"
514
+ print(error)
515
+ call.resolve([ "result": false, "method": "setMuted", "message": error])
516
+ return
517
+ }
518
+ guard let muted = call.options["muted"] as? Bool else {
519
+ let error: String = "Must provide a boolean true/false"
520
+ print(error)
521
+ call.resolve([ "result": false, "method": "setMuted", "message": error])
522
+ return
523
+ }
524
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
525
+ if let playerView = self.videoPlayerFullScreenView {
526
+ DispatchQueue.main.async {
527
+ playerView.setMuted(muted: muted)
528
+ call.resolve([ "result": true, "method": "setMuted", "value": muted])
529
+ return
530
+ }
531
+ } else {
532
+ let error: String = "Fullscreen playerId not found"
533
+ print(error)
534
+ call.resolve([ "result": false, "method": "setMuted", "message": error])
535
+ return
536
+ }
537
+ }
538
+ }
539
+
540
+ // MARK: - Stop all player(s) playing
541
+
542
+ @objc func stopAllPlayers(_ call: CAPPluginCall) {
543
+ self.call = call
544
+ if self.mode == "fullscreen" {
545
+ if let playerView = self.videoPlayerFullScreenView {
546
+ DispatchQueue.main.async {
547
+ if playerView.isPlaying {
548
+ playerView.pause()
549
+ }
550
+ call.resolve([ "result": true, "method": "stopAllPlayers", "value": true])
551
+ return
552
+ }
553
+ } else {
554
+ let error: String = "Fullscreen player not found"
555
+ print(error)
556
+ call.resolve([ "result": false, "method": "stopAllPlayers", "message": error])
557
+ return
558
+ }
559
+
560
+ }
561
+ }
562
+
563
+ // MARK: - get Rate for the given player
564
+
565
+ @objc func getRate(_ call: CAPPluginCall) {
566
+ self.call = call
567
+
568
+ guard let playerId = call.options["playerId"] as? String else {
569
+ let error: String = "Must provide a playerId"
570
+ print(error)
571
+ call.resolve([ "result": false, "method": "getRate", "message": error])
572
+ return
573
+ }
574
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
575
+ if let playerView = self.videoPlayerFullScreenView {
576
+ DispatchQueue.main.async {
577
+ let rate: Float = playerView.getRate()
578
+ call.resolve([ "result": true, "method": "getRate", "value": rate])
579
+ return
580
+ }
581
+ } else {
582
+ let error: String = "Fullscreen playerId not found"
583
+ print(error)
584
+ call.resolve([ "result": false, "method": "getRate", "message": error])
585
+ return
586
+ }
587
+ }
588
+ }
589
+
590
+ // MARK: - set Rate for the given player
591
+
592
+ @objc func setRate(_ call: CAPPluginCall) {
593
+ self.call = call
594
+
595
+ guard let playerId = call.options["playerId"] as? String else {
596
+ let error: String = "Must provide a playerId"
597
+ print(error)
598
+ call.resolve([ "result": false, "method": "setRate", "message": error])
599
+ return
600
+ }
601
+ guard let rate = call.options["rate"] as? Float else {
602
+ let error: String = "Must provide a rate value"
603
+ print(error)
604
+ call.resolve([ "result": false, "method": "setRate", "message": error])
605
+
606
+ return
607
+ }
608
+ self.videoRate = rateList.contains(rate) ? rate : 1.0
609
+
610
+ if self.mode == "fullscreen" && self.fsPlayerId == playerId {
611
+ if let playerView = self.videoPlayerFullScreenView {
612
+ //34567890123456789012345678901234567890
613
+ DispatchQueue.main.async {
614
+ playerView.setRate(rate: self.videoRate)
615
+ call.resolve([ "result": true, "method": "setRate",
616
+ "value": self.videoRate])
617
+ return
618
+ }
619
+ } else {
620
+ let error: String = "Fullscreen playerId not found"
621
+ print(error)
622
+ call.resolve([ "result": false, "method": "setRate", "message": error])
623
+ return
624
+ }
625
+ }
626
+
627
+ }
628
+
629
+ }
630
+
631
+ // swiftlint:enable type_body_length
632
632
  // swiftlint:enable file_length