package com.mybigday.rnmediameta;

import android.content.Context;
import android.graphics.Bitmap;
import wseemann.media.FFmpegMediaMetadataRetriever;
import android.util.Base64;
import android.graphics.Matrix;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.WritableMap;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;

public class RNMediaMeta extends ReactContextBaseJavaModule {
  private Context context;

  public RNMediaMeta(ReactApplicationContext reactContext) {
    super(reactContext);

    this.context = (Context) reactContext;
  }

  @Override
  public String getName() {
    return "RNMediaMeta";
  }

  // Related to https://github.com/wseemann/FFmpegMediaMetadataRetriever/blob/master/gradle/fmmr-library/library/src/main/java/wseemann/media/FFmpegMediaMetadataRetriever.java#L632
  private final String[] metadatas = {
    "album",
    "album_artist",
    "comment",
    "copyright",
    "creation_time",
    "disc",
    "encoder",
    "encoded_by",
    "genre",
    "language",
    "performer",
    "publisher",
    "service_name",
    "service_provider",
    "track",
    "variant_bitrate",
    "icy_metadata",
    "framerate",
    "chapter_start_time",
    "chapter_end_time",
    "artist",
    "composer",
    "title",
    "date",
    "duration",
    "rotation"
  };

  private String convertToBase64(byte[] bytes) {
    return Base64.encodeToString(bytes, Base64.NO_WRAP);
  }

  private byte[] convertToBytes(Bitmap bmp) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.PNG, 75, stream);
    return stream.toByteArray();
  }

  private void putString(WritableMap map, String key, String value) {
    if (value != null) map.putString(key, value);
  }

  private void getMetadata(String path, Promise promise) {
    File f = new File(path);
    if (!f.exists() || f.isDirectory()) {
      promise.reject("-15", "file not found");
      return;
    }

    FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
    WritableMap result = Arguments.createMap();
    try {
      mmr.setDataSource(path);

      // check is media
      String audioCodec = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_AUDIO_CODEC);
      String videoCodec = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_VIDEO_CODEC);
      if (audioCodec == null && videoCodec == null) {
        promise.resolve(result);
        mmr.release();
        return;
      }

      // get all metadata
      for (String meta: metadatas) {
        putString(result, meta, mmr.extractMetadata(meta));
      }

      // get thumb
      Bitmap bmp = mmr.getFrameAtTime();
      if (bmp != null) {
        // Bitmap bmp2 = mmr.getFrameAtTime((long) 4E6, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
        // if (bmp2 != null) bmp = bmp2;

        // the image returned seems to be always in landscape mode and does not follow
        // the rotation of the video.
        // get the rotation from the metadata and apply the correction so the image is straight.

        String rotation =  mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
        String createTime =  mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_CREATION_TIME);
        String duration =  mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);

        if( rotation != null )  {
            Bitmap rotatedBmp = RotateBitmap(bmp, Float.parseFloat(rotation));
            if(rotatedBmp != null ) {
                bmp = rotatedBmp;
            }
        }

        byte[] bytes = convertToBytes(bmp);
        result.putInt("width", bmp.getWidth());
        result.putInt("height", bmp.getHeight());
        result.putString("thumb", convertToBase64(bytes));
        result.putString("rotation", rotation);
        result.putString("createTime", createTime);
        result.putString("duration", duration);
      }
    } catch(Exception e) {
      e.printStackTrace();
    } finally {
      promise.resolve(result);
      mmr.release();
    }
  }

  private Bitmap RotateBitmap(Bitmap source, float angle)
  {
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);
      return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
  }

  @ReactMethod
  public void get(final String path, final Promise promise) {
    new Thread() {
      @Override
      public void run() {
        getMetadata(path, promise);
      }
    }.start();
  }
}
@@ -3247,19 +3247,30 @@
        /
-/ t
+*%0A         * T
 he image
@@ -3344,18 +3344,18 @@
         
-//
+ *
  the rot
@@ -3378,26 +3378,26 @@
 eo.%0A        
+ 
-//
+*
  get the rot
@@ -3471,16 +3471,27 @@
 raight.%0A
+         */
 %0A       
@@ -3504,25 +3504,24 @@
 g rotation =
- 
  mmr.extract
@@ -3615,17 +3615,16 @@
 teTime =
- 
  mmr.ext
@@ -3719,17 +3719,16 @@
 ration =
- 
  mmr.ext
@@ -3808,10 +3808,10 @@
   if
-(
  
+(
 rota
@@ -3826,16 +3826,13 @@
 null
- 
 )  %7B%0A
-  
     
@@ -3914,20 +3914,19 @@
         
-  
 if
+ 
 (rotated
@@ -3936,17 +3936,16 @@
  != null
- 
 ) %7B%0A    
@@ -3952,20 +3952,16 @@
         
- 
-   
 bmp = ro
@@ -3970,18 +3970,16 @@
 tedBmp;%0A
-  
         
@@ -4921,8 +4921,9 @@
 );%0A  %7D%0A%7D
+%0A

Make java code cleaner