bitmovin-player-react-native 0.1.0 → 0.2.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.
- package/README.md +163 -1
- package/RNBitmovinPlayer.podspec +3 -3
- package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +191 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +116 -101
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +69 -38
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +10 -26
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/Registry.kt +11 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +178 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +20 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +128 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Events.kt +11 -2
- package/ios/DrmModule.m +16 -0
- package/ios/DrmModule.swift +442 -0
- package/ios/Event+JSON.swift +31 -0
- package/ios/PlayerModule.m +21 -25
- package/ios/PlayerModule.swift +122 -120
- package/ios/RCTConvert+BitmovinPlayer.swift +131 -12
- package/ios/RNPlayerView+PlayerListener.swift +12 -0
- package/ios/RNPlayerView.swift +5 -3
- package/ios/RNPlayerViewManager.m +3 -1
- package/ios/RNPlayerViewManager.swift +4 -21
- package/ios/Registry.swift +5 -0
- package/ios/SourceModule.m +30 -0
- package/ios/SourceModule.swift +187 -0
- package/ios/UuidModule.m +9 -0
- package/ios/UuidModule.swift +23 -0
- package/lib/index.d.ts +670 -235
- package/lib/index.js +257 -106
- package/lib/index.mjs +260 -112
- package/package.json +5 -4
- package/src/components/PlayerView/events.ts +24 -18
- package/src/components/PlayerView/index.tsx +29 -26
- package/src/drm/fairplayConfig.ts +90 -0
- package/src/drm/index.ts +178 -0
- package/src/drm/widevineConfig.ts +37 -0
- package/src/events.ts +67 -6
- package/src/hooks/useProxy.ts +19 -15
- package/src/index.ts +5 -3
- package/src/nativeInstance.ts +64 -0
- package/src/player.ts +51 -42
- package/src/source.ts +88 -8
- package/src/subtitleTrack.ts +60 -0
- package/src/utils.ts +15 -0
package/ios/RNPlayerView.swift
CHANGED
|
@@ -2,7 +2,7 @@ import BitmovinPlayer
|
|
|
2
2
|
|
|
3
3
|
@objc(RNPlayerView)
|
|
4
4
|
class RNPlayerView: UIView {
|
|
5
|
-
///
|
|
5
|
+
/// React component events. Directly mapped to props in `NativePlayerView`.
|
|
6
6
|
@objc var onEvent: RCTBubblingEventBlock?
|
|
7
7
|
@objc var onPlayerActive: RCTBubblingEventBlock?
|
|
8
8
|
@objc var onPlayerError: RCTBubblingEventBlock?
|
|
@@ -23,9 +23,11 @@ class RNPlayerView: UIView {
|
|
|
23
23
|
@objc var onSourceUnloaded: RCTBubblingEventBlock?
|
|
24
24
|
@objc var onSourceError: RCTBubblingEventBlock?
|
|
25
25
|
@objc var onSourceWarning: RCTBubblingEventBlock?
|
|
26
|
+
@objc var onSubtitleAdded: RCTBubblingEventBlock?
|
|
27
|
+
@objc var onSubtitleRemoved: RCTBubblingEventBlock?
|
|
28
|
+
@objc var onSubtitleChanged: RCTBubblingEventBlock?
|
|
26
29
|
|
|
27
|
-
///
|
|
28
|
-
/// Get's initialized when there's a player instance ready to be used.
|
|
30
|
+
/// The `PlayerView` subview.
|
|
29
31
|
var playerView: PlayerView? {
|
|
30
32
|
willSet {
|
|
31
33
|
newValue?.autoresizingMask = [
|
|
@@ -22,8 +22,10 @@ RCT_EXPORT_VIEW_PROPERTY(onSourceLoaded, RCTBubblingEventBlock)
|
|
|
22
22
|
RCT_EXPORT_VIEW_PROPERTY(onSourceUnloaded, RCTBubblingEventBlock)
|
|
23
23
|
RCT_EXPORT_VIEW_PROPERTY(onSourceError, RCTBubblingEventBlock)
|
|
24
24
|
RCT_EXPORT_VIEW_PROPERTY(onSourceWarning, RCTBubblingEventBlock)
|
|
25
|
+
RCT_EXPORT_VIEW_PROPERTY(onSubtitleAdded, RCTBubblingEventBlock)
|
|
26
|
+
RCT_EXPORT_VIEW_PROPERTY(onSubtitleRemoved, RCTBubblingEventBlock)
|
|
27
|
+
RCT_EXPORT_VIEW_PROPERTY(onSubtitleChanged, RCTBubblingEventBlock)
|
|
25
28
|
|
|
26
29
|
RCT_EXTERN_METHOD(attachPlayer:(nonnull NSNumber *)viewId playerId:(NSString *)playerId)
|
|
27
|
-
RCT_EXTERN_METHOD(detachPlayer:(nonnull NSNumber *)viewId playerId:(NSString *)playerId)
|
|
28
30
|
|
|
29
31
|
@end
|
|
@@ -3,8 +3,8 @@ import Foundation
|
|
|
3
3
|
|
|
4
4
|
@objc(RNPlayerViewManager)
|
|
5
5
|
class RNPlayerViewManager: RCTViewManager {
|
|
6
|
-
///
|
|
7
|
-
override
|
|
6
|
+
/// Initialize module on main thread.
|
|
7
|
+
override static func requiresMainQueueSetup() -> Bool {
|
|
8
8
|
true
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -19,11 +19,11 @@ class RNPlayerViewManager: RCTViewManager {
|
|
|
19
19
|
- Parameter viewId: `RNPlayerView` id inside `UIManager`'s registry.
|
|
20
20
|
- Parameter playerId: `Player` instance id inside `PlayerModule`'s registry.
|
|
21
21
|
*/
|
|
22
|
-
@objc func attachPlayer(_ viewId: NSNumber, playerId:
|
|
22
|
+
@objc func attachPlayer(_ viewId: NSNumber, playerId: NativeId) {
|
|
23
23
|
bridge.uiManager.addUIBlock { [weak self] _, views in
|
|
24
24
|
guard
|
|
25
25
|
let view = views?[viewId] as? RNPlayerView,
|
|
26
|
-
let player = self?.getPlayerModule()?.
|
|
26
|
+
let player = self?.getPlayerModule()?.retrieve(playerId)
|
|
27
27
|
else {
|
|
28
28
|
return
|
|
29
29
|
}
|
|
@@ -35,23 +35,6 @@ class RNPlayerViewManager: RCTViewManager {
|
|
|
35
35
|
player.add(listener: view)
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
Remove `RNPlayerView` from its associated `Player` listeners list.
|
|
41
|
-
- Parameter viewId: `RNPlayerView` id inside `UIManager`'s registry.
|
|
42
|
-
- Parameter playerId: `Player` instance id inside `PlayerModule`'s registry.
|
|
43
|
-
*/
|
|
44
|
-
@objc func detachPlayer(_ viewId: NSNumber, playerId: String) {
|
|
45
|
-
bridge.uiManager.addUIBlock { [weak self] _, views in
|
|
46
|
-
guard
|
|
47
|
-
let view = views?[viewId] as? RNPlayerView,
|
|
48
|
-
let player = self?.getPlayerModule()?.player(with: playerId)
|
|
49
|
-
else {
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
player.remove(listener: view)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
38
|
|
|
56
39
|
/// Fetches the initialized `PlayerModule` instance on RN's bridge object.
|
|
57
40
|
private func getPlayerModule() -> PlayerModule? {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_REMAP_MODULE(SourceModule, SourceModule, NSObject)
|
|
4
|
+
|
|
5
|
+
RCT_EXTERN_METHOD(initWithConfig:(NSString *)nativeId config:(nullable id)config)
|
|
6
|
+
RCT_EXTERN_METHOD(initWithDrmConfig:(NSString *)nativeId drmNativeId:(NSString *)drmNativeId config:(nullable id)config)
|
|
7
|
+
RCT_EXTERN_METHOD(destroy:(NSString *)nativeId)
|
|
8
|
+
RCT_EXTERN_METHOD(
|
|
9
|
+
isAttachedToPlayer:(NSString *)nativeId
|
|
10
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
11
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
12
|
+
RCT_EXTERN_METHOD(
|
|
13
|
+
isActive:(NSString *)nativeId
|
|
14
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
15
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
16
|
+
RCT_EXTERN_METHOD(
|
|
17
|
+
duration:(NSString *)nativeId
|
|
18
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
19
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
20
|
+
RCT_EXTERN_METHOD(
|
|
21
|
+
loadingState:(NSString *)nativeId
|
|
22
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
23
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
24
|
+
RCT_EXTERN_METHOD(
|
|
25
|
+
getMetadata:(NSString *)nativeId
|
|
26
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
27
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
28
|
+
RCT_EXTERN_METHOD(setMetadata:(NSString *)nativeId metadata:(nullable id)metadata)
|
|
29
|
+
|
|
30
|
+
@end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import BitmovinPlayer
|
|
2
|
+
|
|
3
|
+
@objc(SourceModule)
|
|
4
|
+
class SourceModule: NSObject, RCTBridgeModule {
|
|
5
|
+
/// React bridge reference.
|
|
6
|
+
@objc var bridge: RCTBridge!
|
|
7
|
+
|
|
8
|
+
/// In-memory mapping from `nativeId`s to `Source` instances.
|
|
9
|
+
private var sources: Registry<Source> = [:]
|
|
10
|
+
|
|
11
|
+
/// JS module name.
|
|
12
|
+
static func moduleName() -> String! {
|
|
13
|
+
"SourceModule"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// Module requires main thread initialization.
|
|
17
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
18
|
+
true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Use `UIManager.addBlock` to enqueue module methods on UI thread.
|
|
22
|
+
var methodQueue: DispatchQueue! {
|
|
23
|
+
bridge.uiManager.methodQueue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
Fetches the `Source` instance associated with `nativeId` from internal sources.
|
|
28
|
+
- Parameter nativeId: `Source` instance ID.
|
|
29
|
+
- Returns: The associated `Source` instance or `nil`.
|
|
30
|
+
*/
|
|
31
|
+
@objc func retrieve(_ nativeId: NativeId) -> Source? {
|
|
32
|
+
sources[nativeId]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
Creates a new `Source` instance inside the internal sources using the provided `config` object.
|
|
37
|
+
- Parameter nativeId: ID to be associated with the `Source` instance.
|
|
38
|
+
- Parameter config: `SourceConfig` object received from JS.
|
|
39
|
+
*/
|
|
40
|
+
@objc(initWithConfig:config:)
|
|
41
|
+
func initWithConfig(_ nativeId: NativeId, config: Any?) {
|
|
42
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
43
|
+
guard
|
|
44
|
+
self?.sources[nativeId] == nil,
|
|
45
|
+
let sourceConfig = RCTConvert.sourceConfig(config)
|
|
46
|
+
else {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
self?.sources[nativeId] = SourceFactory.create(from: sourceConfig)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
Creates a new `Source` instance inside the internal sources using the provided `config` object and an initialized DRM configuration ID.
|
|
55
|
+
- Parameter nativeId: ID to be associated with the `Source` instance.
|
|
56
|
+
- Parameter drmNativeId: ID of the DRM config object to use.
|
|
57
|
+
- Parameter config: `SourceConfig` object received from JS.
|
|
58
|
+
*/
|
|
59
|
+
@objc(initWithDrmConfig:drmNativeId:config:)
|
|
60
|
+
func initWithDrmConfig(_ nativeId: NativeId, drmNativeId: NativeId, config: Any?) {
|
|
61
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
62
|
+
guard
|
|
63
|
+
self?.sources[nativeId] == nil,
|
|
64
|
+
let fairplayConfig = self?.getDrmModule()?.retrieve(drmNativeId),
|
|
65
|
+
let sourceConfig = RCTConvert.sourceConfig(config, drmConfig: fairplayConfig)
|
|
66
|
+
else {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
self?.sources[nativeId] = SourceFactory.create(from: sourceConfig)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// Fetches the initialized `DrmModule` instance on RN's bridge object.
|
|
74
|
+
private func getDrmModule() -> DrmModule? {
|
|
75
|
+
bridge.module(for: DrmModule.self) as? DrmModule
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
Removes the `Source` instance associated with `nativeId` from `sources`.
|
|
80
|
+
- Parameter nativeId: Instance to be disposed.
|
|
81
|
+
*/
|
|
82
|
+
@objc(destroy:)
|
|
83
|
+
func destroy(_ nativeId: NativeId) {
|
|
84
|
+
sources.removeValue(forKey: nativeId)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
Whether `nativeId` source is currently attached to a player instance.
|
|
89
|
+
- Parameter nativeId: Source `nativeId`.
|
|
90
|
+
- Parameter resolver: JS promise resolver.
|
|
91
|
+
- Parameter rejecter: JS promise rejecter.
|
|
92
|
+
*/
|
|
93
|
+
@objc(isAttachedToPlayer:resolver:rejecter:)
|
|
94
|
+
func isAttachedToPlayer(
|
|
95
|
+
_ nativeId: NativeId,
|
|
96
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
97
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
98
|
+
) {
|
|
99
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
100
|
+
resolve(self?.sources[nativeId]?.isAttachedToPlayer)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Whether `nativeId` source is currently active in a `Player`.
|
|
106
|
+
- Parameter nativeId: Source `nativeId`.
|
|
107
|
+
- Parameter resolver: JS promise resolver.
|
|
108
|
+
- Parameter rejecter: JS promise rejecter.
|
|
109
|
+
*/
|
|
110
|
+
@objc(isActive:resolver:rejecter:)
|
|
111
|
+
func isActive(
|
|
112
|
+
_ nativeId: NativeId,
|
|
113
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
114
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
115
|
+
) {
|
|
116
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
117
|
+
resolve(self?.sources[nativeId]?.isActive)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
The duration of `nativeId` source in seconds.
|
|
123
|
+
- Parameter nativeId: Source `nativeId`.
|
|
124
|
+
- Parameter resolver: JS promise resolver.
|
|
125
|
+
- Parameter rejecter: JS promise rejecter.
|
|
126
|
+
*/
|
|
127
|
+
@objc(duration:resolver:rejecter:)
|
|
128
|
+
func duration(
|
|
129
|
+
_ nativeId: NativeId,
|
|
130
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
131
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
132
|
+
) {
|
|
133
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
134
|
+
resolve(self?.sources[nativeId]?.duration)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
The current loading state of `nativeId` source.
|
|
140
|
+
- Parameter nativeId: Source `nativeId`.
|
|
141
|
+
- Parameter resolver: JS promise resolver.
|
|
142
|
+
- Parameter rejecter: JS promise rejecter.
|
|
143
|
+
*/
|
|
144
|
+
@objc(loadingState:resolver:rejecter:)
|
|
145
|
+
func loadingState(
|
|
146
|
+
_ nativeId: NativeId,
|
|
147
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
148
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
149
|
+
) {
|
|
150
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
151
|
+
resolve(self?.sources[nativeId]?.loadingState)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
Metadata for the currently loaded `nativeId` source.
|
|
157
|
+
- Parameter nativeId: Source `nativeId`.
|
|
158
|
+
- Parameter resolver: JS promise resolver.
|
|
159
|
+
- Parameter rejecter: JS promise rejecter.
|
|
160
|
+
*/
|
|
161
|
+
@objc(getMetadata:resolver:rejecter:)
|
|
162
|
+
func getMetadata(
|
|
163
|
+
_ nativeId: NativeId,
|
|
164
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
165
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
166
|
+
) {
|
|
167
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
168
|
+
resolve(self?.sources[nativeId]?.metadata)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
Set the metadata for a loaded `nativeId` source.
|
|
174
|
+
- Parameter nativeId: Source `nativeId`.
|
|
175
|
+
- Parameter resolver: JS promise resolver.
|
|
176
|
+
- Parameter rejecter: JS promise rejecter.
|
|
177
|
+
*/
|
|
178
|
+
@objc(setMetadata:metadata:)
|
|
179
|
+
func setMetadata(_ nativeId: NativeId, metadata: Any?) {
|
|
180
|
+
bridge.uiManager.addUIBlock { [weak self] _, _ in
|
|
181
|
+
guard let metadata = metadata as? [String: AnyObject] else {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
self?.sources[nativeId]?.metadata = metadata
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
package/ios/UuidModule.m
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_REMAP_MODULE(UuidModule, UuidModule, NSObject)
|
|
4
|
+
|
|
5
|
+
// UUID generation is sync and runs on the JS thread so in order to avoid performance
|
|
6
|
+
// issues, it should be as fast as possible.
|
|
7
|
+
RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(generate)
|
|
8
|
+
|
|
9
|
+
@end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Native module for easy and fast unique ID generation on JS side. Used to generate native instance IDs.
|
|
3
|
+
*/
|
|
4
|
+
@objc(UuidModule)
|
|
5
|
+
class UuidModule: NSObject, RCTBridgeModule {
|
|
6
|
+
/// Initialize this module on main thread.
|
|
7
|
+
static func requiresMainQueueSetup() -> Bool {
|
|
8
|
+
true
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/// Exported JS module name.
|
|
12
|
+
static func moduleName() -> String! {
|
|
13
|
+
"UuidModule"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Synchronously generate a random UUIDv4.
|
|
18
|
+
- Returns: Random UUID RFC 4122 version 4.
|
|
19
|
+
*/
|
|
20
|
+
@objc func generate() -> String {
|
|
21
|
+
UUID().uuidString
|
|
22
|
+
}
|
|
23
|
+
}
|