bitmovin-player-react-native 0.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.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/RNBitmovinPlayer.podspec +23 -0
  4. package/android/build.gradle +55 -0
  5. package/android/src/main/AndroidManifest.xml +4 -0
  6. package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +279 -0
  7. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +264 -0
  8. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +139 -0
  9. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +33 -0
  10. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +162 -0
  11. package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Events.kt +15 -0
  12. package/ios/Event+JSON.swift +132 -0
  13. package/ios/PlayerModule.m +61 -0
  14. package/ios/PlayerModule.swift +347 -0
  15. package/ios/RCTConvert+BitmovinPlayer.swift +79 -0
  16. package/ios/RNBitmovinPlayer.h +7 -0
  17. package/ios/RNBitmovinPlayer.xcodeproj/project.pbxproj +303 -0
  18. package/ios/RNPlayerView+PlayerListener.swift +83 -0
  19. package/ios/RNPlayerView.swift +50 -0
  20. package/ios/RNPlayerViewManager.m +29 -0
  21. package/ios/RNPlayerViewManager.swift +60 -0
  22. package/lib/index.d.ts +486 -0
  23. package/lib/index.js +218 -0
  24. package/lib/index.mjs +191 -0
  25. package/package.json +82 -0
  26. package/src/components/PlayerView/events.ts +69 -0
  27. package/src/components/PlayerView/index.tsx +106 -0
  28. package/src/components/PlayerView/native.ts +17 -0
  29. package/src/components/index.ts +1 -0
  30. package/src/events.ts +184 -0
  31. package/src/hooks/index.ts +1 -0
  32. package/src/hooks/usePlayer.ts +10 -0
  33. package/src/hooks/useProxy.ts +36 -0
  34. package/src/index.ts +5 -0
  35. package/src/player.ts +229 -0
  36. package/src/source.ts +95 -0
@@ -0,0 +1,132 @@
1
+ import BitmovinPlayer
2
+
3
+ extension Source {
4
+ func toJSON() -> [AnyHashable: Any] {
5
+ var json: [AnyHashable: Any] = [
6
+ "duration": duration,
7
+ "isActive": isActive,
8
+ "loadingState": loadingState,
9
+ "isAttachedToPlayer": isAttachedToPlayer
10
+ ]
11
+ if let metadata = metadata {
12
+ json["metadata"] = metadata
13
+ }
14
+ return json
15
+ }
16
+ }
17
+
18
+ extension SeekEvent {
19
+ func toJSON() -> [AnyHashable: Any] {
20
+ [
21
+ "name": name,
22
+ "timestamp": timestamp,
23
+ "from": [
24
+ "time": from.time,
25
+ "source": from.source.toJSON()
26
+ ],
27
+ "to": [
28
+ "time": to.time,
29
+ "source": to.source.toJSON()
30
+ ]
31
+ ]
32
+ }
33
+ }
34
+
35
+ extension TimeChangedEvent {
36
+ func toJSON() -> [AnyHashable: Any] {
37
+ ["name": name, "timestamp": timestamp, "currentTime": currentTime]
38
+ }
39
+ }
40
+
41
+ extension Event {
42
+ func toJSON() -> [AnyHashable: Any] {
43
+ ["name": name, "timestamp": timestamp]
44
+ }
45
+ }
46
+
47
+ extension NSError {
48
+ func toJSON() -> [AnyHashable: Any] {
49
+ [
50
+ "code": code,
51
+ "domain": domain,
52
+ "description": description,
53
+ "localizedDescription": localizedDescription
54
+ ]
55
+ }
56
+ }
57
+
58
+ extension DeficiencyData {
59
+ func toJSON() -> [AnyHashable: Any] {
60
+ var json: [AnyHashable: Any] = ["code": code, "message": message]
61
+ if let underlyingError = underlyingError {
62
+ json["underlyingError"] = underlyingError.toJSON()
63
+ }
64
+ return json
65
+ }
66
+ }
67
+
68
+ protocol ErrorEventType: Event {
69
+ associatedtype Code
70
+ var code: Code { get }
71
+ var data: DeficiencyData? { get }
72
+ var message: String { get }
73
+ }
74
+
75
+ extension ErrorEventType {
76
+ func toJSON() -> [AnyHashable: Any] {
77
+ var json: [AnyHashable: Any] = [
78
+ "name": name,
79
+ "timestamp": timestamp,
80
+ "code": code,
81
+ "message": message
82
+ ]
83
+ if let data = data {
84
+ json["data"] = data.toJSON()
85
+ }
86
+ return json
87
+ }
88
+ }
89
+
90
+ extension PlayerErrorEvent: ErrorEventType {
91
+ typealias Code = PlayerError.Code
92
+ }
93
+
94
+ extension PlayerWarningEvent: ErrorEventType {
95
+ typealias Code = PlayerWarning.Code
96
+ }
97
+
98
+ extension SourceErrorEvent: ErrorEventType {
99
+ typealias Code = SourceError.Code
100
+ }
101
+
102
+ extension SourceWarningEvent: ErrorEventType {
103
+ typealias Code = SourceWarning.Code
104
+ }
105
+
106
+ protocol SourceEventType: Event {
107
+ var source: Source { get }
108
+ }
109
+
110
+ extension SourceEventType {
111
+ func toJSON() -> [AnyHashable: Any] {
112
+ ["name": name, "timestamp": timestamp, "source": source.toJSON()]
113
+ }
114
+ }
115
+
116
+ extension SourceLoadEvent: SourceEventType {}
117
+ extension SourceLoadedEvent: SourceEventType {}
118
+ extension SourceUnloadedEvent: SourceEventType {}
119
+
120
+ protocol TimedEventType: Event {
121
+ var time: TimeInterval { get }
122
+ }
123
+
124
+ extension TimedEventType {
125
+ func toJSON() -> [AnyHashable: Any] {
126
+ ["name": name, "timestamp": timestamp, "time": time]
127
+ }
128
+ }
129
+
130
+ extension PlayEvent: TimedEventType {}
131
+ extension PausedEvent: TimedEventType {}
132
+ extension PlayingEvent: TimedEventType {}
@@ -0,0 +1,61 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RCT_EXTERN_REMAP_MODULE(PlayerModule, PlayerModule, NSObject)
4
+
5
+ // UUID generation is sync and runs on the JS thread so it should be as
6
+ // fast as possible to avoid perf issues.
7
+ RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(generateUUIDv4)
8
+
9
+ RCT_EXTERN_METHOD(initWithConfig:(NSString *)playerId config:(nullable id)config)
10
+ RCT_EXTERN_METHOD(loadSource:(NSString *)playerId config:(id)config)
11
+ RCT_EXTERN_METHOD(unload:(NSString *)playerId)
12
+ RCT_EXTERN_METHOD(play:(NSString *)playerId)
13
+ RCT_EXTERN_METHOD(pause:(NSString *)playerId)
14
+ RCT_EXTERN_METHOD(seek:(NSString *)playerId time:(nonnull NSNumber *)time)
15
+ RCT_EXTERN_METHOD(mute:(NSString *)playerId)
16
+ RCT_EXTERN_METHOD(unmute:(NSString *)playerId)
17
+ RCT_EXTERN_METHOD(destroy:(NSString *)playerId)
18
+ RCT_EXTERN_METHOD(setVolume:(NSString *)playerId volume:(nonnull NSNumber *)volume)
19
+ RCT_EXTERN_METHOD(
20
+ source:(NSString *)playerId
21
+ resolver:(RCTPromiseResolveBlock)resolve
22
+ rejecter:(RCTPromiseRejectBlock)reject)
23
+ RCT_EXTERN_METHOD(
24
+ getVolume:(NSString *)playerId
25
+ resolver:(RCTPromiseResolveBlock)resolve
26
+ rejecter:(RCTPromiseRejectBlock)reject)
27
+ RCT_EXTERN_METHOD(
28
+ currentTime:(NSString *)playerId
29
+ mode:(NSString *)mode
30
+ resolver:(RCTPromiseResolveBlock)resolve
31
+ rejecter:(RCTPromiseRejectBlock)reject)
32
+ RCT_EXTERN_METHOD(
33
+ duration:(NSString *)playerId
34
+ resolver:(RCTPromiseResolveBlock)resolve
35
+ rejecter:(RCTPromiseRejectBlock)reject)
36
+ RCT_EXTERN_METHOD(
37
+ isMuted:(NSString *)playerId
38
+ resolver:(RCTPromiseResolveBlock)resolve
39
+ rejecter:(RCTPromiseRejectBlock)reject)
40
+ RCT_EXTERN_METHOD(
41
+ isPlaying:(NSString *)playerId
42
+ resolver:(RCTPromiseResolveBlock)resolve
43
+ rejecter:(RCTPromiseRejectBlock)reject)
44
+ RCT_EXTERN_METHOD(
45
+ isPaused:(NSString *)playerId
46
+ resolver:(RCTPromiseResolveBlock)resolve
47
+ rejecter:(RCTPromiseRejectBlock)reject)
48
+ RCT_EXTERN_METHOD(
49
+ isLive:(NSString *)playerId
50
+ resolver:(RCTPromiseResolveBlock)resolve
51
+ rejecter:(RCTPromiseRejectBlock)reject)
52
+ RCT_EXTERN_METHOD(
53
+ isAirPlayActive:(NSString *)playerId
54
+ resolver:(RCTPromiseResolveBlock)resolve
55
+ rejecter:(RCTPromiseRejectBlock)reject)
56
+ RCT_EXTERN_METHOD(
57
+ isAirPlayAvailable:(NSString *)playerId
58
+ resolver:(RCTPromiseResolveBlock)resolve
59
+ rejecter:(RCTPromiseRejectBlock)reject)
60
+
61
+ @end
@@ -0,0 +1,347 @@
1
+ import BitmovinPlayer
2
+
3
+ @objc(PlayerModule)
4
+ class PlayerModule: NSObject, RCTBridgeModule {
5
+ /// Accessible react bridge reference.
6
+ @objc var bridge: RCTBridge!
7
+
8
+ /// In-memory dictionary mapping id <-> `Player`.
9
+ private var registry: [String: Player] = [:]
10
+
11
+ /// Exported module name to JS.
12
+ static func moduleName() -> String! {
13
+ "PlayerModule"
14
+ }
15
+
16
+ /// Requires module initialization from main thread.
17
+ static func requiresMainQueueSetup() -> Bool {
18
+ true
19
+ }
20
+
21
+ /// Dispatch methods on `UIManager` queue so all of them stay in sync with `RNPlayerViewManager`.
22
+ var methodQueue: DispatchQueue! {
23
+ bridge.uiManager.methodQueue
24
+ }
25
+
26
+ /**
27
+ Resolve the current `Player` instance associated with `id`. Intented to
28
+ be used by other RN bridge modules such as `RNPlayerViewManager`.
29
+ - Parameter id: Target player id.
30
+ - Returns: The player instance found if there's any.
31
+ */
32
+ @objc func player(with id: String) -> Player? {
33
+ registry[id]
34
+ }
35
+
36
+ /**
37
+ Synchronously generate a random UUID for `Player`s native id when no `nativeId` is provided
38
+ by the user.
39
+ - Returns: Random UUID RFC 4122 version 4.
40
+ */
41
+ @objc func generateUUIDv4() -> String {
42
+ UUID().uuidString
43
+ }
44
+
45
+ /**
46
+ Create a new `Player` instance for the given `config` if no one exists already.
47
+ - Parameter config: Player configuration options sent from JS.
48
+ */
49
+ @objc(initWithConfig:config:)
50
+ func initWithConfig(_ playerId: String, config: Any?) {
51
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
52
+ guard
53
+ self?.registry[playerId] == nil,
54
+ let playerConfig = RCTConvert.playerConfig(config)
55
+ else {
56
+ return
57
+ }
58
+ self?.registry[playerId] = PlayerFactory.create(playerConfig: playerConfig)
59
+ }
60
+ }
61
+
62
+ /**
63
+ Load the source of the given `playerId` with `config` options from JS.
64
+ - Parameter playerId: Target player.
65
+ - Parameter config: Source configuration options from JS.
66
+ */
67
+ @objc(loadSource:config:)
68
+ func loadSource(_ playerId: String, config: Any) {
69
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
70
+ guard
71
+ let player = self?.registry[playerId],
72
+ let sourceConfig = RCTConvert.sourceConfig(config)
73
+ else {
74
+ return
75
+ }
76
+ player.load(sourceConfig: sourceConfig)
77
+ }
78
+ }
79
+
80
+ /**
81
+ Call `.unload()` on `playerId`'s player.
82
+ - Parameter playerId: Target player Id.
83
+ */
84
+ @objc(unload:)
85
+ func unload(_ playerId: String) {
86
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
87
+ self?.registry[playerId]?.unload()
88
+ }
89
+ }
90
+
91
+ /**
92
+ Call `.play()` on `playerId`'s player.
93
+ - Parameter playerId: Target player Id.
94
+ */
95
+ @objc(play:)
96
+ func play(_ playerId: String) {
97
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
98
+ self?.registry[playerId]?.play()
99
+ }
100
+ }
101
+
102
+ /**
103
+ Call `.pause()` on `playerId`'s player.
104
+ - Parameter playerId: Target player Id.
105
+ */
106
+ @objc(pause:)
107
+ func pause(_ playerId: String) {
108
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
109
+ self?.registry[playerId]?.pause()
110
+ }
111
+ }
112
+
113
+ /**
114
+ Call `.seek(time:)` on `playerId`'s player.
115
+ - Parameter playerId: Target player Id.
116
+ - Parameter time: Time to seek in seconds.
117
+ */
118
+ @objc(seek:time:)
119
+ func seek(_ playerId: String, time: NSNumber) {
120
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
121
+ self?.registry[playerId]?.seek(time: time.doubleValue)
122
+ }
123
+ }
124
+
125
+ /**
126
+ Call `.mute()` on `playerId`'s player.
127
+ - Parameter playerId: Target player Id.
128
+ */
129
+ @objc(mute:)
130
+ func mute(_ playerId: String) {
131
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
132
+ self?.registry[playerId]?.mute()
133
+ }
134
+ }
135
+
136
+ /**
137
+ Call `.unmute()` on `playerId`'s player.
138
+ - Parameter playerId: Target player Id.
139
+ */
140
+ @objc(unmute:)
141
+ func unmute(_ playerId: String) {
142
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
143
+ self?.registry[playerId]?.unmute()
144
+ }
145
+ }
146
+
147
+ /**
148
+ Call `.destroy()` on `playerId`'s player.
149
+ - Parameter playerId: Target player Id.
150
+ */
151
+ @objc(destroy:)
152
+ func destroy(_ playerId: String) {
153
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
154
+ self?.registry[playerId]?.destroy()
155
+ }
156
+ }
157
+
158
+ /**
159
+ Call `.setVolume(volume:)` on `playerId`'s player.
160
+ - Parameter playerId: Target player Id.
161
+ - Parameter volume: Integer representing the volume level (between 0 to 100).
162
+ */
163
+ @objc(setVolume:volume:)
164
+ func setVolume(_ playerId: String, volume: NSNumber) {
165
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
166
+ self?.registry[playerId]?.volume = volume.intValue
167
+ }
168
+ }
169
+
170
+ /**
171
+ Resolve the source of `playerId`'s player.
172
+ - Parameter playerId: Target player Id.
173
+ - Parameter resolver: JS promise resolver.
174
+ - Parameter rejecter: JS promise rejecter.
175
+ */
176
+ @objc(source:resolver:rejecter:)
177
+ func source(
178
+ _ playerId: String,
179
+ resolver resolve: @escaping RCTPromiseResolveBlock,
180
+ rejecter reject: @escaping RCTPromiseRejectBlock
181
+ ) {
182
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
183
+ resolve(self?.registry[playerId]?.source?.toJSON())
184
+ }
185
+ }
186
+
187
+ /**
188
+ Resolve `playerId`'s current volume.
189
+ - Parameter playerId: Target player Id.
190
+ - Parameter resolver: JS promise resolver.
191
+ - Parameter rejecter: JS promise rejecter.
192
+ */
193
+ @objc(getVolume:resolver:rejecter:)
194
+ func getVolume(
195
+ _ playerId: String,
196
+ resolver resolve: @escaping RCTPromiseResolveBlock,
197
+ rejecter reject: @escaping RCTPromiseRejectBlock
198
+ ) {
199
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
200
+ resolve(self?.registry[playerId]?.volume)
201
+ }
202
+ }
203
+
204
+ /**
205
+ Resolve `playerId`'s current playback time.
206
+ - Parameter playerId: Target player Id.
207
+ - Parameter mode: Time mode: either relative or absolute. Can be empty.
208
+ - Parameter resolver: JS promise resolver.
209
+ - Parameter rejecter: JS promise rejecter.
210
+ */
211
+ @objc(currentTime:mode:resolver:rejecter:)
212
+ func currentTime(
213
+ _ playerId: String,
214
+ mode: String?,
215
+ resolver resolve: @escaping RCTPromiseResolveBlock,
216
+ rejecter reject: @escaping RCTPromiseRejectBlock
217
+ ) {
218
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
219
+ let player = self?.registry[playerId]
220
+ if let mode = mode {
221
+ resolve(player?.currentTime(RCTConvert.timeMode(mode)))
222
+ } else {
223
+ resolve(player?.currentTime)
224
+ }
225
+ }
226
+ }
227
+
228
+ /**
229
+ Resolve `playerId`'s active source duration.
230
+ - Parameter playerId: Target player Id.
231
+ - Parameter resolver: JS promise resolver.
232
+ - Parameter rejecter: JS promise rejecter.
233
+ */
234
+ @objc(duration:resolver:rejecter:)
235
+ func duration(
236
+ _ playerId: String,
237
+ resolver resolve: @escaping RCTPromiseResolveBlock,
238
+ rejecter reject: @escaping RCTPromiseRejectBlock
239
+ ) {
240
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
241
+ resolve(self?.registry[playerId]?.duration)
242
+ }
243
+ }
244
+
245
+ /**
246
+ Resolve `playerId`'s current muted state.
247
+ - Parameter playerId: Target player Id.
248
+ - Parameter resolver: JS promise resolver.
249
+ - Parameter rejecter: JS promise rejecter.
250
+ */
251
+ @objc(isMuted:resolver:rejecter:)
252
+ func isMuted(
253
+ _ playerId: String,
254
+ resolver resolve: @escaping RCTPromiseResolveBlock,
255
+ rejecter reject: @escaping RCTPromiseRejectBlock
256
+ ) {
257
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
258
+ resolve(self?.registry[playerId]?.isMuted)
259
+ }
260
+ }
261
+
262
+ /**
263
+ Resolve `playerId`'s current playing state.
264
+ - Parameter playerId: Target player Id.
265
+ - Parameter resolver: JS promise resolver.
266
+ - Parameter rejecter: JS promise rejecter.
267
+ */
268
+ @objc(isPlaying:resolver:rejecter:)
269
+ func isPlaying(
270
+ _ playerId: String,
271
+ resolver resolve: @escaping RCTPromiseResolveBlock,
272
+ rejecter reject: @escaping RCTPromiseRejectBlock
273
+ ) {
274
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
275
+ resolve(self?.registry[playerId]?.isPlaying)
276
+ }
277
+ }
278
+
279
+ /**
280
+ Resolve `playerId`'s current paused state.
281
+ - Parameter playerId: Target player Id.
282
+ - Parameter resolver: JS promise resolver.
283
+ - Parameter rejecter: JS promise rejecter.
284
+ */
285
+ @objc(isPaused:resolver:rejecter:)
286
+ func isPaused(
287
+ _ playerId: String,
288
+ resolver resolve: @escaping RCTPromiseResolveBlock,
289
+ rejecter reject: @escaping RCTPromiseRejectBlock
290
+ ) {
291
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
292
+ resolve(self?.registry[playerId]?.isPaused)
293
+ }
294
+ }
295
+
296
+ /**
297
+ Resolve `playerId`'s live streaming state.
298
+ `true` if source is a live streaming.
299
+ - Parameter playerId: Target player Id.
300
+ - Parameter resolver: JS promise resolver.
301
+ - Parameter rejecter: JS promise rejecter.
302
+ */
303
+ @objc(isLive:resolver:rejecter:)
304
+ func isLive(
305
+ _ playerId: String,
306
+ resolver resolve: @escaping RCTPromiseResolveBlock,
307
+ rejecter reject: @escaping RCTPromiseRejectBlock
308
+ ) {
309
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
310
+ resolve(self?.registry[playerId]?.isLive)
311
+ }
312
+ }
313
+
314
+ /**
315
+ Resolve `playerId`'s air play activation state.
316
+ - Parameter playerId: Target player Id.
317
+ - Parameter resolver: JS promise resolver.
318
+ - Parameter rejecter: JS promise rejecter.
319
+ */
320
+ @objc(isAirPlayActive:resolver:rejecter:)
321
+ func isAirPlayActive(
322
+ _ playerId: String,
323
+ resolver resolve: @escaping RCTPromiseResolveBlock,
324
+ rejecter reject: @escaping RCTPromiseRejectBlock
325
+ ) {
326
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
327
+ resolve(self?.registry[playerId]?.isAirPlayActive)
328
+ }
329
+ }
330
+
331
+ /**
332
+ Resolve `playerId`'s air play availability state.
333
+ - Parameter playerId: Target player Id.
334
+ - Parameter resolver: JS promise resolver.
335
+ - Parameter rejecter: JS promise rejecter.
336
+ */
337
+ @objc(isAirPlayAvailable:resolver:rejecter:)
338
+ func isAirPlayAvailable(
339
+ _ playerId: String,
340
+ resolver resolve: @escaping RCTPromiseResolveBlock,
341
+ rejecter reject: @escaping RCTPromiseRejectBlock
342
+ ) {
343
+ bridge.uiManager.addUIBlock { [weak self] _, _ in
344
+ resolve(self?.registry[playerId]?.isAirPlayAvailable)
345
+ }
346
+ }
347
+ }
@@ -0,0 +1,79 @@
1
+ import Foundation
2
+ import BitmovinPlayer
3
+
4
+ extension RCTConvert {
5
+ /**
6
+ Utility method to convert a JS object into `PlayerConfig`.
7
+ - Parameter json: JS object
8
+ - Returns: Generated `Playerconfig`
9
+ */
10
+ static func playerConfig(_ json: Any?) -> PlayerConfig? {
11
+ let playerConfig = PlayerConfig()
12
+ guard let json = json as? [String: Any?] else {
13
+ return playerConfig
14
+ }
15
+ if let licenseKey = json["licenseKey"] as? String {
16
+ playerConfig.key = licenseKey
17
+ }
18
+ return playerConfig
19
+ }
20
+
21
+ /**
22
+ Utility method to convert a JS object into `SourceConfig`.
23
+ - Parameter json: JS object
24
+ - Returns: Generated `SourceConfig`
25
+ */
26
+ static func sourceConfig(_ json: Any?) -> SourceConfig? {
27
+ guard let json = json as? [String: Any?] else {
28
+ return nil
29
+ }
30
+ let sourceConfig = SourceConfig(
31
+ url: RCTConvert.nsurl(json["url"]),
32
+ type: RCTConvert.sourceType(json["type"])
33
+ )
34
+ if let title = json["title"] as? String {
35
+ sourceConfig.title = title
36
+ }
37
+ if let poster = json["poster"] as? String {
38
+ sourceConfig.posterSource = RCTConvert.nsurl(poster)
39
+ }
40
+ if let isPosterPersistent = json["isPosterPersistent"] as? Bool {
41
+ sourceConfig.isPosterPersistent = isPosterPersistent
42
+ }
43
+ return sourceConfig
44
+ }
45
+
46
+ /**
47
+ Utility method to convert a JS object into `SourceType`.
48
+ - Parameter json: JS object
49
+ - Returns: Generated `SourceType`
50
+ */
51
+ static func sourceType(_ json: Any?) -> SourceType {
52
+ guard let json = json as? String else {
53
+ return .none
54
+ }
55
+ switch json {
56
+ case "none": return .none
57
+ case "hls": return .hls
58
+ case "dash": return .dash
59
+ case "progressive": return .progressive
60
+ default: return .none
61
+ }
62
+ }
63
+
64
+ /**
65
+ Utility method to convert a JS object into `TimeMode`.
66
+ - Parameter json: JS object
67
+ - Returns: Generated `TimeMode`
68
+ */
69
+ static func timeMode(_ json: Any?) -> TimeMode {
70
+ guard let json = json as? String else {
71
+ return .absoluteTime
72
+ }
73
+ switch json {
74
+ case "absolute": return .absoluteTime
75
+ case "relative": return .relativeTime
76
+ default: return .absoluteTime
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,7 @@
1
+ #import <React/RCTLog.h>
2
+ #import <React/RCTBridgeModule.h>
3
+ #import <React/RCTUIManager.h>
4
+ #import <React/RCTUIManagerUtils.h>
5
+ #import <React/RCTViewManager.h>
6
+ #import <React/RCTViewManager.h>
7
+ #import <React/RCTComponent.h>