Skip to content

Commit

Permalink
feat: add cancellation compression in IOS and android
Browse files Browse the repository at this point in the history
  • Loading branch information
numandev1 committed Dec 22, 2021
1 parent 7b6e50e commit 443cefa
Show file tree
Hide file tree
Showing 18 changed files with 1,304 additions and 144 deletions.
37 changes: 36 additions & 1 deletion README.md
Expand Up @@ -33,7 +33,7 @@ If you find this package useful hit the star 🌟
#### For React Native<0.65

```sh
yarn add react-native-compressor@0.5.9
yarn add react-native-compressor@0.5.11
```

#### For React Native 0.65 or greater
Expand Down Expand Up @@ -176,6 +176,34 @@ const result = await Video.compress(
);
```

##### Cancel Video Compression

```js
import { Video } from 'react-native-compressor';

let cancellationVideoId = '';

const result = await Video.compress(
'file://path_of_file/BigBuckBunny.mp4',
{
compressionMethod: 'auto',
// getCancellationId for get video id which we can use for cancel compression
getCancellationId: (cancellationId) =>
(cancellationVideoId = cancellationId),
},
(progress) => {
if (backgroundMode) {
console.log('Compression Progress: ', progress);
} else {
setCompressingProgress(progress);
}
}
);

// we can cancel video compression by calling cancelCompression with cancel video id which we can get from getCancellationId function while compression
Video.cancelCompression(cancellationVideoId);
```

### Audio

```js
Expand Down Expand Up @@ -247,6 +275,9 @@ const uploadResult = await backgroundUpload(

- ###### `compress(url: string, options?: videoCompresssionType , onProgress?: (progress: number)): Promise<string>`

- ###### `cancelCompression(cancellationId: string): void`
we can get cancellationId from `getCancellationId` which is the callback method of compress method options

### videoCompresssionType

- ###### `compressionMethod: compressionMethod` (default: "manual")
Expand All @@ -262,8 +293,12 @@ const uploadResult = await backgroundUpload(
bitrate of video which reduce or increase video size. if compressionMethod will auto then this prop will not work

- ###### `minimumFileSizeForCompress: number` (default: 16)

16 means 16mb. default our package do not compress under 16mb video file. minimumFileSizeForCompress will allow us to change this 16mb offset. fixed [#26](https://github.com/Shobbak/react-native-compressor/issues/26)

- ###### `getCancellationId: function`
`getCancellationId` is a callback function that gives us compress video id, which can be used in `Video.cancelCompression` method to cancel the compression

## Audio

- ###### `compress(url: string, options?: audioCompresssionType): Promise<string>`
Expand Down
1 change: 0 additions & 1 deletion android/build.gradle
Expand Up @@ -58,6 +58,5 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0"
implementation "com.googlecode.mp4parser:isoparser:1.0.6"
implementation 'com.github.zolad:VideoSlimmer:master-SNAPSHOT'
implementation 'io.github.lizhangqu:coreprogress:1.0.2'
}
Expand Up @@ -14,9 +14,9 @@

import androidx.annotation.RequiresApi;

import com.zolad.videoslimmer.VideoSlimmer;
import com.zolad.videoslimmer.listner.SlimProgressListener;
import com.zolad.videoslimmer.muxer.CodecInputSurface;
import com.reactnativecompressor.Video.videoslimmer.VideoSlimmer;
import com.reactnativecompressor.Video.videoslimmer.listner.SlimProgressListener;
import com.reactnativecompressor.Video.videoslimmer.muxer.CodecInputSurface;

import java.io.File;
import java.io.IOException;
Expand Down
Expand Up @@ -23,7 +23,7 @@
import com.reactnativecompressor.Image.ImageCompressor;
import com.reactnativecompressor.Image.utils.ImageCompressorOptions;
import com.reactnativecompressor.Video.VideoCompressorHelper;
import com.zolad.videoslimmer.VideoSlimmer;
import com.reactnativecompressor.Video.videoslimmer.VideoSlimmer;

import static com.reactnativecompressor.Utils.Utils.generateCacheFilePath;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -110,6 +110,10 @@ public void onFinish(boolean result) {
Log.d("nomi onFinish", "onProgress: ");
}

@Override
public void onError(String errorMessage) {

}

@Override
public void onProgress(float percent) {
Expand Down
74 changes: 74 additions & 0 deletions android/src/main/java/com/reactnativecompressor/Utils/Utils.java
@@ -1,15 +1,89 @@
package com.reactnativecompressor.Utils;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.reactnativecompressor.Video.videoslimmer.VideoSlimTask;
import com.reactnativecompressor.Video.videoslimmer.VideoSlimmer;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class Utils {
static int videoCompressionThreshold=10;
static int currentVideoCompression=0;
static Map<String, VideoSlimTask> compressorExports = new HashMap<>();

public static String generateCacheFilePath(String extension, ReactApplicationContext reactContext){
File outputDir = reactContext.getCacheDir();

String outputUri = String.format("%s/%s." + extension, outputDir.getPath(), UUID.randomUUID().toString());
return outputUri;
}


public static void compressVideo(String srcPath, String destinationPath, int resultWidth, int resultHeight, float videoBitRate, String uuid, Promise promise, ReactApplicationContext reactContext){
try{
VideoSlimTask export=VideoSlimmer.convertVideo(srcPath, destinationPath, resultWidth, resultHeight, (int) videoBitRate, new VideoSlimmer.ProgressListener() {
@Override
public void onStart() {
//convert start
}
@Override
public void onFinish(boolean result) {
//convert finish,result(true is success,false is fail)
promise.resolve("file:/"+destinationPath);
}

@Override
public void onError(String errorMessage) {
promise.resolve(srcPath);
}

@Override
public void onProgress(float percent) {
int roundProgress=Math.round(percent);
if(roundProgress%videoCompressionThreshold==0&&roundProgress>currentVideoCompression) {
WritableMap params = Arguments.createMap();
WritableMap data = Arguments.createMap();
params.putString("uuid", uuid);
data.putDouble("progress", percent / 100);
params.putMap("data", data);
sendEvent(reactContext, "videoCompressProgress", params);
currentVideoCompression=roundProgress;
}
}
});
compressorExports.put(uuid, export);
} catch (Exception ex) {
promise.reject(ex);
}
finally {
currentVideoCompression=0;
}
}

public static void cancelCompressionHelper(String uuid){
try{
VideoSlimTask export=compressorExports.get(uuid);
export.cancel(true);
}
catch (Exception ex) {
}
}

private static void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
@@ -1,30 +1,23 @@
package com.reactnativecompressor.Video.AutoVideoCompression;

import android.media.MediaCodecInfo;
import android.media.MediaMetadataRetriever;
import android.media.session.MediaController;
import android.net.Uri;
import android.os.Build;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.reactnativecompressor.Video.VideoCompressorHelper;
import com.zolad.videoslimmer.VideoSlimmer;
import static com.reactnativecompressor.Utils.Utils.compressVideo;

import java.io.File;

import static com.reactnativecompressor.Utils.Utils.generateCacheFilePath;

public class AutoVideoCompression {
static int videoCompressionThreshold=10;
static int currentVideoCompression=0;

public static void createCompressionSettings(String fileUrl,VideoCompressorHelper options,Promise promise, ReactApplicationContext reactContext) {
float maxSize = options.maxSize;
float minimumFileSizeForCompress=options.minimumFileSizeForCompress;
Expand Down Expand Up @@ -52,43 +45,16 @@ public static void createCompressionSettings(String fileUrl,VideoCompressorHelpe
bitrate,
resultHeight, resultWidth
);

VideoSlimmer.convertVideo(srcPath, destinationPath, resultWidth, resultHeight, (int) videoBitRate, new VideoSlimmer.ProgressListener() {
@Override
public void onStart() {
//convert start
}
@Override
public void onFinish(boolean result) {
//convert finish,result(true is success,false is fail)
promise.resolve("file:/"+destinationPath);
}
@Override
public void onProgress(float percent) {
int roundProgress=Math.round(percent);
if(roundProgress%videoCompressionThreshold==0&&roundProgress>currentVideoCompression) {
WritableMap params = Arguments.createMap();
WritableMap data = Arguments.createMap();
params.putString("uuid", options.uuid);
data.putDouble("progress", percent / 100);
params.putMap("data", data);
sendEvent(reactContext, "videoCompressProgress", params);
currentVideoCompression=roundProgress;
}
}
});

compressVideo(srcPath, destinationPath, resultWidth, resultHeight, videoBitRate,options.uuid,promise,reactContext);
}
else
{
promise.resolve(fileUrl);
}

} catch (Exception ex) {
promise.reject(ex);
}
finally {
currentVideoCompression=0;
}
}

public static int makeVideoBitrate(int originalHeight, int originalWidth, int originalBitrate, int height, int width) {
Expand Down
Expand Up @@ -8,7 +8,6 @@

import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
Expand All @@ -17,13 +16,12 @@
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.reactnativecompressor.Image.utils.ImageCompressorOptions;
import com.reactnativecompressor.Utils.FileUplaoder.FileUploader;
import com.reactnativecompressor.Video.AutoVideoCompression.AutoVideoCompression;
import com.zolad.videoslimmer.VideoSlimmer;

import java.util.UUID;

import static com.reactnativecompressor.Utils.Utils.compressVideo;
import static com.reactnativecompressor.Utils.Utils.generateCacheFilePath;

public class VideoCompressorHelper {
Expand Down Expand Up @@ -166,44 +164,10 @@ public static void VideoCompressManual(String fileUrl,VideoCompressorHelper opti
}
}
float videoBitRate = (options.bitrate>0)?options.bitrate: (float) (height * width * 1.5);

VideoSlimmer.convertVideo(srcPath, destinationPath, width, height, (int) videoBitRate, new VideoSlimmer.ProgressListener() {


@Override
public void onStart() {
//convert start

}

@Override
public void onFinish(boolean result) {
//convert finish,result(true is success,false is fail)
promise.resolve("file:/"+destinationPath);
}


@Override
public void onProgress(float percent) {
int roundProgress=Math.round(percent);
if(roundProgress%videoCompressionThreshold==0&&roundProgress>currentVideoCompression) {
WritableMap params = Arguments.createMap();
WritableMap data = Arguments.createMap();
params.putString("uuid", options.uuid);
data.putDouble("progress", percent / 100);
params.putMap("data", data);
sendEvent(reactContext, "videoCompressProgress", params);
currentVideoCompression=roundProgress;
}
}
});

compressVideo(srcPath, destinationPath, width, height, videoBitRate,options.uuid,promise,reactContext);
} catch (Exception ex) {
promise.reject(ex);
}
finally {
currentVideoCompression=0;
}
}


Expand Down
@@ -1,12 +1,10 @@
package com.reactnativecompressor.Video;

import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
Expand All @@ -16,14 +14,11 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.reactnativecompressor.Image.utils.ImageCompressorOptions;
import com.zolad.videoslimmer.VideoSlimmer;

import static com.reactnativecompressor.Utils.Utils.generateCacheFilePath;
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_activateBackgroundTask_helper;
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_deactivateBackgroundTask_helper;
import static com.reactnativecompressor.Video.VideoCompressorHelper.video_upload_helper;

import static com.reactnativecompressor.Utils.Utils.cancelCompressionHelper;
@ReactModule(name = VideoModule.NAME)
public class VideoModule extends ReactContextBaseJavaModule {
public static final String NAME = "VideoCompressor";
Expand Down Expand Up @@ -67,6 +62,13 @@ public void compress(

}

@ReactMethod
public void cancelCompression(
String uuid) {
cancelCompressionHelper(uuid);
Log.d("cancelCompression", uuid);
}

@ReactMethod
public void upload(
String fileUrl,
Expand Down

0 comments on commit 443cefa

Please sign in to comment.