react-native-compressor 1.7.2 → 1.8.1
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 +51 -8
- package/android/build.gradle +9 -0
- package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt +527 -0
- package/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt +31 -0
- package/android/src/main/java/com/reactnativecompressor/CompressorModule.kt +169 -0
- package/android/src/main/java/com/reactnativecompressor/CompressorPackage.kt +34 -0
- package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressor.kt +199 -0
- package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressorOptions.kt +57 -0
- package/android/src/main/java/com/reactnativecompressor/Image/ImageMain.kt +31 -0
- package/android/src/main/java/com/reactnativecompressor/Image/ImageSize.kt +3 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/Downloader.kt +119 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/EventEmitterHandler.kt +66 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/MediaCache.kt +61 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/RealPathUtil.kt +177 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/Uploader.kt +117 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt +162 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/createVideoThumbnail.kt +158 -0
- package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression.kt +63 -0
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.kt +125 -0
- package/android/src/main/java/com/reactnativecompressor/Video/VideoMain.kt +86 -0
- package/android/src/newarch/CompressorSpec.kt +5 -0
- package/android/src/oldarch/CompressorSpec.kt +34 -0
- package/ios/Audio/AudioMain.swift +115 -0
- package/ios/Compressor-Bridging-Header.h +1 -2
- package/ios/Compressor.h +0 -8
- package/ios/Compressor.mm +37 -389
- package/ios/CompressorManager.swift +107 -0
- package/ios/Image/ImageCompressor.swift +354 -0
- package/ios/Image/ImageCompressorOptions.swift +93 -0
- package/ios/Image/ImageMain.swift +27 -0
- package/ios/Utils/CreateVideoThumbnail.swift +111 -0
- package/ios/Utils/Downloader.swift +157 -0
- package/ios/Utils/EventEmitterHandler.swift +54 -0
- package/ios/Utils/MediaCache.swift +48 -0
- package/ios/Utils/Uploader.swift +99 -0
- package/ios/Utils/Utils.swift +110 -0
- package/ios/Video/{VideoCompressor.swift → VideoMain.swift} +167 -146
- package/lib/commonjs/Image/index.js +1 -1
- package/lib/commonjs/Image/index.js.map +1 -1
- package/lib/commonjs/Main.js +1 -8
- package/lib/commonjs/Main.js.map +1 -1
- package/lib/commonjs/Spec/NativeCompressor.js.map +1 -1
- package/lib/commonjs/Video/index.js +4 -33
- package/lib/commonjs/Video/index.js.map +1 -1
- package/lib/commonjs/expo-plugin/compressor.js.map +1 -1
- package/lib/commonjs/index.js +25 -6
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/Downloader.js +38 -0
- package/lib/commonjs/utils/Downloader.js.map +1 -0
- package/lib/commonjs/utils/Uploader.js +40 -0
- package/lib/commonjs/utils/Uploader.js.map +1 -0
- package/lib/commonjs/utils/index.js +47 -1
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/Image/index.js +1 -1
- package/lib/module/Image/index.js.map +1 -1
- package/lib/module/Main.js +1 -7
- package/lib/module/Main.js.map +1 -1
- package/lib/module/Spec/NativeCompressor.js.map +1 -1
- package/lib/module/Video/index.js +5 -33
- package/lib/module/Video/index.js.map +1 -1
- package/lib/module/expo-plugin/compressor.js.map +1 -1
- package/lib/module/index.js +9 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/Downloader.js +31 -0
- package/lib/module/utils/Downloader.js.map +1 -0
- package/lib/module/utils/Uploader.js +33 -0
- package/lib/module/utils/Uploader.js.map +1 -0
- package/lib/module/utils/index.js +9 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/Image/index.d.ts +4 -0
- package/lib/typescript/Image/index.d.ts.map +1 -1
- package/lib/typescript/Main.d.ts +1 -2
- package/lib/typescript/Main.d.ts.map +1 -1
- package/lib/typescript/Spec/NativeCompressor.d.ts +16 -2
- package/lib/typescript/Spec/NativeCompressor.d.ts.map +1 -1
- package/lib/typescript/Video/index.d.ts +4 -28
- package/lib/typescript/Video/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +7 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils/Downloader.d.ts +2 -0
- package/lib/typescript/utils/Downloader.d.ts.map +1 -0
- package/lib/typescript/utils/Uploader.d.ts +28 -0
- package/lib/typescript/utils/Uploader.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +4 -1
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/Image/index.tsx +5 -1
- package/src/Main.tsx +1 -15
- package/src/Spec/NativeCompressor.ts +25 -2
- package/src/Video/index.tsx +11 -84
- package/src/expo-plugin/compressor.ts +1 -1
- package/src/index.tsx +12 -3
- package/src/utils/Downloader.tsx +38 -0
- package/src/utils/Uploader.tsx +78 -0
- package/src/utils/index.tsx +15 -0
- package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.java +0 -605
- package/android/src/main/java/com/reactnativecompressor/CompressorModule.java +0 -220
- package/android/src/main/java/com/reactnativecompressor/CompressorPackage.java +0 -58
- package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressor.java +0 -257
- package/android/src/main/java/com/reactnativecompressor/Image/utils/ImageCompressorOptions.java +0 -69
- package/android/src/main/java/com/reactnativecompressor/Image/utils/ImageSize.java +0 -13
- package/android/src/main/java/com/reactnativecompressor/Utils/FileUplaoder/FileUploadHelper.java +0 -39
- package/android/src/main/java/com/reactnativecompressor/Utils/FileUplaoder/FileUploader.java +0 -129
- package/android/src/main/java/com/reactnativecompressor/Utils/MediaCache.java +0 -65
- package/android/src/main/java/com/reactnativecompressor/Utils/RealPathUtil.java +0 -210
- package/android/src/main/java/com/reactnativecompressor/Utils/Utils.java +0 -272
- package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression/AutoVideoCompression.java +0 -87
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.java +0 -182
- package/android/src/main/java/com/reactnativecompressor/Video/VideoModule.java +0 -112
- package/android/src/newarch/CompressorSpec.java +0 -9
- package/android/src/newarch/VideoCompressorSpec.java +0 -9
- package/android/src/oldarch/CompressorSpec.java +0 -34
- package/android/src/oldarch/VideoCompressorSpec.java +0 -26
- package/ios/Image/ImageCompressor.h +0 -22
- package/ios/Image/ImageCompressor.m +0 -540
- package/ios/Image/ImageCompressorOptions.h +0 -28
- package/ios/Image/ImageCompressorOptions.m +0 -97
- package/ios/Utils/Downloader.h +0 -16
- package/ios/Utils/Downloader.m +0 -150
- package/ios/Utils/MediaCache.h +0 -11
- package/ios/Utils/MediaCache.m +0 -51
- package/ios/Video/VideoCompressor.h +0 -5
- package/ios/Video/VideoCompressor.m +0 -1
- package/lib/commonjs/Spec/NativeVideoCompressor.js +0 -10
- package/lib/commonjs/Spec/NativeVideoCompressor.js.map +0 -1
- package/lib/module/Spec/NativeVideoCompressor.js +0 -3
- package/lib/module/Spec/NativeVideoCompressor.js.map +0 -1
- package/lib/typescript/Spec/NativeVideoCompressor.d.ts +0 -13
- package/lib/typescript/Spec/NativeVideoCompressor.d.ts.map +0 -1
- package/src/Spec/NativeVideoCompressor.ts +0 -14
package/android/src/main/java/com/reactnativecompressor/Utils/FileUplaoder/FileUploader.java
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
package com.reactnativecompressor.Utils.FileUplaoder;
|
|
2
|
-
|
|
3
|
-
import android.util.Log;
|
|
4
|
-
|
|
5
|
-
import androidx.annotation.Nullable;
|
|
6
|
-
|
|
7
|
-
import com.facebook.react.bridge.Arguments;
|
|
8
|
-
import com.facebook.react.bridge.Promise;
|
|
9
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
10
|
-
import com.facebook.react.bridge.ReactContext;
|
|
11
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
12
|
-
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
13
|
-
import com.facebook.react.bridge.WritableMap;
|
|
14
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
15
|
-
|
|
16
|
-
import java.io.File;
|
|
17
|
-
import java.io.IOException;
|
|
18
|
-
|
|
19
|
-
import io.github.lizhangqu.coreprogress.ProgressHelper;
|
|
20
|
-
import io.github.lizhangqu.coreprogress.ProgressUIListener;
|
|
21
|
-
import okhttp3.Call;
|
|
22
|
-
import okhttp3.Callback;
|
|
23
|
-
import okhttp3.MediaType;
|
|
24
|
-
import okhttp3.OkHttpClient;
|
|
25
|
-
import okhttp3.Request;
|
|
26
|
-
import okhttp3.RequestBody;
|
|
27
|
-
import okhttp3.Response;
|
|
28
|
-
|
|
29
|
-
public class FileUploader {
|
|
30
|
-
private static final String TAG="asyncTaskFileUploader";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
private static void sendEvent(ReactContext reactContext,
|
|
34
|
-
String eventName,
|
|
35
|
-
@Nullable WritableMap params) {
|
|
36
|
-
reactContext
|
|
37
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
38
|
-
.emit(eventName, params);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
private static void sendProgressEvent(long numBytes, long totalBytes, FileUploadHelper options, ReactApplicationContext reactContext) {
|
|
42
|
-
WritableMap _params = Arguments.createMap();
|
|
43
|
-
WritableMap _data = Arguments.createMap();
|
|
44
|
-
_params.putString("uuid", options.uuid);
|
|
45
|
-
_data.putDouble("written", numBytes);
|
|
46
|
-
_data.putDouble("total", totalBytes);
|
|
47
|
-
_params.putMap("data", _data);
|
|
48
|
-
sendEvent(reactContext, "VideoCompressorProgress", _params);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public static void upload(String fileUrl, ReadableMap _options, ReactApplicationContext reactContext, Promise promise) {
|
|
52
|
-
FileUploadHelper options= FileUploadHelper.fromMap(_options);
|
|
53
|
-
String sourceFileUri = fileUrl;
|
|
54
|
-
File uploadableFile = new File(sourceFileUri);
|
|
55
|
-
String url = options.url;
|
|
56
|
-
String contentType="video";
|
|
57
|
-
|
|
58
|
-
OkHttpClient okHttpClient = new OkHttpClient();
|
|
59
|
-
|
|
60
|
-
Request.Builder builder = new Request.Builder();
|
|
61
|
-
builder.url(url);
|
|
62
|
-
|
|
63
|
-
ReadableMapKeySetIterator headerIterator = options.headers.keySetIterator();
|
|
64
|
-
while (headerIterator.hasNextKey()) {
|
|
65
|
-
String key = headerIterator.nextKey();
|
|
66
|
-
String value = options.headers.getString(key);
|
|
67
|
-
Log.d(TAG, key+" value: "+value);
|
|
68
|
-
builder.addHeader(key, value);
|
|
69
|
-
if(key.toLowerCase()=="content-type:")
|
|
70
|
-
{
|
|
71
|
-
contentType=value;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
MediaType mediaType = MediaType.parse(contentType);
|
|
76
|
-
RequestBody body = RequestBody.create(mediaType, uploadableFile);
|
|
77
|
-
|
|
78
|
-
RequestBody requestBody = ProgressHelper.withProgress(body, new ProgressUIListener() {
|
|
79
|
-
|
|
80
|
-
//if you don't need this method, don't override this methd. It isn't an abstract method, just an empty method.
|
|
81
|
-
@Override
|
|
82
|
-
public void onUIProgressStart(long totalBytes) {
|
|
83
|
-
super.onUIProgressStart(totalBytes);
|
|
84
|
-
Log.d(TAG, "onUIProgressStart:" + totalBytes);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@Override
|
|
88
|
-
public void onUIProgressChanged(long numBytes, long totalBytes, float percent, float speed) {
|
|
89
|
-
sendProgressEvent(numBytes,totalBytes,options,reactContext);
|
|
90
|
-
Log.d(TAG, "=============start===============");
|
|
91
|
-
Log.d(TAG, "numBytes:" + numBytes);
|
|
92
|
-
Log.d(TAG, "totalBytes:" + totalBytes);
|
|
93
|
-
Log.d(TAG, "percent:" + percent);
|
|
94
|
-
Log.d(TAG, "speed:" + speed);
|
|
95
|
-
Log.d(TAG, "============= end ===============");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
//if you don't need this method, don't override this methd. It isn't an abstract method, just an empty method.
|
|
99
|
-
@Override
|
|
100
|
-
public void onUIProgressFinish() {
|
|
101
|
-
super.onUIProgressFinish();
|
|
102
|
-
Log.d(TAG, "onUIProgressFinish:");
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
builder.put(requestBody);
|
|
106
|
-
|
|
107
|
-
Call call = okHttpClient.newCall(builder.build());
|
|
108
|
-
call.enqueue(new Callback() {
|
|
109
|
-
@Override
|
|
110
|
-
public void onFailure(Call call, IOException e) {
|
|
111
|
-
Log.d(TAG, "=============onFailure===============");
|
|
112
|
-
promise.reject("");
|
|
113
|
-
e.printStackTrace();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@Override
|
|
117
|
-
public void onResponse(Call call, Response response) throws IOException {
|
|
118
|
-
Log.d(TAG, "=============onResponse===============");
|
|
119
|
-
Log.d(TAG, "request headers:" + response.request().headers());
|
|
120
|
-
Log.d(TAG, "response code:" + response.code());
|
|
121
|
-
Log.d(TAG, "response headers:" + response.headers());
|
|
122
|
-
Log.d(TAG, "response body:" + response.body().string());
|
|
123
|
-
WritableMap param = Arguments.createMap();
|
|
124
|
-
param.putInt("status",response.code());
|
|
125
|
-
promise.resolve(param);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
package com.reactnativecompressor.Utils;
|
|
2
|
-
|
|
3
|
-
import android.util.Log;
|
|
4
|
-
|
|
5
|
-
import java.io.File;
|
|
6
|
-
import java.util.ArrayList;
|
|
7
|
-
import java.util.List;
|
|
8
|
-
|
|
9
|
-
public class MediaCache {
|
|
10
|
-
|
|
11
|
-
private static final String TAG = "MediaCache";
|
|
12
|
-
private static List<String> completedImagePaths = new ArrayList<>();
|
|
13
|
-
|
|
14
|
-
public static void addCompletedImagePath(String imagePath) {
|
|
15
|
-
if (imagePath != null) {
|
|
16
|
-
// Your code to add the imagePath to a list or perform other actions if needed.
|
|
17
|
-
completedImagePaths.add(imagePath);
|
|
18
|
-
Log.d(TAG, "Successfully added image path: " + imagePath);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public static void removeCompletedImagePath(String imagePath) {
|
|
23
|
-
if (imagePath != null) {
|
|
24
|
-
if (completedImagePaths.contains(imagePath)) {
|
|
25
|
-
// Image path exists in the list, so remove it
|
|
26
|
-
completedImagePaths.remove(imagePath);
|
|
27
|
-
|
|
28
|
-
if (imagePath.startsWith("file://")) {
|
|
29
|
-
imagePath = imagePath.substring(7); // Remove "file://"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Remove the image file
|
|
33
|
-
File file = new File(imagePath);
|
|
34
|
-
if (file.exists()) {
|
|
35
|
-
if (file.delete()) {
|
|
36
|
-
Log.d(TAG, "Successfully deleted image file: " + imagePath);
|
|
37
|
-
} else {
|
|
38
|
-
Log.d(TAG, "Failed to delete image file: " + imagePath);
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
Log.d(TAG, "Image file not found: " + imagePath);
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
Log.d(TAG, "Image path not found in the completedImagePaths list: " + imagePath);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public static void cleanupCache() {
|
|
50
|
-
// Iterate through the list of completed image paths and delete the corresponding files
|
|
51
|
-
for (String imagePath : completedImagePaths) {
|
|
52
|
-
File file = new File(imagePath);
|
|
53
|
-
if (file.exists()) {
|
|
54
|
-
if (file.delete()) {
|
|
55
|
-
Log.d(TAG, "Successfully deleted image file during cache cleanup: " + imagePath);
|
|
56
|
-
} else {
|
|
57
|
-
Log.d(TAG, "Failed to delete image file during cache cleanup: " + imagePath);
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
Log.d(TAG, "Image file not found during cache cleanup: " + imagePath);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
completedImagePaths.clear();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
package com.reactnativecompressor.Utils;
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint;
|
|
4
|
-
import android.content.ContentUris;
|
|
5
|
-
import android.content.Context;
|
|
6
|
-
import android.database.Cursor;
|
|
7
|
-
import android.net.Uri;
|
|
8
|
-
import android.os.Build;
|
|
9
|
-
import android.os.Environment;
|
|
10
|
-
import android.provider.DocumentsContract;
|
|
11
|
-
import android.provider.MediaStore;
|
|
12
|
-
|
|
13
|
-
import androidx.loader.content.CursorLoader;
|
|
14
|
-
|
|
15
|
-
public class RealPathUtil {
|
|
16
|
-
|
|
17
|
-
public static String getRealPath(Context context, Uri fileUri) {
|
|
18
|
-
String realPath;
|
|
19
|
-
// SDK < API11
|
|
20
|
-
if (Build.VERSION.SDK_INT < 11) {
|
|
21
|
-
realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(context, fileUri);
|
|
22
|
-
}
|
|
23
|
-
// SDK >= 11 && SDK < 19
|
|
24
|
-
else if (Build.VERSION.SDK_INT < 19) {
|
|
25
|
-
realPath = RealPathUtil.getRealPathFromURI_API11to18(context, fileUri);
|
|
26
|
-
}
|
|
27
|
-
// SDK > 19 (Android 4.4) and up
|
|
28
|
-
else {
|
|
29
|
-
realPath = RealPathUtil.getRealPathFromURI_API19(context, fileUri);
|
|
30
|
-
}
|
|
31
|
-
return realPath;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@SuppressLint("NewApi")
|
|
36
|
-
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
|
|
37
|
-
String[] proj = {MediaStore.Images.Media.DATA};
|
|
38
|
-
String result = null;
|
|
39
|
-
|
|
40
|
-
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
|
|
41
|
-
Cursor cursor = cursorLoader.loadInBackground();
|
|
42
|
-
|
|
43
|
-
if (cursor != null) {
|
|
44
|
-
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
|
45
|
-
cursor.moveToFirst();
|
|
46
|
-
result = cursor.getString(column_index);
|
|
47
|
-
cursor.close();
|
|
48
|
-
}
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
|
|
53
|
-
String[] proj = {MediaStore.Images.Media.DATA};
|
|
54
|
-
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
|
55
|
-
int column_index = 0;
|
|
56
|
-
String result = "";
|
|
57
|
-
if (cursor != null) {
|
|
58
|
-
column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
|
59
|
-
cursor.moveToFirst();
|
|
60
|
-
result = cursor.getString(column_index);
|
|
61
|
-
cursor.close();
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Get a file path from a Uri. This will get the the path for Storage Access
|
|
69
|
-
* Framework Documents, as well as the _data field for the MediaStore and
|
|
70
|
-
* other file-based ContentProviders.
|
|
71
|
-
*
|
|
72
|
-
* @param context The context.
|
|
73
|
-
* @param uri The Uri to query.
|
|
74
|
-
* @author paulburke
|
|
75
|
-
*/
|
|
76
|
-
@SuppressLint("NewApi")
|
|
77
|
-
public static String getRealPathFromURI_API19(final Context context, final Uri uri) {
|
|
78
|
-
|
|
79
|
-
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
|
80
|
-
|
|
81
|
-
// DocumentProvider
|
|
82
|
-
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
83
|
-
// ExternalStorageProvider
|
|
84
|
-
if (isExternalStorageDocument(uri)) {
|
|
85
|
-
final String docId = DocumentsContract.getDocumentId(uri);
|
|
86
|
-
final String[] split = docId.split(":");
|
|
87
|
-
final String type = split[0];
|
|
88
|
-
|
|
89
|
-
if ("primary".equalsIgnoreCase(type)) {
|
|
90
|
-
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// TODO handle non-primary volumes
|
|
94
|
-
}
|
|
95
|
-
// DownloadsProvider
|
|
96
|
-
else if (isDownloadsDocument(uri)) {
|
|
97
|
-
|
|
98
|
-
final String id = DocumentsContract.getDocumentId(uri);
|
|
99
|
-
final Uri contentUri = ContentUris.withAppendedId(
|
|
100
|
-
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
|
101
|
-
|
|
102
|
-
return getDataColumn(context, contentUri, null, null);
|
|
103
|
-
}
|
|
104
|
-
// MediaProvider
|
|
105
|
-
else if (isMediaDocument(uri)) {
|
|
106
|
-
final String docId = DocumentsContract.getDocumentId(uri);
|
|
107
|
-
final String[] split = docId.split(":");
|
|
108
|
-
final String type = split[0];
|
|
109
|
-
|
|
110
|
-
Uri contentUri = null;
|
|
111
|
-
if ("image".equals(type)) {
|
|
112
|
-
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
113
|
-
} else if ("video".equals(type)) {
|
|
114
|
-
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
115
|
-
} else if ("audio".equals(type)) {
|
|
116
|
-
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
final String selection = "_id=?";
|
|
120
|
-
final String[] selectionArgs = new String[]{
|
|
121
|
-
split[1]
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
return getDataColumn(context, contentUri, selection, selectionArgs);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// MediaStore (and general)
|
|
128
|
-
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
129
|
-
|
|
130
|
-
// Return the remote address
|
|
131
|
-
if (isGooglePhotosUri(uri))
|
|
132
|
-
return uri.getLastPathSegment();
|
|
133
|
-
|
|
134
|
-
return getDataColumn(context, uri, null, null);
|
|
135
|
-
}
|
|
136
|
-
// File
|
|
137
|
-
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
|
138
|
-
return uri.getPath();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get the value of the data column for this Uri. This is useful for
|
|
146
|
-
* MediaStore Uris, and other file-based ContentProviders.
|
|
147
|
-
*
|
|
148
|
-
* @param context The context.
|
|
149
|
-
* @param uri The Uri to query.
|
|
150
|
-
* @param selection (Optional) Filter used in the query.
|
|
151
|
-
* @param selectionArgs (Optional) Selection arguments used in the query.
|
|
152
|
-
* @return The value of the _data column, which is typically a file path.
|
|
153
|
-
*/
|
|
154
|
-
public static String getDataColumn(Context context, Uri uri, String selection,
|
|
155
|
-
String[] selectionArgs) {
|
|
156
|
-
|
|
157
|
-
Cursor cursor = null;
|
|
158
|
-
final String column = "_data";
|
|
159
|
-
final String[] projection = {
|
|
160
|
-
column
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
|
165
|
-
null);
|
|
166
|
-
if (cursor != null && cursor.moveToFirst()) {
|
|
167
|
-
final int index = cursor.getColumnIndexOrThrow(column);
|
|
168
|
-
return cursor.getString(index);
|
|
169
|
-
}
|
|
170
|
-
} finally {
|
|
171
|
-
if (cursor != null)
|
|
172
|
-
cursor.close();
|
|
173
|
-
}
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* @param uri The Uri to check.
|
|
180
|
-
* @return Whether the Uri authority is ExternalStorageProvider.
|
|
181
|
-
*/
|
|
182
|
-
public static boolean isExternalStorageDocument(Uri uri) {
|
|
183
|
-
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* @param uri The Uri to check.
|
|
188
|
-
* @return Whether the Uri authority is DownloadsProvider.
|
|
189
|
-
*/
|
|
190
|
-
public static boolean isDownloadsDocument(Uri uri) {
|
|
191
|
-
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* @param uri The Uri to check.
|
|
196
|
-
* @return Whether the Uri authority is MediaProvider.
|
|
197
|
-
*/
|
|
198
|
-
public static boolean isMediaDocument(Uri uri) {
|
|
199
|
-
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* @param uri The Uri to check.
|
|
204
|
-
* @return Whether the Uri authority is Google Photos.
|
|
205
|
-
*/
|
|
206
|
-
public static boolean isGooglePhotosUri(Uri uri) {
|
|
207
|
-
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
}
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
package com.reactnativecompressor.Utils;
|
|
2
|
-
|
|
3
|
-
import android.net.Uri;
|
|
4
|
-
import android.util.Log;
|
|
5
|
-
|
|
6
|
-
import androidx.annotation.Nullable;
|
|
7
|
-
|
|
8
|
-
import com.facebook.react.bridge.Arguments;
|
|
9
|
-
import com.facebook.react.bridge.Promise;
|
|
10
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
11
|
-
import com.facebook.react.bridge.ReactContext;
|
|
12
|
-
import com.facebook.react.bridge.WritableMap;
|
|
13
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
14
|
-
import numan.dev.videocompressor.VideoCompressTask;
|
|
15
|
-
import numan.dev.videocompressor.VideoCompressor;
|
|
16
|
-
|
|
17
|
-
import okhttp3.Call;
|
|
18
|
-
import okhttp3.Callback;
|
|
19
|
-
import okhttp3.OkHttpClient;
|
|
20
|
-
import okhttp3.Request;
|
|
21
|
-
import okhttp3.Response;
|
|
22
|
-
import okhttp3.ResponseBody;
|
|
23
|
-
|
|
24
|
-
import java.io.BufferedInputStream;
|
|
25
|
-
import java.io.File;
|
|
26
|
-
import java.io.FileOutputStream;
|
|
27
|
-
import java.io.IOException;
|
|
28
|
-
import java.net.HttpURLConnection;
|
|
29
|
-
import java.net.URL;
|
|
30
|
-
import java.net.URLConnection;
|
|
31
|
-
import java.util.HashMap;
|
|
32
|
-
import java.util.Map;
|
|
33
|
-
import java.util.UUID;
|
|
34
|
-
import java.util.concurrent.Semaphore;
|
|
35
|
-
import java.util.concurrent.atomic.AtomicReference;
|
|
36
|
-
|
|
37
|
-
public class Utils {
|
|
38
|
-
static int videoCompressionThreshold=10;
|
|
39
|
-
private static final String TAG = "react-native-compessor";
|
|
40
|
-
static Map<String, VideoCompressTask> compressorExports = new HashMap<>();
|
|
41
|
-
|
|
42
|
-
public static String generateCacheFilePath(String extension, ReactApplicationContext reactContext){
|
|
43
|
-
File outputDir = reactContext.getCacheDir();
|
|
44
|
-
|
|
45
|
-
String outputUri = String.format("%s/%s." + extension, outputDir.getPath(), UUID.randomUUID().toString());
|
|
46
|
-
return outputUri;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
public static void compressVideo(String srcPath, String destinationPath, int resultWidth, int resultHeight, float videoBitRate, String uuid, Promise promise, ReactApplicationContext reactContext){
|
|
51
|
-
final int[] currentVideoCompression = {0};
|
|
52
|
-
try{
|
|
53
|
-
VideoCompressTask export=VideoCompressor.convertVideo(srcPath, destinationPath, resultWidth, resultHeight, (int) videoBitRate, new VideoCompressor.ProgressListener() {
|
|
54
|
-
@Override
|
|
55
|
-
public void onStart() {
|
|
56
|
-
//convert start
|
|
57
|
-
}
|
|
58
|
-
@Override
|
|
59
|
-
public void onFinish(boolean result) {
|
|
60
|
-
String fileUrl="file://"+destinationPath;
|
|
61
|
-
//convert finish,result(true is success,false is fail)
|
|
62
|
-
promise.resolve(fileUrl);
|
|
63
|
-
MediaCache.removeCompletedImagePath(fileUrl);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
@Override
|
|
67
|
-
public void onError(String errorMessage) {
|
|
68
|
-
if(errorMessage.equals(("class java.lang.AssertionError")))
|
|
69
|
-
{
|
|
70
|
-
promise.resolve("file://"+srcPath);
|
|
71
|
-
}
|
|
72
|
-
else
|
|
73
|
-
{
|
|
74
|
-
promise.reject("Compression has canncelled");
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@Override
|
|
79
|
-
public void onProgress(float percent) {
|
|
80
|
-
int roundProgress=Math.round(percent);
|
|
81
|
-
if(roundProgress%videoCompressionThreshold==0&&roundProgress> currentVideoCompression[0]) {
|
|
82
|
-
WritableMap params = Arguments.createMap();
|
|
83
|
-
WritableMap data = Arguments.createMap();
|
|
84
|
-
params.putString("uuid", uuid);
|
|
85
|
-
data.putDouble("progress", percent / 100);
|
|
86
|
-
params.putMap("data", data);
|
|
87
|
-
sendEvent(reactContext, "videoCompressProgress", params);
|
|
88
|
-
currentVideoCompression[0] =roundProgress;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
compressorExports.put(uuid, export);
|
|
93
|
-
} catch (Exception ex) {
|
|
94
|
-
promise.reject(ex);
|
|
95
|
-
}
|
|
96
|
-
finally {
|
|
97
|
-
currentVideoCompression[0] =0;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public static void cancelCompressionHelper(String uuid){
|
|
102
|
-
try{
|
|
103
|
-
VideoCompressTask export=compressorExports.get(uuid);
|
|
104
|
-
export.cancel(true);
|
|
105
|
-
}
|
|
106
|
-
catch (Exception ex) {
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
private static void sendEvent(ReactContext reactContext,
|
|
111
|
-
String eventName,
|
|
112
|
-
@Nullable WritableMap params) {
|
|
113
|
-
reactContext
|
|
114
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
115
|
-
.emit(eventName, params);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
public static int getFileSizeFromURL(String urlString) {
|
|
119
|
-
URL url;
|
|
120
|
-
HttpURLConnection conn = null;
|
|
121
|
-
try {
|
|
122
|
-
url = new URL(urlString);
|
|
123
|
-
conn = (HttpURLConnection) url.openConnection();
|
|
124
|
-
conn.setRequestMethod("HEAD");
|
|
125
|
-
conn.getInputStream();
|
|
126
|
-
return conn.getContentLength();
|
|
127
|
-
} catch (IOException e) {
|
|
128
|
-
throw new RuntimeException(e);
|
|
129
|
-
} finally {
|
|
130
|
-
if (conn != null) {
|
|
131
|
-
conn.disconnect();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
public static String getRealPath(String fileUrl,ReactApplicationContext reactContext, String... args){
|
|
137
|
-
if(fileUrl.startsWith("content://"))
|
|
138
|
-
{
|
|
139
|
-
try {
|
|
140
|
-
Uri uri= Uri.parse(fileUrl);
|
|
141
|
-
fileUrl= RealPathUtil.getRealPath(reactContext,uri);
|
|
142
|
-
}
|
|
143
|
-
catch (Exception ex) {
|
|
144
|
-
Log.d(TAG, " Please see this issue: https://github.com/numandev1/react-native-compressor/issues/25");
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
else if(fileUrl.startsWith("http://")||fileUrl.startsWith("https://"))
|
|
148
|
-
{
|
|
149
|
-
String uuid = (args.length > 0) ? args[0] : "";
|
|
150
|
-
fileUrl=downloadMediaWithProgress(fileUrl,reactContext, uuid);
|
|
151
|
-
Log.d(TAG, "getRealPath: "+fileUrl);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return fileUrl;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
public static String downloadMediaWithProgress(String mediaUrl, ReactApplicationContext reactContext, String uuid) {
|
|
158
|
-
downloadCompression[0]=0;
|
|
159
|
-
OkHttpClient client = new OkHttpClient();
|
|
160
|
-
|
|
161
|
-
Request request = new Request.Builder()
|
|
162
|
-
.url(mediaUrl)
|
|
163
|
-
.build();
|
|
164
|
-
|
|
165
|
-
final Semaphore semaphore = new Semaphore(0); // Semaphore to wait for the download to complete
|
|
166
|
-
final AtomicReference<String> filePathRef = new AtomicReference<>(null); // To store the file path
|
|
167
|
-
|
|
168
|
-
// Perform the request asynchronously
|
|
169
|
-
client.newCall(request).enqueue(new Callback() {
|
|
170
|
-
@Override
|
|
171
|
-
public void onResponse(Call call, Response response) throws IOException {
|
|
172
|
-
if (response.isSuccessful()) {
|
|
173
|
-
ResponseBody responseBody = response.body();
|
|
174
|
-
if (responseBody != null) {
|
|
175
|
-
String fileExtension = "unknown"; // Default extension
|
|
176
|
-
|
|
177
|
-
// Detect the file extension based on the Content-Type header
|
|
178
|
-
String contentType = response.header("Content-Type");
|
|
179
|
-
if (contentType != null) {
|
|
180
|
-
if (contentType.equals("image/jpeg")) {
|
|
181
|
-
fileExtension = "jpg";
|
|
182
|
-
} else if (contentType.equals("image/png")) {
|
|
183
|
-
fileExtension = "png";
|
|
184
|
-
} else if (contentType.equals("video/mp4")) {
|
|
185
|
-
fileExtension = "mp4";
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
File cacheDir = reactContext.getCacheDir();
|
|
190
|
-
String randomFileName = UUID.randomUUID().toString() + "." + fileExtension;
|
|
191
|
-
File mediaFile = new File(cacheDir, randomFileName);
|
|
192
|
-
|
|
193
|
-
try (FileOutputStream fos = new FileOutputStream(mediaFile)) {
|
|
194
|
-
BufferedInputStream inputStream = new BufferedInputStream(responseBody.byteStream());
|
|
195
|
-
byte[] buffer = new byte[4096];
|
|
196
|
-
int bytesRead;
|
|
197
|
-
long totalBytesRead = 0;
|
|
198
|
-
long totalBytes = responseBody.contentLength();
|
|
199
|
-
|
|
200
|
-
if (totalBytes <= 0) {
|
|
201
|
-
totalBytes = 31457280;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
Log.d(TAG, totalBytesRead+" totalBytesRead "+totalBytes);
|
|
205
|
-
Log.d(TAG, response.toString()+" responseBody "+responseBody.toString());
|
|
206
|
-
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
207
|
-
fos.write(buffer, 0, bytesRead);
|
|
208
|
-
totalBytesRead += bytesRead;
|
|
209
|
-
double progressRatio = (double) totalBytesRead / totalBytes;
|
|
210
|
-
int progress = (int) (progressRatio * 100);
|
|
211
|
-
sendProgressUpdate(progress, uuid, reactContext);
|
|
212
|
-
}
|
|
213
|
-
fos.flush();
|
|
214
|
-
String filePath="file://" + mediaFile.getAbsolutePath();
|
|
215
|
-
MediaCache.addCompletedImagePath(filePath);
|
|
216
|
-
filePathRef.set(filePath); // Set the file path
|
|
217
|
-
} catch (IOException e) {
|
|
218
|
-
e.printStackTrace();
|
|
219
|
-
sendErrorResult(e.getMessage(), uuid, reactContext);
|
|
220
|
-
} finally {
|
|
221
|
-
semaphore.release(); // Release the semaphore when download is complete
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
} else {
|
|
225
|
-
sendErrorResult("Failed to download media: " + response.message(), uuid, reactContext);
|
|
226
|
-
semaphore.release(); // Release the semaphore in case of error
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
@Override
|
|
231
|
-
public void onFailure(Call call, IOException e) {
|
|
232
|
-
e.printStackTrace();
|
|
233
|
-
sendErrorResult(e.getMessage(), uuid, reactContext);
|
|
234
|
-
semaphore.release(); // Release the semaphore in case of failure
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
try {
|
|
239
|
-
semaphore.acquire(); // Wait for the download to complete
|
|
240
|
-
} catch (InterruptedException e) {
|
|
241
|
-
e.printStackTrace();
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return filePathRef.get(); // Return the file path
|
|
245
|
-
}
|
|
246
|
-
static final int[] downloadCompression = {0};
|
|
247
|
-
private static void sendProgressUpdate(int progress, String uuid, ReactApplicationContext reactContext) {
|
|
248
|
-
int roundProgress=Math.round(progress);
|
|
249
|
-
if(roundProgress%videoCompressionThreshold==0&&roundProgress> downloadCompression[0]) {
|
|
250
|
-
WritableMap params = Arguments.createMap();
|
|
251
|
-
WritableMap data = Arguments.createMap();
|
|
252
|
-
params.putString("uuid", uuid);
|
|
253
|
-
data.putDouble("progress", progress / 100.0);
|
|
254
|
-
params.putMap("data", data);
|
|
255
|
-
sendEvent(reactContext, "downloadProgress", params);
|
|
256
|
-
Log.d(TAG, "downloadProgress: " + (progress / 100.0));
|
|
257
|
-
downloadCompression[0] =roundProgress;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
private static void sendErrorResult(String error, String uuid, ReactApplicationContext reactContext) {
|
|
262
|
-
WritableMap params = Arguments.createMap();
|
|
263
|
-
WritableMap data = Arguments.createMap();
|
|
264
|
-
params.putString("uuid", uuid);
|
|
265
|
-
params.putString("error", error);
|
|
266
|
-
params.putMap("data", data);
|
|
267
|
-
Log.d(TAG, "videoDownloadError: "+error);
|
|
268
|
-
sendEvent(reactContext, "videoDownloadError", params);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|