@granite-js/video 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/GraniteVideo.podspec +72 -0
- package/android/README.md +232 -0
- package/android/build.gradle +117 -0
- package/android/gradle.properties +8 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/run/granite/video/GraniteVideoModule.kt +70 -0
- package/android/src/main/java/run/granite/video/GraniteVideoPackage.kt +43 -0
- package/android/src/main/java/run/granite/video/GraniteVideoView.kt +384 -0
- package/android/src/main/java/run/granite/video/GraniteVideoViewManager.kt +318 -0
- package/android/src/main/java/run/granite/video/event/GraniteVideoEvents.kt +273 -0
- package/android/src/main/java/run/granite/video/event/VideoEventDispatcher.kt +66 -0
- package/android/src/main/java/run/granite/video/event/VideoEventListenerAdapter.kt +157 -0
- package/android/src/main/java/run/granite/video/provider/GraniteVideoProvider.kt +346 -0
- package/android/src/media3/AndroidManifest.xml +9 -0
- package/android/src/media3/java/run/granite/video/provider/media3/ExoPlayerProvider.kt +386 -0
- package/android/src/media3/java/run/granite/video/provider/media3/Media3ContentProvider.kt +29 -0
- package/android/src/media3/java/run/granite/video/provider/media3/Media3Initializer.kt +25 -0
- package/android/src/media3/java/run/granite/video/provider/media3/factory/ExoPlayerFactory.kt +32 -0
- package/android/src/media3/java/run/granite/video/provider/media3/factory/MediaSourceFactory.kt +61 -0
- package/android/src/media3/java/run/granite/video/provider/media3/factory/TrackSelectorFactory.kt +26 -0
- package/android/src/media3/java/run/granite/video/provider/media3/factory/VideoSurfaceFactory.kt +62 -0
- package/android/src/media3/java/run/granite/video/provider/media3/listener/ExoPlayerEventListener.kt +104 -0
- package/android/src/media3/java/run/granite/video/provider/media3/scheduler/ProgressScheduler.kt +56 -0
- package/android/src/test/java/run/granite/video/GraniteVideoViewRobolectricTest.kt +598 -0
- package/android/src/test/java/run/granite/video/event/VideoEventListenerAdapterTest.kt +319 -0
- package/android/src/test/java/run/granite/video/helpers/FakeGraniteVideoProvider.kt +161 -0
- package/android/src/test/java/run/granite/video/helpers/TestProgressScheduler.kt +42 -0
- package/android/src/test/java/run/granite/video/provider/GraniteVideoRegistryTest.kt +232 -0
- package/android/src/test/java/run/granite/video/provider/ProviderContractTest.kt +174 -0
- package/android/src/test/java/run/granite/video/provider/media3/listener/ExoPlayerEventListenerTest.kt +243 -0
- package/android/src/test/resources/kotest.properties +2 -0
- package/dist/module/GraniteVideo.js +458 -0
- package/dist/module/GraniteVideo.js.map +1 -0
- package/dist/module/GraniteVideoNativeComponent.ts +265 -0
- package/dist/module/index.js +7 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/package.json +1 -0
- package/dist/module/types.js +4 -0
- package/dist/module/types.js.map +1 -0
- package/dist/typescript/GraniteVideo.d.ts +12 -0
- package/dist/typescript/GraniteVideoNativeComponent.d.ts +189 -0
- package/dist/typescript/index.d.ts +5 -0
- package/dist/typescript/types.d.ts +328 -0
- package/ios/GraniteVideoComponentsProvider.h +10 -0
- package/ios/GraniteVideoProvider.swift +280 -0
- package/ios/GraniteVideoView.h +15 -0
- package/ios/GraniteVideoView.mm +661 -0
- package/ios/Providers/AVPlayerProvider.swift +541 -0
- package/package.json +106 -0
- package/src/GraniteVideo.tsx +575 -0
- package/src/GraniteVideoNativeComponent.ts +265 -0
- package/src/index.ts +8 -0
- package/src/types.ts +464 -0
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#import <AVKit/AVKit.h>
|
|
3
|
+
|
|
4
|
+
#import <React/RCTViewComponentView.h>
|
|
5
|
+
#import <React/RCTConversions.h>
|
|
6
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
7
|
+
#import <React/RCTComponentViewFactory.h>
|
|
8
|
+
|
|
9
|
+
#import <react/renderer/components/GraniteVideoViewSpec/ComponentDescriptors.h>
|
|
10
|
+
#import <react/renderer/components/GraniteVideoViewSpec/EventEmitters.h>
|
|
11
|
+
#import <react/renderer/components/GraniteVideoViewSpec/Props.h>
|
|
12
|
+
#import <react/renderer/components/GraniteVideoViewSpec/RCTComponentViewHelpers.h>
|
|
13
|
+
|
|
14
|
+
// Import Swift module - the header is generated during build
|
|
15
|
+
#if __has_include(<GraniteVideo/GraniteVideo-Swift.h>)
|
|
16
|
+
#import <GraniteVideo/GraniteVideo-Swift.h>
|
|
17
|
+
#elif __has_include(<granite_video/granite_video-Swift.h>)
|
|
18
|
+
#import <granite_video/granite_video-Swift.h>
|
|
19
|
+
#else
|
|
20
|
+
#import "GraniteVideo-Swift.h"
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
using namespace facebook::react;
|
|
24
|
+
|
|
25
|
+
// Define GraniteVideoView inheriting from RCTViewComponentView here in .mm file
|
|
26
|
+
// The header declares it as UIView to avoid exposing C++ headers to Swift module
|
|
27
|
+
@interface GraniteVideoView : RCTViewComponentView <RCTGraniteVideoViewViewProtocol, GraniteVideoDelegate>
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
@implementation GraniteVideoView {
|
|
31
|
+
UIView *_playerView;
|
|
32
|
+
id<GraniteVideoProvidable> _provider;
|
|
33
|
+
BOOL _paused;
|
|
34
|
+
float _volume;
|
|
35
|
+
float _rate;
|
|
36
|
+
BOOL _muted;
|
|
37
|
+
BOOL _repeat;
|
|
38
|
+
NSString *_resizeMode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
42
|
+
{
|
|
43
|
+
return concreteComponentDescriptorProvider<GraniteVideoViewComponentDescriptor>();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
47
|
+
{
|
|
48
|
+
if (self = [super initWithFrame:frame]) {
|
|
49
|
+
static const auto defaultProps = std::make_shared<const GraniteVideoViewProps>();
|
|
50
|
+
_props = defaultProps;
|
|
51
|
+
|
|
52
|
+
// Default values
|
|
53
|
+
_paused = NO;
|
|
54
|
+
_volume = 1.0f;
|
|
55
|
+
_rate = 1.0f;
|
|
56
|
+
_muted = NO;
|
|
57
|
+
_repeat = NO;
|
|
58
|
+
_resizeMode = @"contain";
|
|
59
|
+
|
|
60
|
+
// Create provider from registry
|
|
61
|
+
_provider = [[GraniteVideoRegistry shared] createProvider];
|
|
62
|
+
|
|
63
|
+
#if defined(GRANITE_VIDEO_DEFAULT_PROVIDER)
|
|
64
|
+
if (_provider == nil) {
|
|
65
|
+
// Use default AVPlayer provider
|
|
66
|
+
_provider = [[AVPlayerProvider alloc] init];
|
|
67
|
+
}
|
|
68
|
+
#endif
|
|
69
|
+
|
|
70
|
+
if (_provider == nil) {
|
|
71
|
+
NSLog(@"[GraniteVideo] No provider registered. Register a provider in AppDelegate or use default AVPlayer provider.");
|
|
72
|
+
return self;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[_provider setDelegate:self];
|
|
76
|
+
|
|
77
|
+
// Create player view
|
|
78
|
+
_playerView = [_provider createPlayerView];
|
|
79
|
+
_playerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
80
|
+
|
|
81
|
+
self.contentView = _playerView;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return self;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
- (void)layoutSubviews
|
|
88
|
+
{
|
|
89
|
+
[super layoutSubviews];
|
|
90
|
+
_playerView.frame = self.bounds;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
|
94
|
+
{
|
|
95
|
+
const auto &oldViewProps = *std::static_pointer_cast<GraniteVideoViewProps const>(_props);
|
|
96
|
+
const auto &newViewProps = *std::static_pointer_cast<GraniteVideoViewProps const>(props);
|
|
97
|
+
|
|
98
|
+
// Source
|
|
99
|
+
if (newViewProps.source.uri != oldViewProps.source.uri ||
|
|
100
|
+
newViewProps.source.type != oldViewProps.source.type) {
|
|
101
|
+
[self updateSource:newViewProps.source];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Paused
|
|
105
|
+
if (newViewProps.paused != oldViewProps.paused) {
|
|
106
|
+
_paused = newViewProps.paused;
|
|
107
|
+
if (_paused) {
|
|
108
|
+
[_provider pause];
|
|
109
|
+
} else {
|
|
110
|
+
[_provider play];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Muted
|
|
115
|
+
if (newViewProps.muted != oldViewProps.muted) {
|
|
116
|
+
_muted = newViewProps.muted;
|
|
117
|
+
if ([_provider respondsToSelector:@selector(setMuted:)]) {
|
|
118
|
+
[_provider setMuted:_muted];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Volume
|
|
123
|
+
if (newViewProps.volume != oldViewProps.volume) {
|
|
124
|
+
_volume = newViewProps.volume;
|
|
125
|
+
if ([_provider respondsToSelector:@selector(setVolume:)]) {
|
|
126
|
+
[_provider setVolume:_volume];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Rate
|
|
131
|
+
if (newViewProps.rate != oldViewProps.rate) {
|
|
132
|
+
_rate = newViewProps.rate;
|
|
133
|
+
if ([_provider respondsToSelector:@selector(setRate:)]) {
|
|
134
|
+
[_provider setRate:_rate];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Repeat
|
|
139
|
+
if (newViewProps.repeat != oldViewProps.repeat) {
|
|
140
|
+
_repeat = newViewProps.repeat;
|
|
141
|
+
if ([_provider respondsToSelector:@selector(setRepeat:)]) {
|
|
142
|
+
[_provider setRepeat:_repeat];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Resize Mode
|
|
147
|
+
if (newViewProps.resizeMode != oldViewProps.resizeMode) {
|
|
148
|
+
_resizeMode = [NSString stringWithUTF8String:newViewProps.resizeMode.c_str()];
|
|
149
|
+
[self updateResizeMode:_resizeMode];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Controls
|
|
153
|
+
if (newViewProps.controls != oldViewProps.controls) {
|
|
154
|
+
if ([_provider respondsToSelector:@selector(setControlsEnabled:)]) {
|
|
155
|
+
[_provider setControlsEnabled:newViewProps.controls];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Fullscreen
|
|
160
|
+
if (newViewProps.fullscreen != oldViewProps.fullscreen) {
|
|
161
|
+
if ([_provider respondsToSelector:@selector(setFullscreen:animated:)]) {
|
|
162
|
+
[_provider setFullscreen:newViewProps.fullscreen animated:YES];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Picture in Picture
|
|
167
|
+
if (newViewProps.pictureInPicture != oldViewProps.pictureInPicture) {
|
|
168
|
+
if ([_provider respondsToSelector:@selector(setPictureInPictureEnabled:)]) {
|
|
169
|
+
[_provider setPictureInPictureEnabled:newViewProps.pictureInPicture];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Play in Background
|
|
174
|
+
if (newViewProps.playInBackground != oldViewProps.playInBackground) {
|
|
175
|
+
if ([_provider respondsToSelector:@selector(setPlayInBackground:)]) {
|
|
176
|
+
[_provider setPlayInBackground:newViewProps.playInBackground];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Play when Inactive
|
|
181
|
+
if (newViewProps.playWhenInactive != oldViewProps.playWhenInactive) {
|
|
182
|
+
if ([_provider respondsToSelector:@selector(setPlayWhenInactive:)]) {
|
|
183
|
+
[_provider setPlayWhenInactive:newViewProps.playWhenInactive];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Max Bit Rate
|
|
188
|
+
if (newViewProps.maxBitRate != oldViewProps.maxBitRate) {
|
|
189
|
+
if ([_provider respondsToSelector:@selector(setMaxBitRate:)]) {
|
|
190
|
+
[_provider setMaxBitRate:newViewProps.maxBitRate];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Preferred Forward Buffer Duration
|
|
195
|
+
if (newViewProps.preferredForwardBufferDuration != oldViewProps.preferredForwardBufferDuration) {
|
|
196
|
+
if ([_provider respondsToSelector:@selector(setPreferredForwardBufferDuration:)]) {
|
|
197
|
+
[_provider setPreferredForwardBufferDuration:newViewProps.preferredForwardBufferDuration];
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Automatically Waits to Minimize Stalling
|
|
202
|
+
if (newViewProps.automaticallyWaitsToMinimizeStalling != oldViewProps.automaticallyWaitsToMinimizeStalling) {
|
|
203
|
+
if ([_provider respondsToSelector:@selector(setAutomaticallyWaitsToMinimizeStalling:)]) {
|
|
204
|
+
[_provider setAutomaticallyWaitsToMinimizeStalling:newViewProps.automaticallyWaitsToMinimizeStalling];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Allows External Playback
|
|
209
|
+
if (newViewProps.allowsExternalPlayback != oldViewProps.allowsExternalPlayback) {
|
|
210
|
+
if ([_provider respondsToSelector:@selector(setAllowsExternalPlayback:)]) {
|
|
211
|
+
[_provider setAllowsExternalPlayback:newViewProps.allowsExternalPlayback];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Prevents Display Sleep
|
|
216
|
+
if (newViewProps.preventsDisplaySleepDuringVideoPlayback != oldViewProps.preventsDisplaySleepDuringVideoPlayback) {
|
|
217
|
+
if ([_provider respondsToSelector:@selector(setPreventsDisplaySleepDuringVideoPlayback:)]) {
|
|
218
|
+
[_provider setPreventsDisplaySleepDuringVideoPlayback:newViewProps.preventsDisplaySleepDuringVideoPlayback];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// DRM Config
|
|
223
|
+
if (newViewProps.drm.type != oldViewProps.drm.type ||
|
|
224
|
+
newViewProps.drm.licenseServer != oldViewProps.drm.licenseServer ||
|
|
225
|
+
newViewProps.drm.contentId != oldViewProps.drm.contentId ||
|
|
226
|
+
newViewProps.drm.certificateUrl != oldViewProps.drm.certificateUrl) {
|
|
227
|
+
[self updateDrmConfig:newViewProps.drm];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
[super updateProps:props oldProps:oldProps];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
- (void)updateSource:(const GraniteVideoViewSourceStruct &)source
|
|
234
|
+
{
|
|
235
|
+
if (source.uri.empty()) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
GraniteVideoSource *videoSource = [[GraniteVideoSource alloc] init];
|
|
240
|
+
videoSource.uri = [NSString stringWithUTF8String:source.uri.c_str()];
|
|
241
|
+
|
|
242
|
+
if (!source.type.empty()) {
|
|
243
|
+
videoSource.type = [NSString stringWithUTF8String:source.type.c_str()];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
videoSource.startPosition = source.startPosition;
|
|
247
|
+
videoSource.cropStart = source.cropStart;
|
|
248
|
+
videoSource.cropEnd = source.cropEnd;
|
|
249
|
+
|
|
250
|
+
[_provider loadSource:videoSource];
|
|
251
|
+
|
|
252
|
+
if (!_paused) {
|
|
253
|
+
[_provider play];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
- (void)updateResizeMode:(NSString *)mode
|
|
258
|
+
{
|
|
259
|
+
if ([_provider respondsToSelector:@selector(setResizeMode:)]) {
|
|
260
|
+
GraniteVideoResizeMode resizeMode = GraniteVideoResizeModeContain;
|
|
261
|
+
|
|
262
|
+
if ([mode isEqualToString:@"cover"]) {
|
|
263
|
+
resizeMode = GraniteVideoResizeModeCover;
|
|
264
|
+
} else if ([mode isEqualToString:@"stretch"]) {
|
|
265
|
+
resizeMode = GraniteVideoResizeModeStretch;
|
|
266
|
+
} else if ([mode isEqualToString:@"none"]) {
|
|
267
|
+
resizeMode = GraniteVideoResizeModeNone;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
[_provider setResizeMode:resizeMode];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (void)updateDrmConfig:(const GraniteVideoViewDrmStruct &)drm
|
|
275
|
+
{
|
|
276
|
+
if (drm.type.empty()) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
GraniteVideoDrmConfig *drmConfig = [[GraniteVideoDrmConfig alloc] init];
|
|
281
|
+
|
|
282
|
+
// Map DRM type
|
|
283
|
+
NSString *typeStr = [NSString stringWithUTF8String:drm.type.c_str()];
|
|
284
|
+
if ([typeStr isEqualToString:@"fairplay"]) {
|
|
285
|
+
drmConfig.type = GraniteVideoDrmTypeFairplay;
|
|
286
|
+
} else if ([typeStr isEqualToString:@"widevine"]) {
|
|
287
|
+
drmConfig.type = GraniteVideoDrmTypeWidevine;
|
|
288
|
+
} else if ([typeStr isEqualToString:@"playready"]) {
|
|
289
|
+
drmConfig.type = GraniteVideoDrmTypePlayready;
|
|
290
|
+
} else if ([typeStr isEqualToString:@"clearkey"]) {
|
|
291
|
+
drmConfig.type = GraniteVideoDrmTypeClearkey;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!drm.licenseServer.empty()) {
|
|
295
|
+
drmConfig.licenseServer = [NSString stringWithUTF8String:drm.licenseServer.c_str()];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Map JS contentId -> iOS contentID
|
|
299
|
+
if (!drm.contentId.empty()) {
|
|
300
|
+
drmConfig.contentID = [NSString stringWithUTF8String:drm.contentId.c_str()];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Map JS certificateUrl -> iOS certificateURL
|
|
304
|
+
if (!drm.certificateUrl.empty()) {
|
|
305
|
+
drmConfig.certificateURL = [NSString stringWithUTF8String:drm.certificateUrl.c_str()];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
drmConfig.base64Certificate = drm.base64Certificate;
|
|
309
|
+
|
|
310
|
+
if ([_provider respondsToSelector:@selector(setDrmConfig:)]) {
|
|
311
|
+
[_provider setDrmConfig:drmConfig];
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
#pragma mark - Native Commands
|
|
316
|
+
|
|
317
|
+
- (void)seek:(double)time tolerance:(double)tolerance
|
|
318
|
+
{
|
|
319
|
+
[_provider seekTo:time toleranceBefore:tolerance toleranceAfter:tolerance];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
- (void)adjustVolume:(float)volume
|
|
323
|
+
{
|
|
324
|
+
_volume = volume;
|
|
325
|
+
if ([_provider respondsToSelector:@selector(setVolume:)]) {
|
|
326
|
+
[_provider setVolume:volume];
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
- (void)setFullScreen:(BOOL)fullscreen
|
|
331
|
+
{
|
|
332
|
+
if ([_provider respondsToSelector:@selector(setFullscreen:animated:)]) {
|
|
333
|
+
[_provider setFullscreen:fullscreen animated:YES];
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
- (void)loadSource:(NSString *)uri
|
|
338
|
+
{
|
|
339
|
+
GraniteVideoSource *source = [[GraniteVideoSource alloc] initWithUri:uri];
|
|
340
|
+
[_provider loadSource:source];
|
|
341
|
+
|
|
342
|
+
if (!_paused) {
|
|
343
|
+
[_provider play];
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
- (void)pause
|
|
348
|
+
{
|
|
349
|
+
[_provider pause];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
- (void)resume
|
|
353
|
+
{
|
|
354
|
+
[_provider play];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
- (void)enterPictureInPicture
|
|
358
|
+
{
|
|
359
|
+
if ([_provider respondsToSelector:@selector(enterPictureInPicture)]) {
|
|
360
|
+
[_provider enterPictureInPicture];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
- (void)exitPictureInPicture
|
|
365
|
+
{
|
|
366
|
+
if ([_provider respondsToSelector:@selector(exitPictureInPicture)]) {
|
|
367
|
+
[_provider exitPictureInPicture];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
#pragma mark - GraniteVideoDelegate
|
|
372
|
+
|
|
373
|
+
- (void)videoDidLoadStartWithIsNetwork:(BOOL)isNetwork type:(nonnull NSString *)type uri:(nonnull NSString *)uri
|
|
374
|
+
{
|
|
375
|
+
if (_eventEmitter) {
|
|
376
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
377
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoLoadStart event = {
|
|
378
|
+
.isNetwork = isNetwork,
|
|
379
|
+
.type = std::string([type UTF8String] ?: ""),
|
|
380
|
+
.uri = std::string([uri UTF8String] ?: "")
|
|
381
|
+
};
|
|
382
|
+
emitter->onVideoLoadStart(event);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
- (void)videoDidLoadWithData:(nonnull GraniteVideoLoadData *)data
|
|
387
|
+
{
|
|
388
|
+
if (_eventEmitter) {
|
|
389
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
390
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoLoad event = {
|
|
391
|
+
.currentTime = data.currentTime,
|
|
392
|
+
.duration = data.duration,
|
|
393
|
+
.naturalSize = {
|
|
394
|
+
.width = data.naturalWidth,
|
|
395
|
+
.height = data.naturalHeight,
|
|
396
|
+
.orientation = std::string([data.orientation UTF8String] ?: "landscape")
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
emitter->onVideoLoad(event);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
- (void)videoDidFailWithError:(nonnull GraniteVideoErrorData *)error
|
|
404
|
+
{
|
|
405
|
+
if (_eventEmitter) {
|
|
406
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
407
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoError event = {
|
|
408
|
+
.error = {
|
|
409
|
+
.code = (int)error.code,
|
|
410
|
+
.domain = std::string([error.domain UTF8String] ?: ""),
|
|
411
|
+
.localizedDescription = std::string([error.localizedDescription_ UTF8String] ?: ""),
|
|
412
|
+
.localizedFailureReason = std::string([error.localizedFailureReason_ UTF8String] ?: ""),
|
|
413
|
+
.localizedRecoverySuggestion = std::string([error.localizedRecoverySuggestion_ UTF8String] ?: ""),
|
|
414
|
+
.errorString = std::string([error.localizedDescription_ UTF8String] ?: "")
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
emitter->onVideoError(event);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
- (void)videoDidUpdateProgressWithData:(nonnull GraniteVideoProgressData *)data
|
|
422
|
+
{
|
|
423
|
+
if (_eventEmitter) {
|
|
424
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
425
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoProgress event = {
|
|
426
|
+
.currentTime = data.currentTime,
|
|
427
|
+
.playableDuration = data.playableDuration,
|
|
428
|
+
.seekableDuration = data.seekableDuration
|
|
429
|
+
};
|
|
430
|
+
emitter->onVideoProgress(event);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
- (void)videoDidSeekWithCurrentTime:(double)currentTime seekTime:(double)seekTime
|
|
435
|
+
{
|
|
436
|
+
if (_eventEmitter) {
|
|
437
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
438
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoSeek event = {
|
|
439
|
+
.currentTime = currentTime,
|
|
440
|
+
.seekTime = seekTime
|
|
441
|
+
};
|
|
442
|
+
emitter->onVideoSeek(event);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
- (void)videoDidEnd
|
|
447
|
+
{
|
|
448
|
+
if (_eventEmitter) {
|
|
449
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
450
|
+
emitter->onVideoEnd({});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
- (void)videoBufferingStateChangedWithIsBuffering:(BOOL)isBuffering
|
|
455
|
+
{
|
|
456
|
+
if (_eventEmitter) {
|
|
457
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
458
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoBuffer event = {
|
|
459
|
+
.isBuffering = isBuffering
|
|
460
|
+
};
|
|
461
|
+
emitter->onVideoBuffer(event);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
- (void)videoBandwidthDidUpdateWithBitrate:(double)bitrate width:(NSInteger)width height:(NSInteger)height
|
|
466
|
+
{
|
|
467
|
+
if (_eventEmitter) {
|
|
468
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
469
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoBandwidthUpdate event = {
|
|
470
|
+
.bitrate = bitrate,
|
|
471
|
+
.width = (int)width,
|
|
472
|
+
.height = (int)height
|
|
473
|
+
};
|
|
474
|
+
emitter->onVideoBandwidthUpdate(event);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
- (void)videoPlaybackStateChangedWithIsPlaying:(BOOL)isPlaying isSeeking:(BOOL)isSeeking isLooping:(BOOL)isLooping
|
|
479
|
+
{
|
|
480
|
+
if (_eventEmitter) {
|
|
481
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
482
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoPlaybackStateChanged event = {
|
|
483
|
+
.isPlaying = isPlaying,
|
|
484
|
+
.isSeeking = isSeeking,
|
|
485
|
+
.isLooping = isLooping
|
|
486
|
+
};
|
|
487
|
+
emitter->onVideoPlaybackStateChanged(event);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
- (void)videoPlaybackRateChangedWithRate:(float)rate
|
|
492
|
+
{
|
|
493
|
+
if (_eventEmitter) {
|
|
494
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
495
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoPlaybackRateChange event = {
|
|
496
|
+
.playbackRate = rate
|
|
497
|
+
};
|
|
498
|
+
emitter->onVideoPlaybackRateChange(event);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
- (void)videoVolumeChangedWithVolume:(float)volume
|
|
503
|
+
{
|
|
504
|
+
if (_eventEmitter) {
|
|
505
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
506
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoVolumeChange event = {
|
|
507
|
+
.volume = volume
|
|
508
|
+
};
|
|
509
|
+
emitter->onVideoVolumeChange(event);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
- (void)videoDidBecomeIdle
|
|
514
|
+
{
|
|
515
|
+
if (_eventEmitter) {
|
|
516
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
517
|
+
emitter->onVideoIdle({});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
- (void)videoReadyForDisplay
|
|
522
|
+
{
|
|
523
|
+
if (_eventEmitter) {
|
|
524
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
525
|
+
emitter->onVideoReadyForDisplay({});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
- (void)videoAudioBecomingNoisy
|
|
530
|
+
{
|
|
531
|
+
if (_eventEmitter) {
|
|
532
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
533
|
+
emitter->onVideoAudioBecomingNoisy({});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
- (void)videoFullscreenPlayerWillPresent
|
|
538
|
+
{
|
|
539
|
+
if (_eventEmitter) {
|
|
540
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
541
|
+
emitter->onVideoFullscreenPlayerWillPresent({});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
- (void)videoFullscreenPlayerDidPresent
|
|
546
|
+
{
|
|
547
|
+
if (_eventEmitter) {
|
|
548
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
549
|
+
emitter->onVideoFullscreenPlayerDidPresent({});
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
- (void)videoFullscreenPlayerWillDismiss
|
|
554
|
+
{
|
|
555
|
+
if (_eventEmitter) {
|
|
556
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
557
|
+
emitter->onVideoFullscreenPlayerWillDismiss({});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
- (void)videoFullscreenPlayerDidDismiss
|
|
562
|
+
{
|
|
563
|
+
if (_eventEmitter) {
|
|
564
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
565
|
+
emitter->onVideoFullscreenPlayerDidDismiss({});
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
- (void)videoPictureInPictureStatusChangedWithIsActive:(BOOL)isActive
|
|
570
|
+
{
|
|
571
|
+
if (_eventEmitter) {
|
|
572
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
573
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoPictureInPictureStatusChanged event = {
|
|
574
|
+
.isActive = isActive
|
|
575
|
+
};
|
|
576
|
+
emitter->onVideoPictureInPictureStatusChanged(event);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
- (void)videoRestoreUserInterfaceForPictureInPictureStop
|
|
581
|
+
{
|
|
582
|
+
if (_eventEmitter) {
|
|
583
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
584
|
+
emitter->onVideoRestoreUserInterfaceForPictureInPictureStop({});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
- (void)videoControlsVisibilityChangedWithIsVisible:(BOOL)isVisible
|
|
589
|
+
{
|
|
590
|
+
if (_eventEmitter) {
|
|
591
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
592
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoControlsVisibilityChange event = {
|
|
593
|
+
.isVisible = isVisible
|
|
594
|
+
};
|
|
595
|
+
emitter->onVideoControlsVisibilityChange(event);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
- (void)videoExternalPlaybackChangedWithIsActive:(BOOL)isActive
|
|
600
|
+
{
|
|
601
|
+
if (_eventEmitter) {
|
|
602
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
603
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoExternalPlaybackChange event = {
|
|
604
|
+
.isExternalPlaybackActive = isActive
|
|
605
|
+
};
|
|
606
|
+
emitter->onVideoExternalPlaybackChange(event);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
- (void)videoAspectRatioChangedWithWidth:(double)width height:(double)height
|
|
611
|
+
{
|
|
612
|
+
if (_eventEmitter) {
|
|
613
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
614
|
+
facebook::react::GraniteVideoViewEventEmitter::OnVideoAspectRatio event = {
|
|
615
|
+
.width = width,
|
|
616
|
+
.height = height
|
|
617
|
+
};
|
|
618
|
+
emitter->onVideoAspectRatio(event);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
- (void)videoTransferEndWithUri:(NSString *)uri bytesTransferred:(double)bytesTransferred
|
|
623
|
+
{
|
|
624
|
+
if (_eventEmitter) {
|
|
625
|
+
auto emitter = std::static_pointer_cast<GraniteVideoViewEventEmitter const>(_eventEmitter);
|
|
626
|
+
facebook::react::GraniteVideoViewEventEmitter::OnTransferEnd event = {
|
|
627
|
+
.uri = std::string([uri UTF8String] ?: ""),
|
|
628
|
+
.bytesTransferred = bytesTransferred
|
|
629
|
+
};
|
|
630
|
+
emitter->onTransferEnd(event);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
#pragma mark - Command Handler
|
|
635
|
+
|
|
636
|
+
- (void)handleCommand:(NSString const *)commandName args:(NSArray const *)args
|
|
637
|
+
{
|
|
638
|
+
RCTGraniteVideoViewHandleCommand(self, commandName, args);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
#pragma mark - Cleanup
|
|
642
|
+
|
|
643
|
+
- (void)prepareForRecycle
|
|
644
|
+
{
|
|
645
|
+
[super prepareForRecycle];
|
|
646
|
+
[_provider unload];
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
- (void)dealloc
|
|
650
|
+
{
|
|
651
|
+
[_provider unload];
|
|
652
|
+
_provider = nil;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
@end
|
|
656
|
+
|
|
657
|
+
Class<RCTComponentViewProtocol> GraniteVideoViewCls(void)
|
|
658
|
+
{
|
|
659
|
+
return GraniteVideoView.class;
|
|
660
|
+
}
|
|
661
|
+
|