2525package com .shahenlibrary .Trimmer ;
2626
2727import android .annotation .TargetApi ;
28+ import android .content .Context ;
2829import android .graphics .Bitmap ;
2930import android .graphics .Matrix ;
3031import android .media .MediaMetadataRetriever ;
3940import com .facebook .react .bridge .ReadableMap ;
4041import com .facebook .react .bridge .WritableArray ;
4142import com .facebook .react .bridge .WritableMap ;
42- import com .facebook .react .uimanager .events . Event ;
43+ import com .facebook .react .uimanager .ThemedReactContext ;
4344import com .shahenlibrary .Events .Events ;
44- import com .shahenlibrary .Events . EventsEnum ;
45+ import com .shahenlibrary .interfaces . OnCompressVideoListener ;
4546import com .shahenlibrary .interfaces .OnTrimVideoListener ;
4647import com .shahenlibrary .utils .VideoEdit ;
4748
@@ -90,12 +91,12 @@ public static void getPreviewImages(String path, Promise promise, ReactApplicati
9091 float scaleHeight = ((float ) resizeHeight ) / height ;
9192
9293 Log .d (TrimmerManager .REACT_PACKAGE , "getPreviewImages: \n \t duration: " + duration +
93- "\n \t width: " + width +
94- "\n \t height: " + height +
95- "\n \t orientation: " + orientation +
96- "\n \t aspectRatio: " + aspectRatio +
97- "\n \t resizeWidth: " + resizeWidth +
98- "\n \t resizeHeight: " + resizeHeight
94+ "\n \t width: " + width +
95+ "\n \t height: " + height +
96+ "\n \t orientation: " + orientation +
97+ "\n \t aspectRatio: " + aspectRatio +
98+ "\n \t resizeWidth: " + resizeWidth +
99+ "\n \t resizeHeight: " + resizeHeight
99100 );
100101
101102 Matrix mx = new Matrix ();
@@ -141,6 +142,11 @@ public static void getVideoInfo(String path, Promise promise, ReactApplicationCo
141142 int width = Integer .parseInt (mmr .extractMetadata (FFmpegMediaMetadataRetriever .METADATA_KEY_VIDEO_WIDTH ));
142143 int height = Integer .parseInt (mmr .extractMetadata (FFmpegMediaMetadataRetriever .METADATA_KEY_VIDEO_HEIGHT ));
143144 int orientation = Integer .parseInt (mmr .extractMetadata (FFmpegMediaMetadataRetriever .METADATA_KEY_VIDEO_ROTATION ));
145+ if (orientation == 90 || orientation == 270 ) {
146+ width = width + height ;
147+ height = width - height ;
148+ width = width - height ;
149+ }
144150
145151 WritableMap event = Arguments .createMap ();
146152 WritableMap size = Arguments .createMap ();
@@ -149,7 +155,7 @@ public static void getVideoInfo(String path, Promise promise, ReactApplicationCo
149155 size .putInt (Events .HEIGHT , height );
150156
151157 event .putMap (Events .SIZE , size );
152- event .putInt (Events .DURATION , duration );
158+ event .putInt (Events .DURATION , duration / 1000 );
153159 event .putInt (Events .ORIENTATION , orientation );
154160
155161 promise .resolve (event );
@@ -215,7 +221,97 @@ public void cancelAction() {
215221 }
216222 }
217223
218- static File createTempFile (String extension , final Promise promise , ReactApplicationContext ctx ) {
224+ public static void compress (String source , ReadableMap options , final Promise promise , final OnCompressVideoListener cb , ThemedReactContext tctx , ReactApplicationContext rctx ) {
225+ Context ctx = tctx != null ? tctx : rctx ;
226+
227+ FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever ();
228+ if (VideoEdit .shouldUseURI (source )) {
229+ retriever .setDataSource (ctx , Uri .parse (source ));
230+ } else {
231+ retriever .setDataSource (source );
232+ }
233+ retriever .release ();
234+ Log .d (LOG_TAG , "OPTIONS: " + options .toString ());
235+ Double width = options .hasKey ("width" ) ? options .getDouble ("width" ) : null ;
236+ Double height = options .hasKey ("height" ) ? options .getDouble ("height" ) : null ;
237+ Double minimumBitrate = options .hasKey ("minimumBitrate" ) ? options .getDouble ("minimumBitrate" ) : null ;
238+ Double bitrateMultiplier = options .hasKey ("bitrateMultiplier" ) ? options .getDouble ("bitrateMultiplier" ) : null ;
239+ Boolean removeAudio = options .hasKey ("removeAudio" ) ? options .getBoolean ("removeAudio" ) : false ;
240+
241+ final File tempFile = createTempFile ("mp4" , promise , ctx );
242+
243+ ArrayList <String > cmd = new ArrayList <String >();
244+ cmd .add ("-y" );
245+ cmd .add ("-i" );
246+ cmd .add (source );
247+ cmd .add ("-c:v" );
248+ cmd .add ("libx264" );
249+ if (width != null && height != null ) {
250+ cmd .add ("-vf" );
251+ cmd .add ("scale=" + Double .toString (width ) + ":" + Double .toString (height ));
252+ }
253+
254+ cmd .add ("-preset" );
255+ cmd .add ("ultrafast" );
256+ cmd .add ("-pix_fmt" );
257+ cmd .add ("yuv420p" );
258+
259+ if (removeAudio ) {
260+ cmd .add ("-an" );
261+ }
262+ cmd .add (tempFile .getPath ());
263+
264+ final String [] cmdToExec = cmd .toArray ( new String [0 ] );
265+
266+ Log .d (LOG_TAG , Arrays .toString (cmdToExec ));
267+
268+ try {
269+ FFmpeg .getInstance (ctx ).execute (cmdToExec , new FFmpegExecuteResponseHandler () {
270+
271+ @ Override
272+ public void onStart () {
273+ Log .d (LOG_TAG , "Compress: Start" );
274+ }
275+
276+ @ Override
277+ public void onProgress (String message ) {
278+ }
279+
280+ @ Override
281+ public void onFailure (String message ) {
282+ if (cb != null ) {
283+ cb .onError ("compress error: failed. " + message );
284+ } else if (promise != null ) {
285+ promise .reject ("compress error: failed." , message );
286+ }
287+ }
288+
289+ @ Override
290+ public void onSuccess (String message ) {
291+ if (cb != null ) {
292+ cb .onSuccess ("file://" + tempFile .getPath ());
293+ } else if (promise != null ) {
294+ WritableMap event = Arguments .createMap ();
295+ event .putString ("source" , "file://" + tempFile .getPath ());
296+ promise .resolve (event );
297+ }
298+ }
299+
300+ @ Override
301+ public void onFinish () {
302+ Log .d (LOG_TAG , "Compress: Finished" );
303+ }
304+ });
305+ } catch (Exception e ) {
306+ if (cb != null ) {
307+ cb .onError ("compress error. Command already running" + e .toString ());
308+ } else if (promise != null ) {
309+ promise .reject ("compress error. Command already running" , e .toString ());
310+ }
311+ }
312+ }
313+
314+ static File createTempFile (String extension , final Promise promise , Context ctx ) {
219315 UUID uuid = UUID .randomUUID ();
220316 String imageName = uuid .toString () + "-screenshot" ;
221317
@@ -256,7 +352,7 @@ static void getPreviewImageAtPosition(String source, double sec, String format,
256352
257353 WritableMap event = Arguments .createMap ();
258354
259- if ( format . equals ( null ) || format .equals ("base64" ) ) {
355+ if ( format == null || ( format != null && format .equals ("base64" ) ) ) {
260356 bmp .compress (Bitmap .CompressFormat .PNG , 100 , byteArrayOutputStream );
261357 byte [] byteArray = byteArrayOutputStream .toByteArray ();
262358 String encoded = Base64 .encodeToString (byteArray , Base64 .DEFAULT );
@@ -406,27 +502,27 @@ public void onFinish() {
406502 public static void loadFfmpeg (ReactApplicationContext ctx ){
407503 try {
408504 FFmpeg .getInstance (ctx ).loadBinary (new FFmpegLoadBinaryResponseHandler () {
409- @ Override
410- public void onStart () {
411- Log .d (LOG_TAG , "load FFMPEG: onStart" );
412- }
505+ @ Override
506+ public void onStart () {
507+ Log .d (LOG_TAG , "load FFMPEG: onStart" );
508+ }
413509
414- @ Override
415- public void onSuccess () {
416- Log .d (LOG_TAG , "load FFMPEG: onSuccess" );
417- ffmpegLoaded = true ;
418- }
510+ @ Override
511+ public void onSuccess () {
512+ Log .d (LOG_TAG , "load FFMPEG: onSuccess" );
513+ ffmpegLoaded = true ;
514+ }
419515
420- @ Override
421- public void onFailure () {
422- ffmpegLoaded = false ;
423- Log .d (LOG_TAG , "load FFMPEG: Failed to load ffmpeg" );
424- }
516+ @ Override
517+ public void onFailure () {
518+ ffmpegLoaded = false ;
519+ Log .d (LOG_TAG , "load FFMPEG: Failed to load ffmpeg" );
520+ }
425521
426- @ Override
427- public void onFinish () {
428- Log .d (LOG_TAG , "load FFMPEG: onFinish" );
429- }
522+ @ Override
523+ public void onFinish () {
524+ Log .d (LOG_TAG , "load FFMPEG: onFinish" );
525+ }
430526 });
431527 } catch (Exception e ){
432528 ffmpegLoaded = false ;
0 commit comments