Load Btimap of Video thumbnails from sdcard

1.2k Views Asked by At

I am developing a module in which I need to show all the video from phone in form of video thumbnails. I have taken BaseAdapter to show all video thumbnails into GridView. The only problem is that I had to write the code extract thumbnail from video file to bitmap in getView() of BaseAdapter.

 ((Activity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                 Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(
                                                videoValues.get(position).getFile()
                                               .getAbsolutePath(), Thumbnails.MINI_KIND);
                 imageThumbnail.setImageBitmap(bmThumbnail);
                 bmThumbnail = null;
    }
    });

I want to load this Asynchronously with some image loader. I have already tried Aquery, Universal Image Loader, Picasso etc but none of them gives asynchronous image loading with memory caching, file caching, failure callback mechanism etc.

Can anyone suggest how can I achieve this efficiently? TIA.

2

There are 2 best solutions below

0
On BEST ANSWER

To resolve this issue, I have made a class VideoThumbLoader. It asynchronously generated Bitmap and passes it to adapter. So that main benefit is that the whole process is being handled in background thread.

The code for class is as below:

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

public class VideoThumbLoader {

    private LruCache<String, Bitmap> lruCache;

    @SuppressLint("NewApi")
    public VideoThumbLoader() {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();// obtain maximum
                                                                // memory to run
        int maxSize = maxMemory / 4;// get cache memory size 35
        lruCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                // this will be called when the cache deposited in each
                return value.getByteCount();
            }
        };
    }

    public void addVideoThumbToCache(String path, Bitmap bitmap) {
        if (getVideoThumbToCache(path) == null && bitmap != null) {

            lruCache.put(path, bitmap);
        }
    }

    public Bitmap getVideoThumbToCache(String path) {

        return lruCache.get(path);
    }

    public void showThumbByAsynctack(String path, ImageView imgview) {

        if (getVideoThumbToCache(path) == null) {
            // asynchronous loading
            new MyBobAsynctack(imgview, path).execute(path);
        } else {
            imgview.setImageBitmap(getVideoThumbToCache(path));
        }
    }

    class MyBobAsynctack extends AsyncTask<String, Void, Bitmap> {
        private ImageView imgView;
        private String path;

        public MyBobAsynctack(ImageView imageView, String path) {
            this.imgView = imageView;
            this.path = path;
        }

        @Override
        protected Bitmap doInBackground(String... params) {

            Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(params[0],
                    MediaStore.Video.Thumbnails.MINI_KIND);

            // provide
            if (getVideoThumbToCache(params[0]) == null) {
                addVideoThumbToCache(path, bitmap);
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (imgView.getTag().equals(path)) {// through Tag can be bound
                                                // pictures address and
                                                // imageView, this address
                                                // Listview loading the image
                                                // dislocation solution
                imgView.setImageBitmap(bitmap);
            }
        }
    }
}

And from adapter side, simply call:

private VideoThumbLoader mVideoThumbLoader = new VideoThumbLoader();
 imageThumbnail.setTag(videoValues.get(position).getFile()
                    .getAbsolutePath());// binding imageview
 imageThumbnail.setImageResource(R.drawable.videothumb); //default image
 mVideoThumbLoader.showThumbByAsynctack(videoValues.get(position)
                    .getFile().getAbsolutePath(), imageThumbnail);

P.S: One important thing I had taken a note of was, due to asynchronous downloading of bitmap, there were few cases where thumbnails tend to mix up. So I have tagged the imageview with file path. This way I will have the exact thumbnail for the image.

1
On


Use SuziLoader

This loader will load the thumbnails for the videos which is locally stored on your filesystem in background.

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video.mp4";
ImageView mThumbnail = (ImageView) findViewById(R.id.thumbnail);

SuziLoader loader = new SuziLoader(); //Create it for once.
loader.with(MainActivity.this) //Context
    .load(path) //Video path
    .into(mThumbnail) // imageview to load the thumbnail
    .type("mini") // mini or micro
    .show(); // to show the thumbnail

To get this dependency use the following steps

Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
    compile 'com.github.sushinpv:SuziVideoThumbnailLoader:0.1.0'
}

ADD READ EXTERNAL STORAGE Permission in manifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>