web-dev-qa-db-fra.com

Comment obtenir une miniature pour la vidéo dans mon dossier/sdcard/Android/data/mypackage/files?

Une requête sur MediaStore.Video.Media.EXTERNAL_CONTENT_URI renvoie uniquement la vidéo dans /sdcard/DCIM/100MEDIA

Mais je veux obtenir des vignettes pour la vidéo dans mon dossier /sdcard/Android/data/mypackage/files. C'est possible ?

Voici une partie de mon code:

        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();
41
Vladimir Berezkin

Si vous utilisez Android-8 (Froyo) ou une version ultérieure, vous pouvez utiliser ThumbnailUtils.createVideoThumbnail :

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

Utilisez Glide cela ira chercher la vignette en async. 

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

Vous pouvez simplement utiliser FFmpegMediaMetadataRetriever et oublier le reflet:

/**
 *
 * @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;
}
4
William Seemann
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);

Utilisez Options pour charger un bitmap ou diminuer sa taille.

1
Vaibhav Jain

voir la réponse de @Ajji:

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

Cela renvoie parfois une image en noir, ce problème est déjà mentionné dans les numéros de la bibliothèque Glide.

Utilisez ce 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);
1
TapanHP

(3 façons d'obtenir une vignette d'une vidéo:} _

  1. Le meilleur moyen est d'utiliser Glide . Il effectuera tout le travail en arrière-plan, chargera la vignette directement dans ImageView et pourra même afficher une animation lors du chargement. Cela peut fonctionner avec Uri, byte [] et beaucoup d'autres sources . Comme l'a mentionné @Ajji:

    Glide.with(context)
                .load(videoFilePath) // or URI/path
                .into(imgView); //imageview to set thumbnail to
    
  2. Si vous avez juste besoin d’un bitmap de la manière la plus efficace, utilisez ThumbnailUtils. Dans mon cas, il a produit un bitmap d’une taille de 294 912 octets (vidéo prise avec un appareil photo de Nexus5X - 1280x720) et la qualité était identique à l’approche suivante. Une fois compressé en JPEG avec 90, il générera un fichier jpeg de ~ 30 Ko.

    Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
    MediaStore.Images.Thumbnails.MINI_KIND);
    
  3. La dernière approche consiste à utiliser MediaMetadataRetriever. Mais dans mon cas, il produisait une image bitmap d'une taille plus de 6 fois supérieure à celle obtenue avec ThumbnailUtils (avec la même qualité). Alors considérez cela comme un dernier recours. 

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

P.S .: N'oubliez pas que les images aux formats Bitmap, byte[] et real file .jpeg peuvent être facilement converties dans n'importe quel sens au sein de ces types. Dans le cas d'Uri, vous n'avez souvent pas le vrai chemin du fichier source, mais vous pouvez toujours en obtenir le flux d'octets comme ceci:

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

et avec ce flux d'entrée, vous pouvez faire ce que vous voulez.

1
Kirill Karmazin

Obtenir la vignette vidéo de 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
trivatus

Voici une réponse similaire à Matthew Willis mais avec une réflexion supplémentaire. Pourquoi? parce que la science.

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

Essayez quelque chose de similaire à cet extrait de code:

img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
                   Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
                   MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
0
user8085762
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

Si vous créez directement des vignettes comme suit

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

Cette méthode pose également un problème si vous créez des vignettes pour un grand ensemble de vidéos (pour un grand nombre de vidéos). l'application se fige jusqu'à ce que toutes les vignettes soient chargées, car tous les processus s'exécutent dans le thread principal.


Utilisez SuziLoader

Ce chargeur chargera les vignettes des vidéos stockées localement sur votre système de fichiers en arrière-plan.

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

Pour obtenir cette dépendance, utilisez les étapes suivantes

Étape 1. Ajouter le référentiel JitPack à votre fichier de construction
Ajoutez-le dans votre racine build.gradle à la fin des référentiels:

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

Étape 2. Ajouter la dépendance

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

AJOUTER LIRE STOCKAGE EXTERNE Autorisation dans le manifeste

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE"/>
0
Sushin Pv