react-native-compressor 1.3.2 → 1.4.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 +60 -2
- package/android/.gradle/6.1.1/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/6.1.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/6.1.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/6.1.1/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/android/.gradle/checksums/checksums.lock +0 -0
- package/android/.gradle/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/checksums/sha1-checksums.bin +0 -0
- package/android/build.gradle +1 -5
- package/android/src/main/java/com/.DS_Store +0 -0
- package/android/src/main/java/com/reactnativecompressor/.DS_Store +0 -0
- package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.java +0 -1
- package/android/src/main/java/com/reactnativecompressor/CompressorModule.java +14 -2
- package/android/src/main/java/com/reactnativecompressor/Utils/RealPathUtil.java +210 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/Utils.java +30 -6
- package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression/AutoVideoCompression.java +3 -37
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.java +2 -38
- package/android/src/main/java/com/reactnativecompressor/Video/VideoModule.java +23 -15
- package/ios/.DS_Store +0 -0
- package/ios/Compressor-Bridging-Header.h +1 -1
- package/ios/Compressor.m +39 -12
- package/ios/Image/ImageCompressor.h +2 -0
- package/ios/Image/ImageCompressor.m +152 -1
- package/ios/Video/VideoCompressor.swift +57 -47
- package/lib/commonjs/Audio/index.js.map +1 -1
- package/lib/commonjs/Video/index.js +13 -2
- package/lib/commonjs/Video/index.js.map +1 -1
- package/lib/commonjs/index.js +15 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/index.js +12 -4
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/Audio/index.js.map +1 -1
- package/lib/module/Video/index.js +9 -1
- package/lib/module/Video/index.js.map +1 -1
- package/lib/module/index.js +5 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/index.js +6 -4
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/Video/index.d.ts +3 -0
- package/lib/typescript/index.d.ts +4 -2
- package/lib/typescript/utils/index.d.ts +2 -0
- package/package.json +2 -1
- package/src/Audio/index.tsx +1 -1
- package/src/Video/index.tsx +12 -7
- package/src/index.tsx +5 -1
- package/src/utils/index.tsx +7 -3
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
package com.reactnativecompressor.Video;
|
|
2
2
|
|
|
3
|
-
import android.media.MediaMetadataRetriever;
|
|
4
3
|
import android.net.Uri;
|
|
4
|
+
import android.util.Log;
|
|
5
5
|
|
|
6
6
|
import androidx.annotation.NonNull;
|
|
7
7
|
import androidx.annotation.Nullable;
|
|
8
8
|
|
|
9
|
-
import com.facebook.react.bridge.Arguments;
|
|
10
9
|
import com.facebook.react.bridge.Promise;
|
|
11
10
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
12
11
|
import com.facebook.react.bridge.ReactContext;
|
|
@@ -16,17 +15,18 @@ import com.facebook.react.bridge.ReadableMap;
|
|
|
16
15
|
import com.facebook.react.bridge.WritableMap;
|
|
17
16
|
import com.facebook.react.module.annotations.ReactModule;
|
|
18
17
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
19
|
-
import com.reactnativecompressor.
|
|
20
|
-
import com.zolad.videoslimmer.VideoSlimmer;
|
|
18
|
+
import com.reactnativecompressor.Utils.RealPathUtil;
|
|
21
19
|
|
|
22
|
-
import static com.reactnativecompressor.Utils.Utils.
|
|
20
|
+
import static com.reactnativecompressor.Utils.Utils.getRealPath;
|
|
23
21
|
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_activateBackgroundTask_helper;
|
|
24
22
|
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_deactivateBackgroundTask_helper;
|
|
25
23
|
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_upload_helper;
|
|
24
|
+
import static com.reactnativecompressor.Utils.Utils.cancelCompressionHelper;
|
|
26
25
|
|
|
27
26
|
@ReactModule(name = VideoModule.NAME)
|
|
28
|
-
public class
|
|
27
|
+
public class VideoModule extends ReactContextBaseJavaModule {
|
|
29
28
|
public static final String NAME = "VideoCompressor";
|
|
29
|
+
private static final String TAG = "react-native-compessor";
|
|
30
30
|
private final ReactApplicationContext reactContext;
|
|
31
31
|
public VideoModule(ReactApplicationContext reactContext) {
|
|
32
32
|
super(reactContext);
|
|
@@ -53,20 +53,28 @@ public class VideoModule extends ReactContextBaseJavaModule {
|
|
|
53
53
|
String fileUrl,
|
|
54
54
|
ReadableMap optionMap,
|
|
55
55
|
Promise promise) {
|
|
56
|
-
|
|
56
|
+
final VideoCompressorHelper options = VideoCompressorHelper.fromMap(optionMap);
|
|
57
|
+
fileUrl=getRealPath(fileUrl,reactContext);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
if(options.compressionMethod==VideoCompressorHelper.CompressionMethod.auto)
|
|
60
|
+
{
|
|
61
|
+
VideoCompressorHelper.VideoCompressAuto(fileUrl,options,promise,reactContext);
|
|
62
|
+
}
|
|
63
|
+
else
|
|
64
|
+
{
|
|
65
|
+
VideoCompressorHelper.VideoCompressManual(fileUrl,options,promise,reactContext);
|
|
66
|
+
}
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
@ReactMethod
|
|
72
|
+
public void cancelCompression(
|
|
73
|
+
String uuid) {
|
|
74
|
+
cancelCompressionHelper(uuid);
|
|
75
|
+
Log.d("cancelCompression", uuid);
|
|
76
|
+
}
|
|
77
|
+
|
|
70
78
|
@ReactMethod
|
|
71
79
|
public void upload(
|
|
72
80
|
String fileUrl,
|
package/ios/.DS_Store
CHANGED
|
Binary file
|
package/ios/Compressor.m
CHANGED
|
@@ -20,17 +20,19 @@ RCT_EXPORT_METHOD(
|
|
|
20
20
|
rejecter: (RCTPromiseRejectBlock) reject) {
|
|
21
21
|
@try {
|
|
22
22
|
ImageCompressorOptions *options = [ImageCompressorOptions fromDictionary:optionsDict];
|
|
23
|
+
[ImageCompressor getAbsoluteImagePath:imagePath completionHandler:^(NSString* absoluteImagePath){
|
|
24
|
+
if(options.autoCompress)
|
|
25
|
+
{
|
|
26
|
+
NSString *result = [ImageCompressor autoCompressHandler:absoluteImagePath options:options];
|
|
27
|
+
resolve(result);
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
{
|
|
31
|
+
NSString *result = [ImageCompressor manualCompressHandler:absoluteImagePath options:options];
|
|
32
|
+
resolve(result);
|
|
33
|
+
}
|
|
34
|
+
}];
|
|
23
35
|
|
|
24
|
-
if(options.autoCompress)
|
|
25
|
-
{
|
|
26
|
-
NSString *result = [ImageCompressor autoCompressHandler:imagePath options:options];
|
|
27
|
-
resolve(result);
|
|
28
|
-
}
|
|
29
|
-
else
|
|
30
|
-
{
|
|
31
|
-
NSString *result = [ImageCompressor manualCompressHandler:imagePath options:options];
|
|
32
|
-
resolve(result);
|
|
33
|
-
}
|
|
34
36
|
}
|
|
35
37
|
@catch (NSException *exception) {
|
|
36
38
|
reject(exception.name, exception.reason, nil);
|
|
@@ -176,7 +178,7 @@ RCT_EXPORT_METHOD(
|
|
|
176
178
|
|
|
177
179
|
//general
|
|
178
180
|
RCT_EXPORT_METHOD(
|
|
179
|
-
|
|
181
|
+
generateFilePath: (NSString*) extension
|
|
180
182
|
resolver: (RCTPromiseResolveBlock) resolve
|
|
181
183
|
rejecter: (RCTPromiseRejectBlock) reject) {
|
|
182
184
|
@try {
|
|
@@ -188,6 +190,30 @@ RCT_EXPORT_METHOD(
|
|
|
188
190
|
}
|
|
189
191
|
}
|
|
190
192
|
|
|
193
|
+
RCT_EXPORT_METHOD(
|
|
194
|
+
getRealPath: (NSString*) path
|
|
195
|
+
type: (NSString*) type
|
|
196
|
+
resolver: (RCTPromiseResolveBlock) resolve
|
|
197
|
+
rejecter: (RCTPromiseRejectBlock) reject) {
|
|
198
|
+
@try {
|
|
199
|
+
if([type isEqualToString:@"video"])
|
|
200
|
+
{
|
|
201
|
+
[ImageCompressor getAbsoluteVideoPath:path completionHandler:^(NSString* absoluteImagePath){
|
|
202
|
+
resolve(absoluteImagePath);
|
|
203
|
+
}];
|
|
204
|
+
}
|
|
205
|
+
else
|
|
206
|
+
{
|
|
207
|
+
[ImageCompressor getAbsoluteImagePath:path completionHandler:^(NSString* absoluteImagePath){
|
|
208
|
+
resolve(absoluteImagePath);
|
|
209
|
+
}];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
@catch (NSException *exception) {
|
|
213
|
+
reject(exception.name, exception.reason, nil);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
191
217
|
//general
|
|
192
218
|
RCT_EXPORT_METHOD(
|
|
193
219
|
getFileSize: (NSString*) filePath
|
|
@@ -239,5 +265,6 @@ RCT_EXTERN_METHOD(deactivateBackgroundTask: (NSDictionary *)options
|
|
|
239
265
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
240
266
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
241
267
|
|
|
242
|
-
|
|
268
|
+
RCT_EXTERN_METHOD(cancelCompression:(NSString *)uuid)
|
|
243
269
|
|
|
270
|
+
@end
|
|
@@ -12,4 +12,6 @@
|
|
|
12
12
|
+(NSString *)autoCompressHandler:(NSString *)imagePath options:(ImageCompressorOptions*)options;
|
|
13
13
|
+ (NSString *)manualCompress:(UIImage *)image output:(enum OutputType)output quality:(float)quality outputExtension:(NSString*)outputExtension isBase64:(Boolean)isBase64;
|
|
14
14
|
+ (UIImage *)scaleAndRotateImage:(UIImage *)image;
|
|
15
|
+
+ (void)getAbsoluteImagePath:(NSString *)imagePath completionHandler:(void (^)(NSString *absoluteImagePath))completionHandler;
|
|
16
|
+
+(void)getAbsoluteVideoPath:(NSString *)videoPath completionHandler:(void (^)(NSString *absoluteImagePath))completionHandler;
|
|
15
17
|
@end
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
#import <Accelerate/Accelerate.h>
|
|
2
2
|
#import <CoreGraphics/CoreGraphics.h>
|
|
3
|
-
|
|
3
|
+
#import <Photos/Photos.h>
|
|
4
|
+
#import <React/RCTUtils.h>
|
|
5
|
+
#import <React/RCTImageLoader.h>
|
|
4
6
|
#import "ImageCompressor.h"
|
|
7
|
+
#import <React/RCTConvert.h>
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
#import <MobileCoreServices/MobileCoreServices.h>
|
|
5
10
|
|
|
6
11
|
@implementation ImageCompressor
|
|
7
12
|
+ (CGSize) findTargetSize: (UIImage *) image maxWidth: (int) maxWidth maxHeight: (int) maxHeight {
|
|
@@ -288,4 +293,150 @@
|
|
|
288
293
|
return returnablePath;
|
|
289
294
|
}
|
|
290
295
|
|
|
296
|
+
+(void)getAbsoluteImagePath:(NSString *)imagePath completionHandler:(void (^)(NSString *absoluteImagePath))completionHandler
|
|
297
|
+
{
|
|
298
|
+
if (![imagePath containsString:@"ph://"]) {
|
|
299
|
+
completionHandler(imagePath);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
NSURL *imageURL = [NSURL URLWithString:[imagePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"]];
|
|
303
|
+
CGSize size = CGSizeZero;
|
|
304
|
+
CGFloat scale = 1;
|
|
305
|
+
RCTResizeMode resizeMode = RCTResizeModeContain;
|
|
306
|
+
NSString *assetID = @"";
|
|
307
|
+
PHFetchResult *results;
|
|
308
|
+
if (!imageURL) {
|
|
309
|
+
NSString *errorText = @"Cannot load a photo library asset with no URL";
|
|
310
|
+
@throw([NSException exceptionWithName:errorText reason:errorText userInfo:nil]);
|
|
311
|
+
} else if ([imageURL.scheme caseInsensitiveCompare:@"assets-library"] == NSOrderedSame) {
|
|
312
|
+
assetID = [imageURL absoluteString];
|
|
313
|
+
results = [PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil];
|
|
314
|
+
} else {
|
|
315
|
+
assetID = [imageURL.absoluteString substringFromIndex:@"ph://".length];
|
|
316
|
+
results = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil];
|
|
317
|
+
}
|
|
318
|
+
if (results.count == 0) {
|
|
319
|
+
NSString *errorText = [NSString stringWithFormat:@"Failed to fetch PHAsset with local identifier %@ with no error message.", assetID];
|
|
320
|
+
@throw([NSException exceptionWithName:errorText reason:errorText userInfo:nil]);
|
|
321
|
+
}
|
|
322
|
+
PHAsset *asset = [results firstObject]; // <-- WE GOT THE ASSET
|
|
323
|
+
PHImageRequestOptions *imageOptions = [PHImageRequestOptions new];
|
|
324
|
+
imageOptions.networkAccessAllowed = YES;
|
|
325
|
+
imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
|
|
326
|
+
|
|
327
|
+
BOOL useMaximumSize = CGSizeEqualToSize(size, CGSizeZero);
|
|
328
|
+
CGSize targetSize;
|
|
329
|
+
if (useMaximumSize) {
|
|
330
|
+
targetSize = PHImageManagerMaximumSize;
|
|
331
|
+
imageOptions.resizeMode = PHImageRequestOptionsResizeModeNone;
|
|
332
|
+
} else {
|
|
333
|
+
targetSize = CGSizeApplyAffineTransform(size, CGAffineTransformMakeScale(scale, scale));
|
|
334
|
+
imageOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
PHImageContentMode contentMode = PHImageContentModeAspectFill;
|
|
338
|
+
if (resizeMode == RCTResizeModeContain) {
|
|
339
|
+
contentMode = PHImageContentModeAspectFit;
|
|
340
|
+
}
|
|
341
|
+
[[PHImageManager defaultManager] requestImageForAsset:asset
|
|
342
|
+
targetSize:targetSize
|
|
343
|
+
contentMode:contentMode
|
|
344
|
+
options:imageOptions
|
|
345
|
+
resultHandler:^(UIImage *result, NSDictionary<NSString *, id> *info) {
|
|
346
|
+
// WE GOT THE IMAGE
|
|
347
|
+
if (result) {
|
|
348
|
+
UIImage *image = result;
|
|
349
|
+
NSString *imageName = [assetID stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
|
|
350
|
+
NSString *imagePath = [self saveImageIntoCache:image withName:imageName];
|
|
351
|
+
completionHandler(imagePath);
|
|
352
|
+
} else {
|
|
353
|
+
@throw([NSException exceptionWithName:@"image not found" reason:@"image not found" userInfo:nil]);
|
|
354
|
+
}
|
|
355
|
+
}];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
+(NSString*) saveImageIntoCache:(UIImage *)image withName:(NSString *)name {
|
|
359
|
+
NSData *imageData = UIImageJPEGRepresentation(image, 1);
|
|
360
|
+
NSString *path =[self generateCacheFilePath:@"jpg"];
|
|
361
|
+
[[NSFileManager defaultManager] createFileAtPath:path contents:imageData attributes:NULL];
|
|
362
|
+
return path;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/// for vide
|
|
366
|
+
|
|
367
|
+
+(void)getAbsoluteVideoPath:(NSString *)videoPath completionHandler:(void (^)(NSString *absoluteImagePath))completionHandler
|
|
368
|
+
{
|
|
369
|
+
if (![videoPath containsString:@"ph://"]) {
|
|
370
|
+
completionHandler(videoPath);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
NSString *assetId =[videoPath stringByReplacingOccurrencesOfString:@"ph://"
|
|
374
|
+
withString:@""];
|
|
375
|
+
AVFileType outputFileType = AVFileTypeMPEG4;
|
|
376
|
+
NSString *pressetType = AVAssetExportPresetPassthrough;
|
|
377
|
+
|
|
378
|
+
// Throwing some errors to the user if he is not careful enough
|
|
379
|
+
if ([assetId isEqualToString:@""]) {
|
|
380
|
+
NSError *error = [NSError errorWithDomain:@"RNGalleryManager" code: -91 userInfo:nil];
|
|
381
|
+
@throw([NSException exceptionWithName:error reason:error userInfo:nil]);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Getting Video Asset
|
|
386
|
+
NSArray* localIds = [NSArray arrayWithObjects: assetId, nil];
|
|
387
|
+
PHAsset * _Nullable videoAsset = [PHAsset fetchAssetsWithLocalIdentifiers:localIds options:nil].firstObject;
|
|
388
|
+
|
|
389
|
+
// Getting information from the asset
|
|
390
|
+
NSString *mimeType = (NSString *)CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef _Nonnull)(outputFileType), kUTTagClassMIMEType));
|
|
391
|
+
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef _Nonnull)(mimeType), NULL);
|
|
392
|
+
NSString *extension = (NSString *)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension));
|
|
393
|
+
|
|
394
|
+
// Creating output url and temp file name
|
|
395
|
+
NSString *path =[self generateCacheFilePath:extension];
|
|
396
|
+
NSURL *outputUrl = [NSURL URLWithString:[@"file://" stringByAppendingString:path]];
|
|
397
|
+
|
|
398
|
+
// Setting video export session options
|
|
399
|
+
PHVideoRequestOptions *videoRequestOptions = [[PHVideoRequestOptions alloc] init];
|
|
400
|
+
videoRequestOptions.networkAccessAllowed = YES;
|
|
401
|
+
videoRequestOptions.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
|
|
402
|
+
|
|
403
|
+
// Creating new export session
|
|
404
|
+
[[PHImageManager defaultManager] requestExportSessionForVideo:videoAsset options:videoRequestOptions exportPreset:pressetType resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
|
|
405
|
+
|
|
406
|
+
exportSession.shouldOptimizeForNetworkUse = YES;
|
|
407
|
+
exportSession.outputFileType = outputFileType;
|
|
408
|
+
exportSession.outputURL = outputUrl;
|
|
409
|
+
// Converting the video and waiting to see whats going to happen
|
|
410
|
+
[exportSession exportAsynchronouslyWithCompletionHandler:^{
|
|
411
|
+
switch ([exportSession status])
|
|
412
|
+
{
|
|
413
|
+
case AVAssetExportSessionStatusFailed:
|
|
414
|
+
{
|
|
415
|
+
NSError* error = exportSession.error;
|
|
416
|
+
NSString *codeWithDomain = [NSString stringWithFormat:@"E%@%zd", error.domain.uppercaseString, error.code];
|
|
417
|
+
@throw([NSException exceptionWithName:error reason:error userInfo:nil]);
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
case AVAssetExportSessionStatusCancelled:
|
|
421
|
+
{
|
|
422
|
+
NSError *error = [NSError errorWithDomain:@"RNGalleryManager" code: -91 userInfo:nil];
|
|
423
|
+
@throw([NSException exceptionWithName:error reason:error userInfo:nil]);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
case AVAssetExportSessionStatusCompleted:
|
|
427
|
+
{
|
|
428
|
+
completionHandler(outputUrl.absoluteString);
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
default:
|
|
432
|
+
{
|
|
433
|
+
NSError *error = [NSError errorWithDomain:@"RNGalleryManager" code: -91 userInfo:nil];
|
|
434
|
+
@throw([NSException exceptionWithName:@"Unknown status" reason:@"Unknown status" userInfo:nil]);
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}];
|
|
439
|
+
}];
|
|
440
|
+
}
|
|
441
|
+
|
|
291
442
|
@end
|
|
@@ -2,6 +2,7 @@ import Foundation
|
|
|
2
2
|
import AssetsLibrary
|
|
3
3
|
import AVFoundation
|
|
4
4
|
import NextLevelSessionExporter
|
|
5
|
+
import Photos
|
|
5
6
|
|
|
6
7
|
struct CompressionError: Error {
|
|
7
8
|
private let message: String
|
|
@@ -34,8 +35,9 @@ class VideoCompressor: RCTEventEmitter, URLSessionTaskDelegate {
|
|
|
34
35
|
var hasListener: Bool=false
|
|
35
36
|
var uploadResolvers: [String: RCTPromiseResolveBlock] = [:]
|
|
36
37
|
var uploadRejectors: [String: RCTPromiseRejectBlock] = [:]
|
|
38
|
+
var compressorExports: [String: NextLevelSessionExporter] = [:]
|
|
37
39
|
let videoCompressionThreshold:Int=7
|
|
38
|
-
|
|
40
|
+
|
|
39
41
|
|
|
40
42
|
override static func requiresMainQueueSetup() -> Bool {
|
|
41
43
|
return false
|
|
@@ -83,6 +85,11 @@ class VideoCompressor: RCTEventEmitter, URLSessionTaskDelegate {
|
|
|
83
85
|
})
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
@objc(cancelCompression:)
|
|
89
|
+
func cancelCompression(uuid: String) -> Void {
|
|
90
|
+
compressorExports[uuid]?.cancelExport()
|
|
91
|
+
}
|
|
92
|
+
|
|
86
93
|
func makeValidUri(filePath: String) -> String {
|
|
87
94
|
let fileWithUrl = URL(fileURLWithPath: filePath)
|
|
88
95
|
let absoluteUrl = fileWithUrl.deletingLastPathComponent()
|
|
@@ -199,45 +206,45 @@ func makeValidUri(filePath: String) -> String {
|
|
|
199
206
|
|
|
200
207
|
|
|
201
208
|
func compressVideo(url: URL, options: [String: Any], onProgress: @escaping (Float) -> Void, onCompletion: @escaping (URL) -> Void, onFailure: @escaping (Error) -> Void){
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
if(fileSize>minimumFileSizeForCompress)
|
|
209
|
-
{
|
|
210
|
-
if(options["compressionMethod"] as! String=="auto")
|
|
209
|
+
ImageCompressor.getAbsoluteVideoPath(url.absoluteString) { absoluteVideoPath in
|
|
210
|
+
var minimumFileSizeForCompress:Double=16.0;
|
|
211
|
+
let videoURL = URL(string: absoluteVideoPath!)
|
|
212
|
+
let fileSize=self.getfileSize(forURL: videoURL!);
|
|
213
|
+
if((options["minimumFileSizeForCompress"]) != nil)
|
|
211
214
|
{
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
minimumFileSizeForCompress=options["minimumFileSizeForCompress"] as! Double;
|
|
216
|
+
}
|
|
217
|
+
if(fileSize>minimumFileSizeForCompress)
|
|
218
|
+
{
|
|
219
|
+
if(options["compressionMethod"] as! String=="auto")
|
|
220
|
+
{
|
|
221
|
+
self.autoCompressionHelper(url: videoURL!, options:options) { progress in
|
|
222
|
+
onProgress(progress)
|
|
223
|
+
} onCompletion: { outputURL in
|
|
224
|
+
onCompletion(outputURL)
|
|
225
|
+
} onFailure: { error in
|
|
226
|
+
onFailure(error)
|
|
227
|
+
}
|
|
218
228
|
}
|
|
229
|
+
else
|
|
230
|
+
{
|
|
231
|
+
self.manualCompressionHelper(url: videoURL!, options:options) { progress in
|
|
232
|
+
onProgress(progress)
|
|
233
|
+
} onCompletion: { outputURL in
|
|
234
|
+
onCompletion(outputURL)
|
|
235
|
+
} onFailure: { error in
|
|
236
|
+
onFailure(error)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
219
242
|
}
|
|
220
243
|
else
|
|
221
244
|
{
|
|
222
|
-
|
|
223
|
-
onProgress(progress)
|
|
224
|
-
} onCompletion: { outputURL in
|
|
225
|
-
onCompletion(outputURL)
|
|
226
|
-
} onFailure: { error in
|
|
227
|
-
onFailure(error)
|
|
228
|
-
}
|
|
245
|
+
onCompletion(url)
|
|
229
246
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
else
|
|
235
|
-
{
|
|
236
|
-
onCompletion(url)
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
247
|
+
}
|
|
241
248
|
}
|
|
242
249
|
|
|
243
250
|
|
|
@@ -263,6 +270,7 @@ func makeValidUri(filePath: String) -> String {
|
|
|
263
270
|
|
|
264
271
|
func autoCompressionHelper(url: URL, options: [String: Any], onProgress: @escaping (Float) -> Void, onCompletion: @escaping (URL) -> Void, onFailure: @escaping (Error) -> Void){
|
|
265
272
|
let maxSize:Float = options["maxSize"] as! Float;
|
|
273
|
+
let uuid:String = options["uuid"] as! String
|
|
266
274
|
|
|
267
275
|
let asset = AVAsset(url: url)
|
|
268
276
|
guard asset.tracks.count >= 1 else {
|
|
@@ -286,8 +294,8 @@ func makeValidUri(filePath: String) -> String {
|
|
|
286
294
|
originalBitrate: Int(bitrate),
|
|
287
295
|
height: Int(resultHeight), width: Int(resultWidth)
|
|
288
296
|
);
|
|
289
|
-
|
|
290
|
-
exportVideoHelper(url: url, asset: asset, bitRate: videoBitRate, resultWidth: resultWidth, resultHeight: resultHeight) { progress in
|
|
297
|
+
|
|
298
|
+
exportVideoHelper(url: url, asset: asset, bitRate: videoBitRate, resultWidth: resultWidth, resultHeight: resultHeight,uuid: uuid) { progress in
|
|
291
299
|
onProgress(progress)
|
|
292
300
|
} onCompletion: { outputURL in
|
|
293
301
|
onCompletion(outputURL)
|
|
@@ -296,9 +304,9 @@ func makeValidUri(filePath: String) -> String {
|
|
|
296
304
|
}
|
|
297
305
|
}
|
|
298
306
|
|
|
299
|
-
func manualCompressionHelper(url: URL,
|
|
300
|
-
|
|
301
|
-
var
|
|
307
|
+
func manualCompressionHelper(url: URL, options: [String: Any], onProgress: @escaping (Float) -> Void, onCompletion: @escaping (URL) -> Void, onFailure: @escaping (Error) -> Void){
|
|
308
|
+
let uuid:String = options["uuid"] as! String
|
|
309
|
+
var bitRate=options["bitrate"] as! Float?;
|
|
302
310
|
let asset = AVAsset(url: url)
|
|
303
311
|
guard asset.tracks.count >= 1 else {
|
|
304
312
|
let error = CompressionError(message: "Invalid video URL, no track found")
|
|
@@ -321,12 +329,12 @@ func makeValidUri(filePath: String) -> String {
|
|
|
321
329
|
}
|
|
322
330
|
else
|
|
323
331
|
{
|
|
324
|
-
|
|
332
|
+
bitRate=bitRate ?? Float(abs(track.estimatedDataRate))*0.8
|
|
325
333
|
}
|
|
326
334
|
|
|
327
|
-
let videoBitRate =
|
|
335
|
+
let videoBitRate = bitRate ?? height*width*1.5
|
|
328
336
|
|
|
329
|
-
exportVideoHelper(url: url, asset: asset, bitRate: Int(videoBitRate), resultWidth: width, resultHeight: height) { progress in
|
|
337
|
+
exportVideoHelper(url: url, asset: asset, bitRate: Int(videoBitRate), resultWidth: width, resultHeight: height,uuid: uuid) { progress in
|
|
330
338
|
onProgress(progress)
|
|
331
339
|
} onCompletion: { outputURL in
|
|
332
340
|
onCompletion(outputURL)
|
|
@@ -335,7 +343,8 @@ func makeValidUri(filePath: String) -> String {
|
|
|
335
343
|
}
|
|
336
344
|
}
|
|
337
345
|
|
|
338
|
-
func exportVideoHelper(url: URL,asset: AVAsset, bitRate: Int,resultWidth:Float,resultHeight:Float, onProgress: @escaping (Float) -> Void, onCompletion: @escaping (URL) -> Void, onFailure: @escaping (Error) -> Void){
|
|
346
|
+
func exportVideoHelper(url: URL,asset: AVAsset, bitRate: Int,resultWidth:Float,resultHeight:Float,uuid:String, onProgress: @escaping (Float) -> Void, onCompletion: @escaping (URL) -> Void, onFailure: @escaping (Error) -> Void){
|
|
347
|
+
var videoCompressionCounter:Int=0
|
|
339
348
|
var tmpURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
|
340
349
|
.appendingPathComponent(ProcessInfo().globallyUniqueString)
|
|
341
350
|
.appendingPathExtension("mp4")
|
|
@@ -364,17 +373,17 @@ func makeValidUri(filePath: String) -> String {
|
|
|
364
373
|
AVSampleRateKey: NSNumber(value: Float(44100))
|
|
365
374
|
]
|
|
366
375
|
|
|
367
|
-
|
|
376
|
+
compressorExports[uuid] = exporter
|
|
368
377
|
exporter.export(progressHandler: { (progress) in
|
|
369
378
|
let _progress:Float=progress*100;
|
|
370
|
-
if(Int(_progress)==
|
|
379
|
+
if(Int(_progress)==videoCompressionCounter)
|
|
371
380
|
{
|
|
372
|
-
|
|
381
|
+
videoCompressionCounter=Int(_progress)+self.videoCompressionThreshold
|
|
373
382
|
onProgress(progress)
|
|
374
383
|
}
|
|
375
384
|
|
|
376
385
|
}, completionHandler: { result in
|
|
377
|
-
|
|
386
|
+
videoCompressionCounter=0;
|
|
378
387
|
switch exporter.status {
|
|
379
388
|
case .completed:
|
|
380
389
|
onCompletion(exporter.outputURL!)
|
|
@@ -403,4 +412,5 @@ func makeValidUri(filePath: String) -> String {
|
|
|
403
412
|
let track = asset.tracks[videoTrackIndex];
|
|
404
413
|
return track;
|
|
405
414
|
}
|
|
415
|
+
|
|
406
416
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.tsx"],"names":["NativeAudio","NativeModules","Compressor","Audio","compress","url","options","DEFAULT_COMPRESS_AUDIO_OPTIONS","checkUrlAndOptionsResult","isCorrect","message","mediaDetails","bitrate","i","AUDIO_BITRATE","length","quality","compress_audio","error"],"mappings":";;;;;;;AAAA;;AACA;;AAOA,MAAMA,WAAW,GAAGC,2BAAcC,UAAlC;AAEA,MAAMC,KAAgB,GAAG;AACvBC,EAAAA,QAAQ,EAAE,OAAOC,GAAP,EAAYC,OAAO,GAAGC,qCAAtB,KAAyD;AACjE,QAAI;AACF,YAAMC,wBAA2C,GAC/C,MAAM,+BAAmBH,GAAnB,EAAwBC,OAAxB,CADR;;AAEA,UAAI,CAACE,wBAAwB,CAACC,SAA9B,EAAyC;AACvC,cAAMD,wBAAwB,CAACE,OAA/B;AACD,OAFD,MAEO;AACL;AAEA;AACA;AACA,cAAMC,YAAiB,GAAG;AACxBC,UAAAA,OAAO,EAAE;AADe,SAA1B,CALK,CASL;;AACA,YAAIA,OAAY,GAAGL,sCAA+BK,OAAlD;;AAEA,YAAID,YAAY,IAAIA,YAAY,CAACC,OAAjC,EAA0C;AACxC;AACA,eAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGC,qBAAcC,MAAlC,EAA0CF,CAAC,EAA3C,EAA+C;AAC7C;AACA,gBAAIF,YAAY,CAACC,OAAb,GAAuBE,qBAAcD,CAAd,CAA3B,EAA6C;AAC3C,kBAAIA,CAAC,GAAG,CAAJ,GAAQC,qBAAcC,MAA1B,EAAkC;AAChC,oBAAIT,OAAO,CAACU,OAAR,KAAoB,KAAxB,EAA+BJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CAA/B,KACK,IAAIP,OAAO,CAACU,OAAR,KAAoB,QAAxB,EACHJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CADG,KAEAD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;AACN,eALD,MAKO,IAAIA,CAAC,GAAG,CAAJ,GAAQC,qBAAcC,MAA1B,EAAkC;AACvC,oBAAIT,OAAO,CAACU,OAAR,KAAoB,KAAxB,EAA+BJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CAA/B,KACKD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;AACN,eAHM,MAGAD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;;AACP;AACD,aAb4C,CAe7C;;;AACA,gBACEF,YAAY,CAACC,OAAb,IAAwBE,qBAAcA,qBAAcC,MAAd,GAAuB,CAArC,CAD1B,EAEE;AACAH,cAAAA,OAAO,GAAGE,qBAAcA,qBAAcC,MAAd,GAAuB,CAArC,CAAV;AACA;AACD;AACF;AACF;;AAED,eAAOf,WAAW,CAACiB,cAAZ,CAA2BZ,GAA3B,EAAgC;AACrCO,UAAAA,OADqC;AAErCI,UAAAA,OAAO,EAAEV,OAAO,CAACU;AAFoB,SAAhC,CAAP;AAID;AACF,KAjDD,CAiDE,OAAOE,KAAP,
|
|
1
|
+
{"version":3,"sources":["index.tsx"],"names":["NativeAudio","NativeModules","Compressor","Audio","compress","url","options","DEFAULT_COMPRESS_AUDIO_OPTIONS","checkUrlAndOptionsResult","isCorrect","message","mediaDetails","bitrate","i","AUDIO_BITRATE","length","quality","compress_audio","error"],"mappings":";;;;;;;AAAA;;AACA;;AAOA,MAAMA,WAAW,GAAGC,2BAAcC,UAAlC;AAEA,MAAMC,KAAgB,GAAG;AACvBC,EAAAA,QAAQ,EAAE,OAAOC,GAAP,EAAYC,OAAO,GAAGC,qCAAtB,KAAyD;AACjE,QAAI;AACF,YAAMC,wBAA2C,GAC/C,MAAM,+BAAmBH,GAAnB,EAAwBC,OAAxB,CADR;;AAEA,UAAI,CAACE,wBAAwB,CAACC,SAA9B,EAAyC;AACvC,cAAMD,wBAAwB,CAACE,OAA/B;AACD,OAFD,MAEO;AACL;AAEA;AACA;AACA,cAAMC,YAAiB,GAAG;AACxBC,UAAAA,OAAO,EAAE;AADe,SAA1B,CALK,CASL;;AACA,YAAIA,OAAY,GAAGL,sCAA+BK,OAAlD;;AAEA,YAAID,YAAY,IAAIA,YAAY,CAACC,OAAjC,EAA0C;AACxC;AACA,eAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGC,qBAAcC,MAAlC,EAA0CF,CAAC,EAA3C,EAA+C;AAC7C;AACA,gBAAIF,YAAY,CAACC,OAAb,GAAuBE,qBAAcD,CAAd,CAA3B,EAA6C;AAC3C,kBAAIA,CAAC,GAAG,CAAJ,GAAQC,qBAAcC,MAA1B,EAAkC;AAChC,oBAAIT,OAAO,CAACU,OAAR,KAAoB,KAAxB,EAA+BJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CAA/B,KACK,IAAIP,OAAO,CAACU,OAAR,KAAoB,QAAxB,EACHJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CADG,KAEAD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;AACN,eALD,MAKO,IAAIA,CAAC,GAAG,CAAJ,GAAQC,qBAAcC,MAA1B,EAAkC;AACvC,oBAAIT,OAAO,CAACU,OAAR,KAAoB,KAAxB,EAA+BJ,OAAO,GAAGE,qBAAcD,CAAC,GAAG,CAAlB,CAAV,CAA/B,KACKD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;AACN,eAHM,MAGAD,OAAO,GAAGE,qBAAcD,CAAd,CAAV;;AACP;AACD,aAb4C,CAe7C;;;AACA,gBACEF,YAAY,CAACC,OAAb,IAAwBE,qBAAcA,qBAAcC,MAAd,GAAuB,CAArC,CAD1B,EAEE;AACAH,cAAAA,OAAO,GAAGE,qBAAcA,qBAAcC,MAAd,GAAuB,CAArC,CAAV;AACA;AACD;AACF;AACF;;AAED,eAAOf,WAAW,CAACiB,cAAZ,CAA2BZ,GAA3B,EAAgC;AACrCO,UAAAA,OADqC;AAErCI,UAAAA,OAAO,EAAEV,OAAO,CAACU;AAFoB,SAAhC,CAAP;AAID;AACF,KAjDD,CAiDE,OAAOE,KAAP,EAAmB;AACnB,YAAMA,KAAK,CAACR,OAAZ;AACD;AACF;AAtDsB,CAAzB;eAyDeP,K","sourcesContent":["import { NativeModules } from 'react-native';\nimport {\n AUDIO_BITRATE,\n AudioType,\n DEFAULT_COMPRESS_AUDIO_OPTIONS,\n defaultResultType,\n checkUrlAndOptions,\n} from '../utils';\nconst NativeAudio = NativeModules.Compressor;\n\nconst Audio: AudioType = {\n compress: async (url, options = DEFAULT_COMPRESS_AUDIO_OPTIONS) => {\n try {\n const checkUrlAndOptionsResult: defaultResultType =\n await checkUrlAndOptions(url, options);\n if (!checkUrlAndOptionsResult.isCorrect) {\n throw checkUrlAndOptionsResult.message;\n } else {\n // Get resulting output file path\n\n // Get media details\n // const mediaDetails: any = await getDetails(url).catch(() => null);\n const mediaDetails: any = {\n bitrate: 0,\n };\n\n // Initialize bitrate\n let bitrate: any = DEFAULT_COMPRESS_AUDIO_OPTIONS.bitrate;\n\n if (mediaDetails && mediaDetails.bitrate) {\n // Check and return the appropriate bitrate according to quality expected\n for (let i = 0; i < AUDIO_BITRATE.length; i++) {\n // Check a particular bitrate to return its nearest lower according to quality\n if (mediaDetails.bitrate > AUDIO_BITRATE[i]) {\n if (i + 2 < AUDIO_BITRATE.length) {\n if (options.quality === 'low') bitrate = AUDIO_BITRATE[i + 2];\n else if (options.quality === 'medium')\n bitrate = AUDIO_BITRATE[i + 1];\n else bitrate = AUDIO_BITRATE[i];\n } else if (i + 1 < AUDIO_BITRATE.length) {\n if (options.quality === 'low') bitrate = AUDIO_BITRATE[i + 1];\n else bitrate = AUDIO_BITRATE[i];\n } else bitrate = AUDIO_BITRATE[i];\n break;\n }\n\n // Check if the matching bitrate is the last in the array\n if (\n mediaDetails.bitrate <= AUDIO_BITRATE[AUDIO_BITRATE.length - 1]\n ) {\n bitrate = AUDIO_BITRATE[AUDIO_BITRATE.length - 1];\n break;\n }\n }\n }\n\n return NativeAudio.compress_audio(url, {\n bitrate,\n quality: options.quality,\n });\n }\n } catch (error: any) {\n throw error.message;\n }\n },\n};\n\nexport default Audio;\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = exports.backgroundUpload = void 0;
|
|
6
|
+
exports.default = exports.cancelCompression = exports.backgroundUpload = void 0;
|
|
7
7
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
|
|
@@ -45,6 +45,12 @@ const backgroundUpload = async (url, fileUrl, options, onProgress) => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
exports.backgroundUpload = backgroundUpload;
|
|
48
|
+
|
|
49
|
+
const cancelCompression = cancellationId => {
|
|
50
|
+
return NativeVideoCompressor.cancelCompression(cancellationId);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
exports.cancelCompression = cancelCompression;
|
|
48
54
|
const Video = {
|
|
49
55
|
compress: async (fileUrl, options, onProgress) => {
|
|
50
56
|
const uuid = (0, _utils.uuidv4)();
|
|
@@ -76,10 +82,14 @@ const Video = {
|
|
|
76
82
|
modifiedOptions.maxSize = 640;
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
if (options
|
|
85
|
+
if ((options === null || options === void 0 ? void 0 : options.minimumFileSizeForCompress) !== undefined) {
|
|
80
86
|
modifiedOptions.minimumFileSizeForCompress = options === null || options === void 0 ? void 0 : options.minimumFileSizeForCompress;
|
|
81
87
|
}
|
|
82
88
|
|
|
89
|
+
if (options !== null && options !== void 0 && options.getCancellationId) {
|
|
90
|
+
options === null || options === void 0 ? void 0 : options.getCancellationId(uuid);
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
const result = await NativeVideoCompressor.compress(fileUrl, modifiedOptions);
|
|
84
94
|
return result;
|
|
85
95
|
} finally {
|
|
@@ -90,6 +100,7 @@ const Video = {
|
|
|
90
100
|
}
|
|
91
101
|
},
|
|
92
102
|
backgroundUpload,
|
|
103
|
+
cancelCompression,
|
|
93
104
|
|
|
94
105
|
activateBackgroundTask(onExpired) {
|
|
95
106
|
if (onExpired) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.tsx"],"names":["VideoCompressEventEmitter","NativeEventEmitter","NativeModules","VideoCompressor","NativeVideoCompressor","backgroundUpload","url","fileUrl","options","onProgress","uuid","subscription","addListener","event","data","written","total","Platform","OS","includes","replace","result","upload","method","httpMethod","headers","remove","Video","compress","progress","modifiedOptions","bitrate","compressionMethod","maxSize","minimumFileSizeForCompress","activateBackgroundTask","onExpired","deactivateBackgroundTask","removeAllListeners"],"mappings":";;;;;;;AAAA;;AAMA;;
|
|
1
|
+
{"version":3,"sources":["index.tsx"],"names":["VideoCompressEventEmitter","NativeEventEmitter","NativeModules","VideoCompressor","NativeVideoCompressor","backgroundUpload","url","fileUrl","options","onProgress","uuid","subscription","addListener","event","data","written","total","Platform","OS","includes","replace","result","upload","method","httpMethod","headers","remove","cancelCompression","cancellationId","Video","compress","progress","modifiedOptions","bitrate","compressionMethod","maxSize","minimumFileSizeForCompress","undefined","getCancellationId","activateBackgroundTask","onExpired","deactivateBackgroundTask","removeAllListeners"],"mappings":"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","sourcesContent":["import {\n NativeModules,\n NativeEventEmitter,\n Platform,\n NativeEventSubscription,\n} from 'react-native';\nimport { uuidv4 } from '../utils';\n\nexport declare enum FileSystemUploadType {\n BINARY_CONTENT = 0,\n MULTIPART = 1,\n}\n\nexport declare type FileSystemAcceptedUploadHttpMethod =\n | 'POST'\n | 'PUT'\n | 'PATCH';\nexport type compressionMethod = 'auto' | 'manual';\ntype videoCompresssionType = {\n bitrate?: number;\n maxSize?: number;\n compressionMethod?: compressionMethod;\n minimumFileSizeForCompress?: number;\n getCancellationId?: (cancellationId: string) => void;\n};\n\nexport declare enum FileSystemSessionType {\n BACKGROUND = 0,\n FOREGROUND = 1,\n}\n\nexport declare type HTTPResponse = {\n status: number;\n headers: Record<string, string>;\n body: string;\n};\n\nexport declare type FileSystemUploadOptions = (\n | {\n uploadType?: FileSystemUploadType.BINARY_CONTENT;\n }\n | {\n uploadType: FileSystemUploadType.MULTIPART;\n fieldName?: string;\n mimeType?: string;\n parameters?: Record<string, string>;\n }\n) & {\n headers?: Record<string, string>;\n httpMethod?: FileSystemAcceptedUploadHttpMethod;\n sessionType?: FileSystemSessionType;\n};\n\nexport type VideoCompressorType = {\n compress(\n fileUrl: string,\n options?: videoCompresssionType,\n onProgress?: (progress: number) => void\n ): Promise<string>;\n cancelCompression(cancellationId: string): void;\n backgroundUpload(\n url: string,\n fileUrl: string,\n options: FileSystemUploadOptions,\n onProgress?: (writtem: number, total: number) => void\n ): Promise<any>;\n activateBackgroundTask(onExpired?: (data: any) => void): Promise<any>;\n deactivateBackgroundTask(): Promise<any>;\n};\n\nconst VideoCompressEventEmitter = new NativeEventEmitter(\n NativeModules.VideoCompressor\n);\n\nconst NativeVideoCompressor = NativeModules.VideoCompressor;\n\nexport const backgroundUpload = async (\n url: string,\n fileUrl: string,\n options: FileSystemUploadOptions,\n onProgress?: (writtem: number, total: number) => void\n): Promise<any> => {\n const uuid = uuidv4();\n let subscription: NativeEventSubscription;\n try {\n if (onProgress) {\n subscription = VideoCompressEventEmitter.addListener(\n 'VideoCompressorProgress',\n (event: any) => {\n if (event.uuid === uuid) {\n onProgress(event.data.written, event.data.total);\n }\n }\n );\n }\n if (Platform.OS === 'android' && fileUrl.includes('file://')) {\n fileUrl = fileUrl.replace('file://', '');\n }\n const result = await NativeVideoCompressor.upload(fileUrl, {\n uuid,\n method: options.httpMethod,\n headers: options.headers,\n url,\n });\n return result;\n } finally {\n // @ts-ignore\n if (subscription) {\n subscription.remove();\n }\n }\n};\n\nexport const cancelCompression = (cancellationId: string) => {\n return NativeVideoCompressor.cancelCompression(cancellationId);\n};\n\nconst Video: VideoCompressorType = {\n compress: async (\n fileUrl: string,\n options?: videoCompresssionType,\n onProgress?: (progress: number) => void\n ) => {\n const uuid = uuidv4();\n let subscription: NativeEventSubscription;\n try {\n if (onProgress) {\n subscription = VideoCompressEventEmitter.addListener(\n 'videoCompressProgress',\n (event: any) => {\n if (event.uuid === uuid) {\n onProgress(event.data.progress);\n }\n }\n );\n }\n const modifiedOptions: {\n uuid: string;\n bitrate?: number;\n compressionMethod?: compressionMethod;\n maxSize?: number;\n minimumFileSizeForCompress?: number;\n } = { uuid };\n if (options?.bitrate) modifiedOptions.bitrate = options?.bitrate;\n if (options?.compressionMethod) {\n modifiedOptions.compressionMethod = options?.compressionMethod;\n } else {\n modifiedOptions.compressionMethod = 'manual';\n }\n if (options?.maxSize) {\n modifiedOptions.maxSize = options?.maxSize;\n } else {\n modifiedOptions.maxSize = 640;\n }\n if (options?.minimumFileSizeForCompress !== undefined) {\n modifiedOptions.minimumFileSizeForCompress =\n options?.minimumFileSizeForCompress;\n }\n if (options?.getCancellationId) {\n options?.getCancellationId(uuid);\n }\n const result = await NativeVideoCompressor.compress(\n fileUrl,\n modifiedOptions\n );\n return result;\n } finally {\n // @ts-ignore\n if (subscription) {\n subscription.remove();\n }\n }\n },\n backgroundUpload,\n cancelCompression,\n activateBackgroundTask(onExpired?) {\n if (onExpired) {\n const subscription: NativeEventSubscription =\n VideoCompressEventEmitter.addListener(\n 'backgroundTaskExpired',\n (event: any) => {\n onExpired(event);\n if (subscription) {\n subscription.remove();\n }\n }\n );\n }\n return NativeVideoCompressor.activateBackgroundTask({});\n },\n deactivateBackgroundTask() {\n VideoCompressEventEmitter.removeAllListeners('backgroundTaskExpired');\n return NativeVideoCompressor.deactivateBackgroundTask({});\n },\n} as VideoCompressorType;\n\nexport default Video;\n"]}
|