如何在我的/ sdcard / Android / data / mypackage / files文件夹中获取视频缩略图?

时间:2010-11-30 19:28:58

标签: android video thumbnails

MediaStore.Video.Media.EXTERNAL_CONTENT_URI的查询仅返回/sdcard/DCIM/100MEDIA

中的视频

但我希望在我的/sdcard/Android/data/mypackage/files文件夹中获取视频缩略图。有可能吗?

以下是我的代码的一部分:

        ContentResolver cr = getContentResolver();
    String[] proj = {
                    BaseColumns._ID
    };

    Cursor c = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
    if (c.moveToFirst()) {
        do
        {
            int id = c.getInt(0);
            Bitmap b = MediaStore.Video.Thumbnails.getThumbnail(cr, id, MediaStore.Video.Thumbnails.MINI_KIND, null);
            Log.d("*****My Thumbnail*****", "onCreate bitmap " + b);
            ImageView iv = (ImageView) findViewById(R.id.img_thumbnail);
            iv.setImageBitmap(b);
        }
        while( c.moveToNext() );
    }         
    c.close();

12 个答案:

答案 0 :(得分:114)

如果您使用的是android-8(Froyo)或以上版本,则可以使用ThumbnailUtils.createVideoThumbnail

Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);

答案 1 :(得分:19)

使用Glide它将在异步中获取缩略图。

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

答案 2 :(得分:4)

您可以使用FFmpegMediaMetadataRetriever并忘记反思:

/**
 *
 * @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;
}

答案 3 :(得分:2)

从视频获取缩略图的3种方法:

  1. 最好的方法是使用Glide。它将在后台完成所有工作,将缩略图直接加载到ImageView中,甚至可以在加载时显示动画。它可以与Uri,byte []和许多其他源一起使用。 正如@Ajji提到的:

    Glide.with(context)
                .load(videoFilePath) // or URI/path
                .into(imgView); //imageview to set thumbnail to
    
  2. 如果仅以最有效的方式需要位图,请使用ThumbnailUtils。 就我而言,它产生的位图大小为294912字节(使用Nexus5X相机拍摄的视频-1280x720),其质量与下一种方法相同。用90压缩为JPEG后,它将生成一个约30Kb的jpeg文件。

    Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);
    
  3. 最后一种方法是使用MediaMetadataRetriever。但是在我的情况下,它生成的位图的大小是ThumbnailUtils的6倍(质量相同)。因此,将其视为最后的选择。

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

P.S .:请不要忘记,Bitmapbyte[]real file .jpeg格式的图像可以在这些类型的任何方向上轻松转换。如果是Uri,则通常没有到源文件的真实路径,但是您始终可以从中获取字节流,如下所示:

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

并且使用此输入流,您可以做任何您想做的事。

答案 4 :(得分:1)

BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

Bitmap bitmapThumb = MediaStore.Video.Thumbnails.getThumbnail(mActivity.getContentResolver(),
     Long.parseLong(video_id), 
     Images.Thumbnails.MINI_KIND, 
     options);

使用选项加载减少位图大小的位图..

答案 5 :(得分:1)

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;
    }

答案 6 :(得分:1)

请参阅@Ajji的回答:

cannot fine module 'moment'

它有时会返回黑色图像,这个问题已在Glide图书馆的问题中提及

使用此代码:

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

答案 7 :(得分:0)

这是马修威利斯的一个类似的答案,但增加了反思。为什么?因为科学。

/**
 *
 * @param path
 *            the path to the Video
 * @return a thumbnail of the video or null if retrieving the thumbnail failed.
 */
public static Bitmap getVidioThumbnail(String path) {
    Bitmap bitmap = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
        bitmap = ThumbnailUtils.createVideoThumbnail(path, Thumbnails.MICRO_KIND);
        if (bitmap != null) {
            return bitmap;
        }
    }
    // MediaMetadataRetriever is available on API Level 8 but is hidden until API Level 10
    Class<?> clazz = null;
    Object instance = null;
    try {
        clazz = Class.forName("android.media.MediaMetadataRetriever");
        instance = clazz.newInstance();
        final Method method = clazz.getMethod("setDataSource", String.class);
        method.invoke(instance, path);
        // The method name changes between API Level 9 and 10.
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD) {
            bitmap = (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
        } else {
            final byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
            if (data != null) {
                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }
            if (bitmap == null) {
                bitmap = (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
            }
        }
    } catch (Exception e) {
        bitmap = null;
    } finally {
        try {
            if (instance != null) {
                clazz.getMethod("release").invoke(instance);
            }
        } catch (final Exception ignored) {
        }
    }
    return bitmap;
}

答案 8 :(得分:0)

如果您直接创建缩略图,如下所示

Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);
  

如果您正在为大型视频集(针对大量视频)创建缩略图,则此方法存在问题。应用程序将冻结,直到所有缩略图都被加载,因为所有进程都在主线程中执行。


使用SuziLoader

此加载程序将加载视频的缩略图,这些视频本地存储在后台文件系统中。

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
  

要获得此依赖关系,请使用以下步骤

第1步。将JitPack存储库添加到构建文件中 将其添加到存储库末尾的根build.gradle中:

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

第2步。添加依赖项

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

添加READ外部存储清单

中的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

答案 9 :(得分:0)

尝试类似于此代码段的内容:

img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
                   Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
                   MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));

答案 10 :(得分:0)

Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String[] projection = { MediaStore.Video.VideoColumns.DATA };
        Cursor c = getContentResolver().query(uri, projection, null, null, null);
        int vidsCount = 0;
        if (c != null) {
            vidsCount = c.getCount();
            while (c.moveToNext()) {
                String path = c.getString(0);
                Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
                        MediaStore.Images.Thumbnails.MINI_KIND);
            }
            c.close();
        }

答案 11 :(得分:0)

您可以将此方法与任何Uri一起使用:

public static Bitmap getVideoFrame(Uri uri, Context context) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource(context, uri);
    return retriever.getFrameAtTime();
}