MediaStore.Video.Thumbnails.getThumbnail获取本地视频缩略图

读取本地视频教程
本文介绍了一种通过CursorLoader读取本地媒体数据库的方法,并解决了录制视频后无法立即读取到最新数据的问题。文章详细说明了如何通知媒体数据库更新、如何使用CursorLoader查询媒体数据库以及如何在RecyclerView中正确展示视频缩略图。

原理:通过 CursorLoader读取本地媒体数据库

一 解决录制视频后  读取媒体 数据库时,没有最新录制数据的问题

    办法:通知媒体数据库更新:    

        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(file);
        mediaScanIntent.setData(contentUri);
        context.sendBroadcast(mediaScanIntent);

   注意:当文件夹里含有    .nomedia    文件是 自带文件管理器是读不到媒体数据的

二 利用 CursorLoader读取媒体数据库 

 private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
  private static final String ORDER_BY = MediaStore.Files.FileColumns._ID + " DESC";

    读取数据库的字段:

 // 媒体文件数据库字段
  private static final String[] PROJECTION = {
      MediaStore.Files.FileColumns._ID,
      MediaStore.MediaColumns.DATA,
      MediaStore.MediaColumns.MIME_TYPE,
      MediaStore.MediaColumns.WIDTH,
      MediaStore.MediaColumns.HEIGHT,
      DURATION};
// 只获取视频
      String video_condition =
                    getSelectionArgsForSingleMediaCondition(getDurationCondition(0, 0));
     String[] MEDIA_TYPE_VIDEO = getSelectionArgsForSingleMediaType(
                    MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
     cursorLoader = new CursorLoader(
                    activity, QUERY_URI, PROJECTION, video_condition, MEDIA_TYPE_VIDEO, ORDER_BY);


读完数据库后  拿到  cursor

  获取媒体库的id   

int media_id = data.getInt(data.getColumnIndexOrThrow(PROJECTION[0]));
  通过id  可以获取对应的视频缩略图

 Bitmap bitmap = MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(),
            media_id, MediaStore.Video.Thumbnails.MINI_KIND, null);
这是个耗时操作   ,,如果在recycle里展示   切记在viewholder里开异步加载流畅  
MediaStore.Video.Thumbnails.MINI_KIND      清晰度高于  
MediaStore.Video.Thumbnails.MICRO_KIND



三recycler里展示本地视频时,,通过读取媒体库缩略图展示

   解决滑动的时候viewholder复用  滑动出去一异步还加载的问题:

  重写  view回收方法   获取回收的viewHolder  回收时 停止异步任务

 @Override
  public void onViewRecycled(RecyclerView.ViewHolder holder) {
    super.onViewRecycled(holder);
    ViewHolder contentHolder = (ViewHolder) holder;
    ImageAsyncTask asyncTask = (ImageAsyncTask) contentHolder.contentView.getTag();
    if (null != asyncTask) {
      asyncTask.cancel(true);
    }
  }

源码


  





package com.weishitech.privateplayer.utils; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.media.MediaMetadataRetriever; import android.os.AsyncTask; import android.provider.MediaStore; import com.weishitech.privateplayer.bean.EntityVideo; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class VideoLoader { private Context context; private VideoLoadCallback callback; private ProgressUpdateCallback progressCallback; private static final int TOTAL_PROGRESS = 100; // 总进度为100% public VideoLoader(Context context, VideoLoadCallback callback, ProgressUpdateCallback progressCallback) { this.context = context; this.callback = callback; this.progressCallback = progressCallback; } public void loadVideos() { new VideoLoadTask().execute(); } private class VideoLoadTask extends AsyncTask<Void, Integer, List<EntityVideo>> { @Override protected List<EntityVideo> doInBackground(Void... voids) { List<EntityVideo> videoList = new ArrayList<>(); String[] thumbColumns = new String[]{ MediaStore.Video.Thumbnails.DATA, MediaStore.Video.Thumbnails.VIDEO_ID }; String[] projection = { MediaStore.Video.Media._ID, MediaStore.Video.Media.DISPLAY_NAME, MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATA, MediaStore.Video.Media.DURATION, MediaStore.Video.Media.DATE_TAKEN }; String sortOrder = MediaStore.Video.Media.DATE_TAKEN + " DESC"; // 按创建时间降序排列 Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, sortOrder); if (cursor != null) { int totalCount = cursor.getCount(); int currentCount = 0; while (cursor.moveToNext()) { long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)); String displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); String data = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); long duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); long time = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_TAKEN)); EntityVideo video = new EntityVideo(); video.setThumbnails(getVideoThumbnail(data)); video.setData(data); video.setName(displayName); video.setDuration(duration == 0 ? LocalData.getVideoDuration(data) : millisecondsToString(duration)); video.setSize(size == 0 ? LocalData.getVideoSize(data) : (size / 1024 / 1024 + "MB")); video.setCreatTime(time == 0 ? TimeUtil.getCurrentTime() : TimeUtil.formatTime(time)); videoList.add(video); currentCount++; int progress = (int) ((currentCount / (float) totalCount) * 100); publishProgress(progress); } cursor.close(); } return videoList; } @Override protected void onProgressUpdate(Integer... values) { if (progressCallback != null) { progressCallback.onProgressUpdate(values[0]); } int progress = values[0]; // 显示实时百分比进度 System.out.println("Loading progress: " + progress + "%"); } @Override protected void onPostExecute(List<EntityVideo> videoList) { if (callback != null) { callback.onVideoLoaded(videoList); } } } public interface VideoLoadCallback { void onVideoLoaded(List<EntityVideo> videoList); } public interface ProgressUpdateCallback { void onProgressUpdate(int progress); } // 获取视频缩略图 public static Bitmap getVideoThumbnail(String filePath) { Bitmap b=null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(filePath); b=retriever.getFrameAtTime(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); } finally { try { retriever.release(); } catch (RuntimeException e) { e.printStackTrace(); } catch (IOException e) { throw new RuntimeException(e); } } return b; } // 将毫秒转换为格式化的时间字符串(00:00) private static String millisecondsToString(long milliseconds) { long seconds = (milliseconds / 1000) % 60; long minutes = (milliseconds / (1000 * 60)) % 60; return String.format("%02d:%02d", minutes, seconds); } } 如上代码,加载大量的文件有什么地放还需要优化,怎么优化请在该代码中表示出来
最新发布
10-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值