[Android] Load video thumbnail from Android library

Geoffrey Métais git at videolan.org
Wed Apr 4 18:35:33 CEST 2018


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Tue Mar 20 16:41:16 2018 +0100| [6897c0853d8ed7c76447a1d367e526c4b0e7fbf8] | committer: Geoffrey Métais

Load video thumbnail from Android library

> https://code.videolan.org/videolan/vlc-android/commit/6897c0853d8ed7c76447a1d367e526c4b0e7fbf8
---

 .../videolan/vlc/gui/helpers/AsyncImageLoader.java | 11 ++----
 .../org/videolan/vlc/util/ThumbnailsProvider.java  | 45 +++++++++++++---------
 2 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/helpers/AsyncImageLoader.java b/vlc-android/src/org/videolan/vlc/gui/helpers/AsyncImageLoader.java
index 27a18e3b5..14e12afc6 100644
--- a/vlc-android/src/org/videolan/vlc/gui/helpers/AsyncImageLoader.java
+++ b/vlc-android/src/org/videolan/vlc/gui/helpers/AsyncImageLoader.java
@@ -33,7 +33,6 @@ import android.net.Uri;
 import android.support.v17.leanback.widget.ImageCardView;
 import android.support.v4.util.Pools;
 import android.support.v4.view.ViewCompat;
-import android.text.TextUtils;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -44,7 +43,6 @@ import org.videolan.medialibrary.media.MediaWrapper;
 import org.videolan.vlc.BR;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
-import org.videolan.vlc.media.MediaGroup;
 import org.videolan.vlc.util.HttpImageLoader;
 import org.videolan.vlc.util.ThumbnailsProvider;
 
@@ -79,14 +77,14 @@ public class AsyncImageLoader {
 
     @BindingAdapter({"media"})
     public static void loadPicture(View v, MediaLibraryItem item) {
-        if (item == null || TextUtils.isEmpty(item.getArtworkMrl())
+        if (item == null
                 || item.getItemType() == MediaLibraryItem.TYPE_GENRE
                 || item.getItemType() == MediaLibraryItem.TYPE_PLAYLIST)
             return;
         final boolean isMedia = item.getItemType() == MediaLibraryItem.TYPE_MEDIA;
         final boolean isGroup = isMedia && ((MediaWrapper)item).getType() == MediaWrapper.TYPE_GROUP;
-        final String cacheKey = isGroup ? "group:"+item.getTitle() : item.getArtworkMrl();
-        final Bitmap bitmap = sBitmapCache.getBitmapFromMemCache(cacheKey);
+        final String cacheKey = isGroup ? "group:"+item.getTitle() : ThumbnailsProvider.getMediaCacheKey(isMedia, item);
+        final Bitmap bitmap = cacheKey != null ? sBitmapCache.getBitmapFromMemCache(cacheKey) : null;
         if (bitmap != null) {
             updateTargetImage(bitmap, v, DataBindingUtil.findBinding(v));
             return;
@@ -143,8 +141,7 @@ public class AsyncImageLoader {
         @Override
         public Bitmap getImage() {
             if (bindChanged) return null;
-            if (item instanceof MediaGroup)
-                return ThumbnailsProvider.getComposedImage((MediaGroup) item);
+            if (item.getItemType() == MediaLibraryItem.TYPE_MEDIA) return ThumbnailsProvider.getMediaThumbnail((MediaWrapper) item);
             return AudioUtil.readCoverBitmap(Uri.decode(item.getArtworkMrl()), width);
         }
 
diff --git a/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java b/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
index 74aaf37b0..c0eda4629 100644
--- a/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
+++ b/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
@@ -9,6 +9,7 @@ import android.provider.MediaStore;
 import android.support.annotation.WorkerThread;
 import android.text.TextUtils;
 
+import org.videolan.medialibrary.media.MediaLibraryItem;
 import org.videolan.medialibrary.media.MediaWrapper;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
@@ -28,6 +29,8 @@ public class ThumbnailsProvider {
 
     private static final String TAG = "VLC/ThumbnailsProvider";
 
+    private static File appDir;
+    private static String cacheDir;
     private static final int sImageWidth = VLCApplication.getAppResources().getDimensionPixelSize(VLCApplication.showTvUi() ? R.dimen.tv_grid_card_thumb_width : R.dimen.grid_card_thumb_width);
     private static final int MAX_IMAGES = 4;
 
@@ -36,28 +39,38 @@ public class ThumbnailsProvider {
         if (item.getType() == MediaWrapper.TYPE_GROUP)
             return ThumbnailsProvider.getComposedImage((MediaGroup) item);
         if (item.getType() == MediaWrapper.TYPE_VIDEO && TextUtils.isEmpty(item.getArtworkMrl()))
-            return getVideoThumbnail(item.getUri().getPath());
+            return getVideoThumbnail(item);
         else
             return AudioUtil.readCoverBitmap(Uri.decode(item.getArtworkMrl()), sImageWidth);
     }
 
+    public static String getMediaCacheKey(boolean isMedia, MediaLibraryItem item) {
+        if (isMedia && ((MediaWrapper)item).getType() == MediaWrapper.TYPE_VIDEO && TextUtils.isEmpty(item.getArtworkMrl())) {
+            if (appDir == null) appDir = VLCApplication.getAppContext().getExternalFilesDir(null);
+            final boolean hasCache = appDir != null && appDir.exists();
+            if (hasCache && cacheDir == null) cacheDir = appDir.getAbsolutePath() + THUMBS_FOLDER_NAME;
+            return hasCache ? new StringBuilder(cacheDir).append('/').append(item.getTitle()).append(".jpg").toString() : null;
+        }
+        return item.getArtworkMrl();
+    }
+
     @WorkerThread
-    private static Bitmap getVideoThumbnail(final String filePath) {
-        final File appDir = VLCApplication.getAppContext().getExternalFilesDir(null);
+    private static Bitmap getVideoThumbnail(final MediaWrapper media) {
+        final String filePath = media.getUri().getPath();
+        if (appDir == null) appDir = VLCApplication.getAppContext().getExternalFilesDir(null);
         final boolean hasCache = appDir != null && appDir.exists();
-        final String thumbPath = hasCache ? appDir.getAbsolutePath()+ THUMBS_FOLDER_NAME
-                +"/"+ FileUtils.getFileNameFromPath(filePath)+".jpg" : null;
+        final String thumbPath = getMediaCacheKey(true, media);
         final Bitmap cacheBM = hasCache ? BitmapCache.getInstance().getBitmapFromMemCache(thumbPath) : null;
-        if (cacheBM != null)
-            return cacheBM;
-        if (hasCache && new File(thumbPath).exists())
-            return readCoverBitmap(thumbPath, sImageWidth);
+        if (cacheBM != null) return cacheBM;
+        if (hasCache && new File(thumbPath).exists()) return readCoverBitmap(thumbPath, sImageWidth);
         final Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MINI_KIND);
         if (bitmap != null) {
+            BitmapCache.getInstance().addBitmapToMemCache(thumbPath, bitmap);
             if (hasCache)
                 VLCApplication.runBackground(new Runnable() {
                     @Override
                     public void run() {
+                        media.setThumbnail(thumbPath);
                         saveOnDisk(bitmap, thumbPath);
                     }
                 });
@@ -72,8 +85,7 @@ public class ThumbnailsProvider {
         Bitmap composedImage = bmc.getBitmapFromMemCache(key);
         if (composedImage == null) {
             composedImage = composeImage(group);
-            if (composedImage != null)
-                bmc.addBitmapToMemCache(key, composedImage);
+            if (composedImage != null) bmc.addBitmapToMemCache(key, composedImage);
         }
         return composedImage;
     }
@@ -86,21 +98,18 @@ public class ThumbnailsProvider {
         final Bitmap[] sourcesImages = new Bitmap[Math.min(MAX_IMAGES, group.size())];
         int count = 0, minWidth = Integer.MAX_VALUE, minHeight = Integer.MAX_VALUE;
         for (MediaWrapper media : group.getAll()) {
-            final Bitmap bm = readCoverBitmap(Uri.decode(media.getArtworkMrl()), sImageWidth);
+            final Bitmap bm = getVideoThumbnail(media);
             if (bm != null) {
                 int width = bm.getWidth();
                 int height = bm.getHeight();
                 sourcesImages[count++] = bm;
                 minWidth = Math.min(minWidth, width);
                 minHeight = Math.min(minHeight, height);
-                if (count == MAX_IMAGES)
-                    break;
+                if (count == MAX_IMAGES) break;
             }
         }
-        if (count == 0)
-            return null;
-        if (count == 1)
-            return sourcesImages[0];
+        if (count == 0) return null;
+        if (count == 1) return sourcesImages[0];
         return composeCanvas(sourcesImages, count, minWidth, minHeight);
     }
 



More information about the Android mailing list