Как получить миниатюру для видео в папке my / sdcard / Android / data / mypackage / files? - PullRequest
41 голосов
/ 30 ноября 2010

Запрос к 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();

Ответы [ 11 ]

115 голосов
/ 11 марта 2011

Если вы используете Android-8 (Froyo) или выше, вы можете использовать ThumbnailUtils.createVideoThumbnail :

Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);
19 голосов
/ 14 декабря 2015

Используйте Glide , он получит миниатюру в асинхронном режиме.

 Glide.with(context)
                    .load(videoFilePath) // or URI/path
                    .into(imgView); //imageview to set thumbnail to
4 голосов
/ 20 января 2015

Вы можете просто использовать 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;
}
2 голосов
/ 12 ноября 2018

3 способа получить миниатюру из видео:

  1. Лучший способ - использовать Glide .Он будет выполнять всю работу в фоновом режиме, загружать миниатюру прямо в ImageView и даже может показывать анимацию при загрузке.Он может работать с Uri, byte [] и многими другими источниками.Как упомянул @Ajji:

    Glide.with(context)
                .load(videoFilePath) // or URI/path
                .into(imgView); //imageview to set thumbnail to
    
  2. Если вам просто нужно растровое изображение наиболее эффективным способом - используйте ThumbnailUtils.В моем случае получилось растровое изображение размером 294 912 байт (видео, снятое на камеру Nexus5X - 1280x720), и качество было таким же, как в следующем подходе.После сжатия в JPEG с 90 он сгенерирует файл JPEG размером ~ 30 КБ.

    Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);
    
  3. Последний подход заключается в использовании MediaMetadataRetriever.Но в моем случае он дал растровое изображение размером более чем в 6 раз больше, чем вы получили с ThumbnailUtils (с тем же качеством).Так что считайте это последним средством.

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

PS: не забывайте, что изображения в форматах Bitmap, byte[] и real file .jpeg могут быть легко преобразованы в любом направлении в пределах этих типов.В случае с Uri у вас часто нет реального пути к исходному файлу, но вы всегда можете получить поток байтов из него следующим образом:

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

и с этим входным потоком вы можете делать все, что захотите.

1 голос
/ 05 августа 2016

см. Ответ @Ajji:

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

Иногда возвращается черное изображение, эта проблема уже упоминалась в выпусках библиотеки Glide

Используйте этот код:

 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);
1 голос
/ 14 марта 2016

Получить миниатюру видео с 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;
    }
1 голос
/ 11 января 2016
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);

Используйте параметры для загрузки растрового изображения или уменьшения размера растрового изображения.

0 голосов
/ 29 мая 2018
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();
        }
0 голосов
/ 21 марта 2018

Попробуйте что-нибудь похожее на этот фрагмент кода:

img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
                   Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
                   MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
0 голосов
/ 01 октября 2017

Если вы создаете миниатюры напрямую, как показано ниже

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

ДОБАВИТЬ ЧИТАТЬ ВНЕШНЕЕ ХРАНЕНИЕ Разрешение в манифесте

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