3

I've been trying to figure out how to convert a video file to a gif in android. I found a class online, the AnimatedGifEncoder class (https://github.com/nbadal/android-gif-encoder/blob/master/GifEncoder.java). But it doesn't really seem to work. I wrapped the video to gif conversion process in an AsnycTask. The code is shown below:

@Override
protected String doInBackground(File[] files) {
    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
    try {
        mmr.setDataSource(files[0].getPath());
    } catch (Exception e){
        Log.i("VMPF", e.toString());
    }
    //int framesRate = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE));
    int duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
    Log.i("gifduration","" + duration);
    //Log.i("giffps","" + framesRate);
    int millisPerframe = 1000/24;
    int timeAt = 0;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    AnimatedGifEncoder encoder = new AnimatedGifEncoder();
    encoder.setDelay(0);
    encoder.setRepeat(100);
    encoder.start(bos);
    while (timeAt < duration){
        encoder.addFrame(mmr.getFrameAtTime(timeAt));
        timeAt += millisPerframe;
        Log.i("wenfhluwhru", timeAt+"");
    }
    encoder.finish();
    Log.i("wenfhluwhru", "loop finished");
    FileOutputStream outStream = null;
    try {
        outStream = new FileOutputStream(path);
        outStream.write(bos.toByteArray());
        outStream.close();
        Log.i("wenfhluwhru", "outstream closed");
        return path;
    } catch(Exception e) {
        e.printStackTrace();
    }
    return null;
}

Is there something wrong with my code (I assume they're nothing wrong with the AnimatedGifEncoder class)? Also I thought about converting a file to a byte[] and just submitting the byte[] into the GifImageView via Glide but I'm willing to guess that the byte[] for a video is different from that of a gif file (if I'm wrong, please let me know)?

  • actually you need to pass list of images file .. i think you are passing a video file – Adeel Turk Jun 27 '18 at 16:28
  • https://stackoverflow.com/questions/16748074/how-to-convert-video-to-gif-in-android-programmatically/16749143 – Adeel Turk Jun 27 '18 at 16:29
  • http://android-er.blogspot.com/2014/12/create-animated-gif-from-mp4.html – Adeel Turk Jun 27 '18 at 16:31
  • `encoder.addFrame(mmr.getFrameAtTime(timeAt));` adds a bitmap to the encoder @AdeelTurk – Joel Robinson-Johnson Jun 27 '18 at 16:32
  • replacing the file path with a file object and returning the absolute path didn't help, sadly, @AdeelTurk, From what I saw, that was the only difference between my code and the code linked in one of your comments – Joel Robinson-Johnson Jun 27 '18 at 17:04
  • sorry my bad .. so what are the results of above code – Adeel Turk Jun 27 '18 at 17:07
  • The string return from the `doInBackground` method is used as a parameter in a method that is called in `onPostExecute`. the method creates an intent for a new activity where the gif is supposed to start playing automatically. I know the view that plays the gif works because you can also submit a gif file directly (which I've done). Instead of a gif, I see a still image. – Joel Robinson-Johnson Jun 27 '18 at 17:15

2 Answers2

2

You can find frames at different times and create a animation drawable out of it

public void getGIF(){
    int counter = 0;
    Bitmap b = mmRetriever.getFrameAtTime(counter);
    while(counter < duration && b != null){
        frame = new BitmapDrawable(getResources(), b);
        animationDrawable.addFrame(frame, 50);
        counter += incrementor;
        b = mmRetriever.getFrameAtTime(counter);
    }
}
1

you can use FFMPEG like this to convert video file to gif:

In your app's build.gradle add

implementation 'nl.bravobit:android-ffmpeg:1.1.7'

then

        var name="sample"
        var inFIle = Environment
                .getExternalStoragePublicDirectory(Environment
                        .DIRECTORY_DOWNLOADS).toString() + "/${name}.mp4"

        var gifFIle = Environment
                .getExternalStoragePublicDirectory(Environment
                        .DIRECTORY_DOWNLOADS).toString() + "/${name}gif.gif"
        val cmd = arrayOf("-i", inFile, gifFIle)

        val ffmpeg = FFmpeg.getInstance(baseContext)



        if (ffmpeg.getInstance(baseContext).isSupported){



         ffmpeg.execute(cmd, object : ExecuteBinaryResponseHandler() {
            override fun onStart() {

            }

            override fun onProgress(message: String) {


            }

            override fun onFailure(message: String) {

            }

            override fun onSuccess(message: String) {

            }

            override fun onFinish() {


            }
        })
}
Meysam Hadigheh
  • 323
  • 3
  • 10