5

I am trying to make a module for react-native that will change a video into a gif. I have little to no experience with android studios/java, but I would love to learn more! I am using this library to convert the video to a gif. Here is my code:

package com.reactlibrary;

import android.widget.Toast;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;

public class RNGifMakerModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;

  public RNGifMakerModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }

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

  @ReactMethod
  public void alert(String message) {
      Toast.makeText(getReactApplicationContext(), "Error", Toast.LENGTH_LONG).show();
      String[] cmd = {"-i"
              , message
              , "Image.gif"};
      conversion(cmd);
  }

  public void conversion(String[] cmd) {

    FFmpeg ffmpeg = FFmpeg.getInstance(this.reactContext);

    try {


      // to execute "ffmpeg -version" command you just need to pass "-version"
      ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

        @Override
        public void onStart() {
        }

        @Override
        public void onProgress(String message) {
        }

        @Override
        public void onFailure(String message) {
        }

        @Override
        public void onSuccess(String message) {
        }

        @Override
        public void onFinish() {
        }
      });
    } catch (FFmpegCommandAlreadyRunningException e) {
      // Handle if FFmpeg is already running
      e.printStackTrace();
    }
  }
}

And I get this error:

Error:(43, 31) error: cannot find symbol class ExecuteBinaryResponseHandler

This seems odd to be, because in the documentation for ffmpeg-android-java it says to use almost exactly the same code.

Bounty

The bounty will be awarded to you if you can find a way to convert a video.mp4 into a gif. You do not necessarily have to use FFmpeg, but your solution has to work with java/android studios.

Vishal Yadav
  • 3,642
  • 3
  • 25
  • 42
zoecarver
  • 5,523
  • 2
  • 26
  • 56
  • Have you imported that `ExecuteBinaryResponseHandler`? – Bob Aug 07 '17 at 15:52
  • Well... No, I thought that would be included in ...libffmpeg.FFmpeg – zoecarver Aug 07 '17 at 15:53
  • Can you post your entire class and the entire error message? – Bob Aug 07 '17 at 15:55
  • Sure thing. I'll do it in about an hour when I get to work. – zoecarver Aug 07 '17 at 15:56
  • I guess you should import that class separately. `import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler` – Bob Aug 07 '17 at 15:59
  • And make sure you have this line in build.gradle: `compile 'com.writingminds:FFmpegAndroid:0.3.2'` – Bob Aug 07 '17 at 15:59
  • I have included that line in build.gradle. When I tried to add `import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHan‌​dler` it did not recognize it. I have updated my question with **all** of my code. (side note: I figured out thanks to the tutorial you showed me in my previous question that I was supposed to use `this.reactContext` as my context). thanks again for all the help! – zoecarver Aug 07 '17 at 16:53

2 Answers2

3

First of all you should init ffmpeg correctly.

FFmpeg ffmpeg = FFmpeg.getInstance(this.reactContext);

// please add following method after

ffmpeg.loadBinary(new FFmpegLoadBinaryResponseHandler() {
            @Override
            public void onFailure() {
                // probably your device not supported
            }

            @Override
            public void onSuccess() {
                // you should init flag here (isLoaded, isReady etc.)
            }

Only after onSuccess() you can work with commands.

Then please check following answer by LordNeckbeard.

So your code should be something like this:

if (isFFmpegLoaded) {
    // ffmpeg.execute(commands from link from the answer) 
}

Please do not forget to remove all spaces from command's string and "ffmpeg" word. To keep command more readable I will recommend to build command like this:

final String[] command = new String[11]; // example of the first command in the answer
        command[0] = "-y";
        command[1] = "-ss";
        command[2] = "30";
        command[3] = "-t";
        command[4] = "3";
        command[5] = "-i";
        command[6] = "-t";
        command[7] = "filePath";
        command[8] = "-vf"; 
        command[9] = "fps=10,scale=320:-1:flags=lanczos,palettegen";
        command[10] = "palette.png"; 

Please make sure that you have storage permission to work with file just in case you are working on external storage.

Based on this strategy ffmpeg works well for me. Thanks and good luck!

Johnny Cosmic
  • 516
  • 5
  • 8
  • 1
    Thank you so much for this answer! However I am getting this error when I try the code you provided: `Error:(48, 27) error: cannot find symbol class FFmpegLoadBinaryResponseHandler` – zoecarver Aug 13 '17 at 18:24
1

First of all, you should use: File - Invalidate Caches/Restart - Invalidate and Restart and try to reimport ExecuteBinaryResponseHan‌dler. If the problem hasn't been resolved you can try the small hack. Inside your project create package com.github.hiteshsondhi88.libffmpeg and class:

public class ExecuteBinaryResponseHandler implements FFmpegExecuteResponseHandler {

    @Override
    public void onSuccess(String message) {

    }

    @Override
    public void onProgress(String message) {

    }

    @Override
    public void onFailure(String message) {

    }

    @Override
    public void onStart() {

    }

    @Override
    public void onFinish() {

    }
}

It should be as on image:

enter image description here

Then inside your build.gradle file in defaultConfig block add multiDexEnabled true

enter image description here

Then you will be able to use that class

Onregs
  • 420
  • 3
  • 16
  • Thank you for your answer! I did the first part, but before I have done the second part, I realized that I do not think I imported it properly (Actually I did not import anything). What should I do to import the library? – zoecarver Aug 14 '17 at 18:20
  • Could you give me a github link to a working version of your project? – zoecarver Aug 14 '17 at 19:39
  • I am looking at the repository now. Thank you so much for making it! I am getting this error " `Error:(1, 0) Minimum supported Gradle version is 3.3. Current version is 2.14.1. If using the gradle wrapper, try editing the distributionUrl in /Users/zoe/Developer/tmp/FFmpegSample/gradle/wrapper/gradle-wrapper.properties to gradle-3.3-all.zip Open File` any ideas, if not thats fine. Thank you again! – zoecarver Aug 15 '17 at 17:31
  • Try to use Gradle wrapper. File - Settings - Build, Execution, Dep.. - Gradle and select 'use default gradle wrapper (recommended)'. Also, disable instant run: File - Settings - Build, Execution, Dep.. - Instant Run and unmark 'Enable instant run to hot swap...' – Onregs Aug 16 '17 at 08:26
  • I did that and it sort of worked, but I got this error (below link). I would really like to award you the bounty because of all the help you gave me. let me know what you think of this error when I build my app: https://imgur.com/a/0NL0C thanks again for the help. project screenshot: https://imgur.com/a/2TN3x – zoecarver Aug 16 '17 at 18:13
  • The first part of the error is telling about a version of Android Studio, you should use the latest stable (it's 2.3.3 [Android Studio 2.3.3](https://developer.android.com/studio/index.html#downloads)) or latest beta (it's 3.0 [Android Studio 3.0](https://developer.android.com/studio/preview/index.html)) I suggest you use the latest stable. The second part is telling about "Instant run", how to disable it I wrote above (in the second part). I think the problem is in the version. – Onregs Aug 17 '17 at 08:33
  • I for some reason could not get the sources you provided to work again... I asked another question on them. Feel free to answer or not answer it, I just thought that I would let you know. Thanks again for the help! https://stackoverflow.com/questions/46019490/cannot-link-executable-ffmpeg-android – zoecarver Sep 03 '17 at 01:25