@visakov.dev/react-native-compressor
v1.9.1
Published
Compress Image, Video, and Audio same like Whatsapp & Auto/Manual Compression | Background Upload | Download File | Create Video Thumbnail
Downloads
89
Maintainers
Keywords
Readme
REACT-NATIVE-COMPRESSOR is a react-native package, which helps us to Compress Image
, Video
, and Audio
before uploading, same like Whatsapp without knowing the compression algorithm
Why should we use react-native-compress over FFmpeg?
We should use react-native-compressor instead of FFmpeg because react-native-compressor gives you same compression of Whatsapp (Image, Video, and Audio
) without knowing the algorithm of compression + it is lightweight only increase 50 KB Size Size in APK while FFmpeg increase ~> 9 MB Size in APK, and we have to give manual image/video/Audo size and quality as well as
If you find this package useful hit the star 🌟
Would you like to support me?
See the Benchmarks
Table of Contents
Installation
yarn add react-native-compressor
New Architecture (Turbo Module) Supported
you can give feedback on Discord channel
Managed Expo
expo install react-native-compressor
Add the Compressor plugin to your Expo config (app.json
, app.config.json
or app.config.js
):
{
"name": "my app",
"plugins": ["react-native-compressor"]
}
Finally, compile the mods:
expo prebuild
To apply the changes, build a new binary with EAS:
eas build
Automatic linking (for React Native >= 0.60 only)
Automatic linking is supported for both Android
and IOS
Linking (for React Native <= 0.59 only)
Note: If you are using react-native version 0.60 or higher you don't need to link this package.
react-native link react-native-compressor
Manual installation
iOS
- In XCode, open Podfile
- paste this line
pod 'react-native-compressor', :path => '../node_modules/react-native-compressor'
intoPodfile
- run this command inside ios folder
pod install
- Run your project (
Cmd+R
)<
Android
- Open up
android/app/src/main/java/[...]/MainActivity.java
- Add
import com.reactnativecompressor.CompressorPackage;
to the imports at the top of the file - Add
new CompressorPackage()
to the list returned by thegetPackages()
method
- Append the following lines to
android/settings.gradle
:include ':react-native-compressor' project(':react-native-compressor').projectDir = new File(rootProject.projectDir,'../node_modules/react-native-compressor/android')
- Insert the following lines inside the dependencies block in
android/app/build.gradle
:compile project(':react-native-compressor')
Usage
Image
Automatic Image Compression Like Whatsapp
import { Image } from 'react-native-compressor';
const result = await Image.compress('file://path_of_file/image.jpg');
// OR
const result = await Image.compress('https://path_of_file/image.jpg', {
progressDivider: 10,
downloadProgress: (progress) => {
console.log('downloadProgress: ', progress);
},
});
Here is this package comparison of images compression with WhatsApp
Manual Image Compression
import { Image } from 'react-native-compressor';
const result = await Image.compress('file://path_of_file/image.jpg', {
compressionMethod: 'manual',
maxWidth: 1000,
quality: 0.8,
});
Video
Automatic Video Compression Like Whatsapp
import { Video } from 'react-native-compressor';
const result = await Video.compress(
'file://path_of_file/BigBuckBunny.mp4',
{},
(progress) => {
console.log('Compression Progress: ', progress);
}
);
//OR
const result = await Video.compress(
'https://example.com/video.mp4',
{
progressDivider: 10,
downloadProgress: (progress) => {
console.log('downloadProgress: ', progress);
},
},
(progress) => {
console.log('Compression Progress: ', progress);
}
);
Here is this package comparison of video compression with WhatsApp
Manual Video Compression
import { Video } from 'react-native-compressor';
const result = await Video.compress(
'file://path_of_file/BigBuckBunny.mp4',
{
compressionMethod: 'manual',
},
(progress) => {
console.log('Compression Progress: ', progress);
}
);
Cancel Video Compression
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
import { Audio } from 'react-native-compressor';
const result = await Audio.compress(
'file://path_of_file/file_example_MP3_2MG.wav', // recommended wav file but can be use mp3 file
{ quality: 'medium' }
);
// OR
const result = await Audio.compress(
'file://path_of_file/file_example_MP3_2MG.wav', // recommended wav file but can be use mp3 file
{
bitrate: 64000,
samplerate: 44100,
channels: 1,
}
);
Background Upload
import { backgroundUpload } from 'react-native-compressor';
const headers = {};
const uploadResult = await backgroundUpload(
url,
fileUrl,
{ httpMethod: 'PUT', headers },
(written, total) => {
console.log(written, total);
}
);
//OR
const uploadResult = await backgroundUpload(
url,
fileUrl,
{ uploadType: UploadType.MULTIPART, httpMethod: 'POST', headers },
(written, total) => {
console.log(written, total);
}
);
Cancel Background Upload
for cancellation Upload, there is two ways
- by calling, cancelUpload function
- by calling abort function
cancelUpload (support single and all)
import { cancelUpload, backgroundUpload } from 'react-native-compressor';
// if we will call without passing any param then it will remove last pushed uploading
cancelUpload()
// if you pass true as second param then it will cancel all the uploading
cancelUpload("",true)
// if there is multiple files are uploading, and you wanna cancel specific uploading then you pass specific video id like this
let videoId=''
const uploadResult = await backgroundUpload(
url,
fileUrl,
{ httpMethod: 'PUT', getCancellationId: (cancellationId) =>(videoId = cancellationId), },
(written, total) => {
console.log(written, total);
}
);
cancelUpload(videoId)
cancel by calling abort
import { backgroundUpload } from 'react-native-compressor';
const abortSignalRef = useRef(new AbortController());
const uploadResult = await backgroundUpload(
url,
fileUrl,
{ httpMethod: 'PUT' },
(written, total) => {
console.log(written, total);
},
abortSignalRef.current.signal
);
abortSignalRef.current?.abort(); // this will cancel uploading
Download File
import { download } from 'react-native-compressor';
const downloadFileUrl = await download(url, (progress) => {
console.log('downloadProgress: ', progress);
});
Video Thumbnail
import { createVideoThumbnail, clearCache } from 'react-native-compressor';
const thumbnail = await createVideoThumbnail(videoUri);
await clearCache(); // this will clear cache of thumbnails cache directory
API
Image
ImageCompressor
compress(value: string, options?: CompressorOptions): Promise<string>
Compresses the input file URI or base-64 string with the specified options. Promise returns a string after compression has completed. Resizing will always keep the original aspect ratio of the image, the
maxWidth
andmaxHeight
are used as a boundary.
CompressorOptions
compressionMethod: compressionMethod
(default: "auto")if you want to compress images like whatsapp then make this prop
auto
. Can be eithermanual
orauto
, defines the Compression Method.downloadProgress?: (progress: number) => void;
it is callback, only trigger when we pass image url from server
progressDivider?: number
(default: 0)we uses it when we use downloadProgress
maxWidth: number
(default: 1280)The maximum width boundary used as the main boundary in resizing a landscape image.
maxHeight: number
(default: 1280)The maximum height boundary used as the main boundary in resizing a portrait image.
quality: number
(default: 0.8)The quality modifier for the
JPEG
andPNG
file format, if your input file isJPEG
and output file isPNG
then compressed size can be increaseinput: InputType
(default: uri)Can be either
uri
orbase64
, defines the contentents of thevalue
parameter.output: OutputType
(default: jpg)The quality modifier for the
JPEG
file format, can be specified when output isPNG
but will be ignored. if you wanna apply quality modifier then you can enabledisablePngTransparency:true
, Note: if you png image have no transparent background then enabledisablePngTransparency:true
modifier is recommendeddisablePngTransparency: boolean
(default: false)when user add
output:'png'
then by default compressed image will have transparent background, and quality will be ignored, if you wanna apply quality then you have to disablePngTransparency likedisablePngTransparency:true
, it will convert transparent background to whitereturnableOutputType: ReturnableOutputType
(default: uri)Can be either
uri
orbase64
, defines the Returnable output image format.
if you wanna get image metadata (exif) then read this
Video
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 optionsactivateBackgroundTask(onExpired?: (data: any) => void): Promise<any>
if you wanna compress video while app is in backgroup then you should call this method before compression
deactivateBackgroundTask(): Promise<any>
if you call
activateBackgroundTask
method, then after video compression, you should calldeactivateBackgroundTask
for disable background task mode.getCancellationId: function
getCancellationId
is a callback function that gives us compress video id, which can be used inVideo.cancelCompression
method to cancel the compression
videoCompresssionType
compressionMethod: compressionMethod
(default: "manual")if you want to compress videos like whatsapp then make this prop
auto
. Can be eithermanual
orauto
, defines the Compression Method.downloadProgress?: (progress: number) => void;
it is callback, only trigger when we pass image url from server
progressDivider?: number
(default: 0)we uses it when we use downloadProgress/onProgress
maxSize: number
(default: 640)The maximum size can be height in case of portrait video or can be width in case of landscape video.
bitrate: number
bitrate of video which reduce or increase video size. if compressionMethod will auto then this prop will not work
minimumFileSizeForCompress: number
(default: 0)previously default was 16 but now it is 0 by default. 0 mean 0mb. This is an offset, which you can set for minimumFileSizeForCompress will allow this package to dont compress less than or equal to
minimumFileSizeForCompress
ref #26
if you wanna get video metadata then read this
Audio
Android: recommended to usecompress(url: string, options?: audioCompresssionType): Promise<string>
wav
file as we convert mp3 to wav then apply bitrate
audioCompresssionType
quality?: qualityType
(default: medium)we can also control bitrate through quality. qualityType can be
low
|medium
|high
bitrate?: number
Range [64000-320000]we can control bitrate of audio through bitrate, it should be in the range of
64000-320000
samplerate?: number
Range [44100 - 192000]we can control samplerate of audio through samplerate, it should be in the range of
44100 - 192000
channels?: number
Typically 1 or 2we can control channels of audio through channels, Typically 1 or 2
Background Upload
backgroundUpload: (url: string, fileUrl: string, options: UploaderOptions, onProgress?: ((writtem: number, total: number) => void) | undefined) => Promise< any >
UploaderOptions
export enum UploadType {
BINARY_CONTENT = 0,
MULTIPART = 1,
}
export enum UploaderHttpMethod {
POST = 'POST',
PUT = 'PUT',
PATCH = 'PATCH',
}
export declare type HTTPResponse = {
status: number;
headers: Record<string, string>;
body: string;
};
export declare type HttpMethod = 'POST' | 'PUT' | 'PATCH';
export declare type UploaderOptions = (
| {
uploadType?: UploadType.BINARY_CONTENT;
mimeType?: string;
}
| {
uploadType: UploadType.MULTIPART;
fieldName?: string;
mimeType?: string;
parameters?: Record<string, string>;
}
) & {
headers?: Record<string, string>;
httpMethod?: UploaderHttpMethod;
getCancellationId?: (cancellationId: string) => void;
};
Note: some of the uploader code is borrowed from Expo I tested file uploader on this backend Nodejs-File-Uploader
Cancel Background Upload
for cancellation Upload, there is two ways, you can use one of it
cancelUpload: ( uuid?: string, shouldCancelAll?: boolean) => void
- If we call without passing any param then it will remove the last pushed uploading
- If you pass true as the second param then it will cancel all the uploading
- if there is multiple files are uploading, and you wanna cancel specific uploading then you pass a specific video ID like this
we can use AbortController in backgroundUpload Usage
const abortSignalRef = useRef(new AbortController());
abortSignalRef.current?.abort();
Download
download: ( fileUrl: string, downloadProgress?: (progress: number) => void, progressDivider?: number ) => Promise< string >
Create Video Thumbnail and Clear Cache
createVideoThumbnail( fileUrl: string, options: {header:Object} ): Promise<{ path: string;size: number; mime: string; width: number; height: number; }>
it will save the thumbnail of the video into the cache directory and return the thumbnail URI which you can display
clearCache(cacheDir?: string): Promise< string >
it will clear the cache that was created from createVideoThumbnail, in future this clear cache will be totally customized
Get Metadata Of Video
if you want to get metadata of video than you can use this function
import { getVideoMetaData } from 'react-native-compressor';
const metaData = await getVideoMetaData(filePath);
{
"duration": 20.11,
"extension": "mp4",
"height": 1080,
"size": 16940.0,
"width": 1920
}
getVideoMetaData(path: string)
Get Metadata Of Image
if you want to get metadata of video than you can use this function
import { getImageMetaData } from 'react-native-compressor';
const metaData = await getImageMetaData(filePath);
{
"ImageWidth": 4032,
"ImageHeight": 3024,
"Orientation": 3,
"size": 4127057,
"extension": "jpg",
"exif":{...}
}
getImageMetaData(path: string)
Get Real Path
if you want to convert
content://
tofile:///
for androidph://
tofile:///
for IOS
then you can call getRealPath
function like this
import { getRealPath } from 'react-native-compressor';
const realPath = await getRealPath(fileUri, 'video'); // file://file_path.extension
getRealPath(path: string, type: string = 'video'|'image')
Get Temp file Path
if you wanna make random file path in cache folder then you can use this method like this
import { generateFilePath } from 'react-native-compressor';
const randomFilePathForSaveFile = await generateFilePath('mp4'); // file://file_path.mp4
generateFilePath(fileextension: string)
Benchmark
Whatsapp: compresses Images,Videos and Audios in every effect way
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT