如何从视频路径中显示视频缩略图?

时间:2018-04-28 06:11:41

标签: android file imageview android-bitmap video-thumbnails

我想在存储的视频路径中显示ImageView中的视频缩略图。是否有一个函数采用视频路径并返回缩略图的位图?我通过以下代码获得视频路径:

public ArrayList<String> getAllMedia() {
  HashSet<String> videoItemHashSet = new HashSet<>();
  String[] projection = {MediaStore.Video.VideoColumns.DATA, MediaStore.Video.Media.DISPLAY_NAME};
  Cursor cursor = getContext().getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
  try {
    cursor.moveToFirst();
    do {
      videoItemHashSet.add((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))));
    } while(cursor.moveToNext());
    cursor.close();
  } catch(Exception e) {
    e.printStackTrace();
  }
  ArrayList<String> downloadedList = new ArrayList<>(videoItemHashSet);
  return downloadedList;
}

6 个答案:

答案 0 :(得分:3)

这是创建缩略图的默认方式。

适用于迷你种类

Bitmap thumb;
//MINI_KIND, size:  512 x 384 thumbnail 
    thumb = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MINI_KIND);
            img_tumbnail.setImageBitmap(thumb);

对于Micro Kind

Bitmap thumb;
//MICRO_KIND, size: 96 x 96 thumbnail
thumb= ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MICRO_KIND);
img_tumbnail.setImageBitmap(thumb);

此外,您可以使用Glide for Url以及设备的视频路径。

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

另外,您可以使用.override(50,50) ftype来调整缩略图的大小。

答案 1 :(得分:1)

使用Glide lib

显示本地存储空间的缩略图

id="collapseInnerTwo"

答案 2 :(得分:1)

我有第3种方法来设置图像/视频的缩略图。 希望对您有帮助。

1)ThumbnailUtils->有效但很慢

Bitmap thumb = ThumbnailUtils.createVideoThumbnail(thumbPath, MediaStore.Video.Thumbnails.MINI_KIND);
        holder.ivThumb.setImageBitmap(thumb);

2)FFmpegMediaMetadataRetriever->非常有效但是很慢

FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
    try {
        retriever.setDataSource(thumbPath);
       thumb.setImageBitmap(retriever.getFrameAtTime(0));
    } catch (Exception ex) {
        // Assume this is a corrupt  file
    }

3)Glide->快速有效

   RequestOptions options = new RequestOptions()
            .centerCrop()
            .placeholder(android.R.drawable.stat_notify_error)
            .error(android.R.drawable.stat_notify_error);

    Glide.with(context)
            .load(thumPath)
            .apply(options)
            .into(thumb);

答案 3 :(得分:0)

您可以使用ThumbnailUtils来加载3种格式的视频缩略图:

  • MINI_KIND:适用于媒体详细信息视图
  • FULL_SCREEN_KIND:适合标题
  • MICRO_KIND:非常适合回收视图
holder.videoThumb.setImageBitmap(
                   ThumbnailUtils.createVideoThumbnail(getItem(position)
                            .videoURL,
                            MediaStore.Images.Thumbnails.MICRO_KIND))

最大的缺点是 ThumbnailUtils在UI线程上运行,因此,如果您尝试在recycleView中使用此方法,那么该方法将使您的应用跳过帧。您的RecycleView滚动会很慢,并且如果您有7个以上的项目,则您的应用将开始抛出ANR

这意味着您需要创建AsyncTask或线程,这又可能导致内存泄漏。

结论;滑行可以更好地加载视频缩略图。

DiskCacheStrategy.RESULT是对我有用的重要参数,可以在回收视图中实现平稳快速的滚动。

            Glide.with(context).load(getItem(position).videoURL)
                    .asBitmap()
                    .placeholder(R.drawable.app_icon)
                    .centerCrop()
                    .diskCacheStrategy(DiskCacheStrategy.RESULT)
                    .into(holder.videoThumb)

答案 4 :(得分:0)

在某些没有 FileDescriptorBitmapDecoder

的设备不适合我的情况下

所以我在FileDescriptorBitmapDecoder中使用了以下代码

 public static void loadLocalVideoThumbanail(Context context, String path, final ImageView imageView) {
    try {
        if (path == null || path.isEmpty())
            return;

        BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
        int microSecond = 1000000;// 1st second as an example
        VideoBitmapDecoder videoBitmapDecoder = new VideoBitmapDecoder(microSecond);
        FileDescriptorBitmapDecoder fileDescriptorBitmapDecoder = new FileDescriptorBitmapDecoder(videoBitmapDecoder, bitmapPool, DecodeFormat.PREFER_ARGB_8888);


        Glide.with(context).load(path).asBitmap().thumbnail(0.6f)
                .diskCacheStrategy(DiskCacheStrategy.RESULT)
                .dontAnimate()
                .videoDecoder(fileDescriptorBitmapDecoder)
                .override(200,200)
                .into(imageView);
    } catch (Exception e) {
        MyLog.e(TAG, "LoadImage: ", e);
    }
}

答案 5 :(得分:0)

如果有人正在寻找 Kotlin 版本。你可以试试这个扩展功能。 它正在使用 coil

/**
 * https://github.com/coil-kt/coil/issues/413
 */
fun ImageView.setThumbnail(uri: Uri, frameMillis: Long = 2000) {

    val imageLoader = ImageLoader.Builder(context)
        .componentRegistry {
            add(VideoFrameFileFetcher(context))
            add(VideoFrameUriFetcher(context))
        }.build()

    val request = ImageRequest.Builder(context)
        .data(uri)
        .videoFrameMillis(frameMillis)
        .target(this)
        .fetcher(VideoFrameUriFetcher(context))
        .build()

    findViewTreeLifecycleOwner()?.lifecycleScope?.launch(Dispatchers.Main) {
        imageLoader.execute(request)
    }
}