How to get thumbnail for video in my /sdcard/Android/data/mypackage/files folder?

后端 未结 12 1706
情深已故
情深已故 2020-11-30 22:21

Query to MediaStore.Video.Media.EXTERNAL_CONTENT_URI returns only video in /sdcard/DCIM/100MEDIA

But I want to get thumbnails for video in

相关标签:
12条回答
  • 2020-11-30 22:49

    You can use this method with any Uri:

    public static Bitmap getVideoFrame(Uri uri, Context context) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        retriever.setDataSource(context, uri);
        return retriever.getFrameAtTime();
    }
    
    0 讨论(0)
  • 2020-11-30 22:50

    You can just use FFmpegMediaMetadataRetriever and forget the reflection:

    /**
     *
     * @param path
     *            the path to the Video
     * @return a thumbnail of the video or null if retrieving the thumbnail failed.
     */
    public static Bitmap getVideoThumbnail(String path) {
        Bitmap bitmap = null;
    
        FFmpegMediaMetadataRetriever fmmr = new FFmpegMediaMetadataRetriever();  
    
        try {
            fmmr.setDataSource(path);            
    
            final byte[] data = fmmr.getEmbeddedPicture();
    
            if (data != null) {
                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }
    
            if (bitmap == null) {
                bitmap = fmmr.getFrameAtTime();   
            }
        } catch (Exception e) {
            bitmap = null;
        } finally {
            fmmr.release();
        }
        return bitmap;
    }
    
    0 讨论(0)
  • 2020-11-30 22:50

    see @Ajji 's answer :

     Glide.with(context)
                        .load(videoFilePath) // or URI/path
                        .into(imgView); //imageview to set thumbnail to
    

    It sometimes returns black image, this issue is already mentioned in Glide library's issues

    Use this code:

     BitmapPool bitmapPool = Glide.get(activity).getBitmapPool();
                    int microSecond = 6000000;// 6th second as an example
                    VideoBitmapDecoder videoBitmapDecoder = new VideoBitmapDecoder(microSecond);
                    FileDescriptorBitmapDecoder fileDescriptorBitmapDecoder = new FileDescriptorBitmapDecoder(videoBitmapDecoder, bitmapPool, DecodeFormat.PREFER_ARGB_8888);
                    Glide.with(activity)
                            .load(videoPath)
                            .asBitmap()
                            .override(50,50)// Example
                            .videoDecoder(fileDescriptorBitmapDecoder)
                            .into(holder.ivFirstUpload);
    
    0 讨论(0)
  • 2020-11-30 22:54

    3 ways to get a thumbnail from a video:

    1. The best way is to use Glide. It will do all the work in the background, load the thumbnail right into the ImageView and even can show animation when loading. It can work with Uri, byte[] and many other sources. As @Ajji mentioned:

      Glide.with(context)
                  .load(videoFilePath) // or URI/path
                  .into(imgView); //imageview to set thumbnail to
      
    2. If you just need a bitmap in the most efficient way - use ThumbnailUtils. In my case, it produced a bitmap with a size of 294 912 bytes (video taken with a camera of Nexus5X - 1280x720) and the quality was the same as in the next approach. After you compress into JPEG with 90 it will generate a jpeg file of ~30Kb.

      Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
      MediaStore.Images.Thumbnails.MINI_KIND);
      
    3. The last approach is to use MediaMetadataRetriever. But in my case, it produced a bitmap with size more than 6 times bigger than you got with ThumbnailUtils (with the same quality). So consider it as a last resort.

      MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
                          mMMR.setDataSource(mContext, mAttachment.getUri());
                          bmp = mMMR.getFrameAtTime();
      

    P.S.: Don't forget that images in Bitmap, byte[] and real file .jpeg formats can be easily converted in any direction within these types. In case of Uri's you often don't have real path to the source file but you can always get the byte stream from it like this:

        InputStream in =  mContext.getContentResolver().openInputStream(uri);
    

    and with this input stream you can do whatever you want.

    0 讨论(0)
  • 2020-11-30 23:01

    Try something similar to this code snippet:

    img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
                       Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
                       MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
    
    0 讨论(0)
  • 2020-11-30 23:07

    Get video thumbnail from VIDEO_ID:

    public static Drawable getVideoThumbnail(Context context, int videoID) {
            try {
                String[] projection = {
                        MediaStore.Video.Thumbnails.DATA,
                };
                ContentResolver cr = context.getContentResolver();
                Cursor cursor = cr.query(
                        MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
                        projection, 
                        MediaStore.Video.Thumbnails.VIDEO_ID + "=?", 
                        new String[] { String.valueOf(videoID) }, 
                        null);
                cursor.moveToFirst();
                return Drawable.createFromPath(cursor.getString(0));
            } catch (Exception e) {
            }
            return null;
        }
    
    0 讨论(0)
提交回复
热议问题