【问题标题】:get thumbnail from video URL but it takes more than 5 seconds to load data on recycler view从视频 URL 获取缩略图,但在回收站视图上加载数据需要 5 秒以上
【发布时间】:2019-08-17 08:20:30
【问题描述】:
  1. 我正在使用以下代码从视频 URL 获取视频列表和缩略图 但在回收站视图上加载数据需要 5 秒以上。

    public class VideoAsync extends AsyncTask {
    
        private static final String TAG = "VideoAsync";
        private VideoAdapter videoAdapter;
        private RecyclerView recyclerView;
        private List<Video> videoList;
        private Context context;
    
        public VideoAsync(RecyclerView recyclerView, Context context) {
            this.recyclerView = recyclerView;
            this.videoList = new ArrayList<>();
            this.context = context;
        }
    
        @Override
        protected Object doInBackground(Object[] objects) {
    
            return getAllMedia();
        }
    
        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            videoAdapter = new VideoAdapter(getAllMedia(), context);
            recyclerView.setAdapter(videoAdapter);
            videoAdapter.notifyDataSetChanged();
        }
    
        private List<Video>  getAllMedia() {
            HashSet<Video> videoItemHashSet = new HashSet<>();
            String[] projection = { MediaStore.Video.VideoColumns.DATA ,MediaStore.Video.Media.TITLE,
    

    MediaStore.Video.VideoColumns.DURATION}; 光标 cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 投影 ,空,空,空); 尝试 { cursor.moveToFirst();

                do{
                    Video video = new Video();
    
                    video.setVideoPath((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))));
                    video.setVideoTitle((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE))));
                    video.setVideoDuration(duration(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION))));
                    video.setThumbnail(getThumbNail((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)))));
                    videoItemHashSet.add(video);
    
                }while(cursor.moveToNext());
    
                cursor.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            videoList.addAll(videoItemHashSet);
            Log.d(TAG, "getAllMedia: "+ videoList.size()) ;
            return videoList;
        }
    
        private static Bitmap getThumbNail(String imagePath){
            return ThumbnailUtils.createVideoThumbnail(imagePath, MediaStore.Video.Thumbnails.MINI_KIND);
        }
    
        private static String duration(String time){
            long duration = Long.parseLong(time);
            return  String.format("%d:%d",
                    TimeUnit.MILLISECONDS.toMinutes(duration),
                    TimeUnit.MILLISECONDS.toSeconds(duration) -
                            TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration))
            );
        }
    }
    
    
    //Video fragment
    

    这里,Adapter 设置在 Videoasync 类中。 公共类 VideosFragment 扩展 Fragment {

        @BindView(R.id.rv_video) RecyclerView recyclerView;
    
        private VideoAsync videoAsync;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_videos, container, false);
            ButterKnife.bind(this, view);
            setRecyclerView();
    
            return  view;
        }
    
        private void setRecyclerView(){
            recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
            videoAsync = new VideoAsync(recyclerView, getContext());
            videoAsync.execute();
        }
    }
    

【问题讨论】:

  • 检查缩略图的大小。
  • 私有静态位图 getThumbNail(String imagePath){ return ThumbnailUtils.createVideoThumbnail(imagePath, MediaStore.Video.Thumbnails.MINI_KIND); }//这个方法需要时间从url制作缩略图
  • 如果尺寸很大,加载会需要时间。

标签: android


【解决方案1】:

这一行可能会减慢加载过程。最坏的情况是可能会抛出OOM Exception

ThumbnailUtils.createVideoThumbnail(imagePath, MediaStore.Video.Thumbnails.MINI_KIND);

截至

video.setThumbnail(getThumbNail((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)))));

除非有严格的内存管理,否则始终建议仅在需要时加载位图。 为了节省时间,我会让位图加载到 Glide 或任何其他类似的库中。 也就是说,改为:

do{
            Video video = new Video();

            video.setVideoPath((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))));
            video.setVideoTitle((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE))));
            video.setVideoDuration(duration(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION))));
            //video.setThumbnail(getThumbNail((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)))));
            videoItemHashSet.add(video);

        }while(cursor.moveToNext());

在recyclerView的adapter的onBindViewHolder里面,用Glide动态加载视频位图 例如:

 @Override
    public void onBindViewHolder(YourAdapter.ItemViewHolder holder, int position) {
        Video v = videoItemHashset.get(position);

        Glide.with(your_context)
                .asBitmap()
                .load(Uri.fromFile(new File(v.getVideoPath())))
                .centerCrop()
                .into(holder.videoThumbnailImageView);

        holder.mPosition = position;///in case you're going to need it for playing the video at that position
    }

【讨论】:

    【解决方案2】:
    public static Bitmap retriveVideoFrameFromVideo(String videoPath)throws Throwable
    {
        Bitmap bitmap = null;
        MediaMetadataRetriever mediaMetadataRetriever = null;
        try
        {
            mediaMetadataRetriever = new MediaMetadataRetriever();
            if (Build.VERSION.SDK_INT >= 14)
                mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
                else
                    mediaMetadataRetriever.setDataSource(videoPath);
         //   mediaMetadataRetriever.setDataSource(videoPath);
            bitmap = mediaMetadataRetriever.getFrameAtTime(1, MediaMetadataRetriever.OPTION_CLOSEST);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new Throwable("Exception in retriveVideoFrameFromVideo(String videoPath)"+ e.getMessage());
        }
        finally
        {
            if (mediaMetadataRetriever != null)
            {
                mediaMetadataRetriever.release();
            }
        }
        return bitmap;
    }`enter code here`
    

    【讨论】:

      猜你喜欢
      • 2011-05-25
      • 2017-05-15
      • 2011-06-18
      • 2020-05-16
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 2014-08-13
      • 2011-10-12
      相关资源
      最近更新 更多