显示视频缩略图

时间:2014-12-10 10:59:39

标签: android picasso video-thumbnails

我需要使用Picasso库在列表视图中显示每个视频的缩略图,以便更快地运行,因此我需要使用缩略图路径。

这是我获取缩略图路径的代码(我在谷歌上找到了它,我改变了一些东西以适应我的应用程序):

String getThumbnailPathForLocalFile(Uri uri)
     {
         Cursor thumbCursor = null;
         try
         {
             thumbCursor = c.getContentResolver().
                     query(uri
                     , null
                     , null , null, null);

             if(thumbCursor.moveToFirst())
             {
                 // the path is stored in the DATA column
                 int dataIndex = thumbCursor.getColumnIndexOrThrow( MediaStore.MediaColumns.DATA );
                 String thumbnailPath = thumbCursor.getString(dataIndex);
                 return thumbnailPath;
             }
         }
         finally
         {
             if(thumbCursor != null)
             {
                 thumbCursor.close();
             }
         }

         return null;
     }

我的getView功能:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) c
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listview_item, null);
        }

        /* create a new view of my layout and inflate it in the row */
        // convertView = ( RelativeLayout ) inflater.inflate( resource, null );

        final Item item = items.get(position);
        if (item != null) {
            TextView t1 = (TextView) v.findViewById(R.id.txt_fileName);
            imageCity = (ImageView) v.findViewById(R.id.img_icon);

            switch (item.getType()) {
            case "video":
                String uri2 = item.getPath();
                Uri videoUri = MediaStore.Video.Thumbnails
                        .getContentUri(uri2);
                String VideoThumbnailPath =getThumbnailPathForLocalFile(videoUri);
                Picasso.with(c).load(new File(VideoThumbnailPath))
                        .resize(64, 64).into(imageCity);
                break;
            case "image":
                String uri4 = item.getPath();
                Picasso.with(c).load(new File(uri4)).resize(64, 64).into(imageCity);
                break;
            default:
                break;
            }


            if (t1 != null)
                t1.setText(item.getName());

        }
        return v;
    }

我检查了logcat和debug,所以我发现thumbCursor为null:

12-10 17:52:38.400: E/AndroidRuntime(8659): java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
12-10 17:52:38.400: E/AndroidRuntime(8659):     at com.example.knock.FileArrayAdapter.getThumbnailPathForLocalFile(FileArrayAdapter.java:105)
12-10 17:52:38.400: E/AndroidRuntime(8659):     at com.example.knock.FileArrayAdapter.getView(FileArrayAdapter.java:73)

任何人都可以帮助我吗? 非常感谢你

2 个答案:

答案 0 :(得分:2)

你的Uri不正确。 getContentUri(String volumeName)需要神奇的单词"external"而不是路径。你可能还没有缩略图。

您可以使用此段代码加载缩略图

private static final String SELECTION = MediaColumns.DATA + "=?";
private static final String[] PROJECTION = { BaseColumns._ID };
public static Bitmap loadVideoThumbnail(String videoFilePath, ContentResolver cr) {
    Bitmap result = null;
    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    String[] selectionArgs = { videoFilePath };
    Cursor cursor = cr.query(uri, PROJECTION, SELECTION, selectionArgs, null);
    if (cursor.moveToFirst()) {
        // it's the only & first thing in projection, so it is 0
        long videoId = cursor.getLong(0);
        result = MediaStore.Video.Thumbnails.getThumbnail(cr, videoId,
                Thumbnails.MICRO_KIND, null);
    }
    cursor.close();
    return result;
}

它的作用是:

  1. 通过查询Video.Media
  2. 查找文件的视频ID
  3. 将那个videoId传递给getThumbnail,阻止(在你的情况下是ui线程..)直到制作缩略图&解码。
  4. 很大的缺点是你不能在这里使用Picasso的路径。 (自定义加载工作,https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/MediaStoreRequestHandler.java似乎是一个实现,在此处对其进行了一些描述:http://blog.jpardogo.com/requesthandler-api-for-picasso-library/

    您可以获取缩略图路径,但是如果您查看缩略图表的内容,例如通过这段代码

        StringBuilder sb = new StringBuilder();
        Cursor query = getContentResolver().query(
                Video.Thumbnails.EXTERNAL_CONTENT_URI, null, null, null, null);
        DatabaseUtils.dumpCursor(query, sb);
        query.close();
        Log.d("XXX", sb.toString());
    

    您会发现并非所有视频都有缩略图。

    但那些可以通过

    找到
    public static String loadVideoThumbnailPath(String videoFilePath,
            ContentResolver cr) {
        String result = null;
        Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String[] selectionArgs = { videoFilePath };
        Cursor cursor = cr.query(uri, PROJECTION, SELECTION, selectionArgs,
                null);
        long videoId = -1;
        if (cursor.moveToFirst()) {
            videoId = cursor.getLong(0);
        }
        cursor.close();
        if (videoId > 0) {
            Uri uri2 = MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI;
            String[] projection2 = { MediaStore.Video.Thumbnails.DATA };
            String selection2 = MediaStore.Video.Thumbnails.VIDEO_ID + "=?";
            String[] selectionArgs2 = { String.valueOf(videoId) };
            Cursor cursor2 = cr.query(uri2, projection2, selection2, selectionArgs2, null);
            if (cursor2.moveToFirst()) {
                result = cursor2.getString(0);
            }
            cursor2.close();
        }
        return result;
    }
    

    (上面的PROJECTION& SELECTION常数仍然相同)

答案 1 :(得分:1)

获取视频文件缩略图的一种方法是使用MediaMetadataRetriever。但是该类获取视频文件的帧。因此,缩略图的大小可能会比通常的缩略图大。然后,您可以缩放该位图。

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
Uri url = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.test); //Your file uri
mmr.setDataSource(getContext(), url);
Bitmap bitmap = mmr.getFrameAtTime();
ImageView imageview = findViewById(R.id.yourimageviewid);
imageview.setImageBitmap(bitmap);

获取缩略图的另一种方法:

Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath,
MediaStore.Images.Thumbnails.MINI_KIND);