从视频文件创建缩略图返回空位图

时间:2013-04-11 14:43:41

标签: android android-camera video-thumbnails

我发送了启动摄像机的意图

PackageManager pm = getPackageManager();
    if(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            Intent video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
            File tempDir= new File(Environment.getExternalStoragePublicDirectory(
                      Environment.DIRECTORY_PICTURES), "BCA");
            if(!tempDir.exists())
            {
                if(!tempDir.mkdir()){
                    Toast.makeText(this, "Please check SD card! Image shot is impossible!", Toast.LENGTH_SHORT).show();
                }
            }

                String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.US).format(new Date());
                File mediaFile = new File(tempDir.getPath() + File.separator +
                "VIDEO_"+ timeStamp + ".mp4");
                Uri videoUri = Uri.fromFile(mediaFile);
                video.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
                video.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                startActivityForResult(video, VIDEO_REQUEST);

    }else{
        Toast.makeText(this, "This device does not have a rear facing camera",Toast.LENGTH_SHORT).show();
    }

我拍摄视频并正确存储,当onActivityResult被解雇时,我会使用意图来获取存储它的uri来创建位图

这是uri file:///storage/emulated/0/Pictures/BCA/VIDEO_20131227_145043.mp4

的一个例子
 Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(intent.getDataString(), MediaStore.Video.Thumbnails.MICRO_KIND);

但每次位图都为空。所以,既然文档说May return null if the video is corrupt or the format is not supported我检查了目录中的视频,它播放得很好,还有一个支持的.mp4文件,所以我在这里做错了什么?

4 个答案:

答案 0 :(得分:4)

您可以尝试MediaMetadataRetrieverFFmpegMediaMetadataRetriever。这是一个例子:

FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(intent.getDataString());
Bitmap b = mmr.getFrameAtTime();
mmr.release();

答案 1 :(得分:2)

我记得createVideoThumbnail中的参数filePath应该是经典的文件路径,而不是URI

...

Uri videoUri = intent.getData();
final String realFilePath = getRealPathFromUri();
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(realFilePath, MediaStore.Video.Thumbnails.MICRO_KIND);
...

public String getRealPathFromURI(final Uri contentURI) {
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        return contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
        if ( idx == -1 ) {
            return contentURI.getPath();
        }
        String rvalue =  cursor.getString(idx);
        cursor.close();
        return rvalue;
    }
}

修改

基于createVideoThumbnail的源代码,我创建了另一个实现:

public static Bitmap createVideoThumbnail(Context context, Uri uri, int kind) {
    Bitmap bitmap = null;
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
        retriever.setDataSource(context, uri);
        bitmap = retriever.captureFrame();
    } catch (IllegalArgumentException ex) {
        // Assume this is a corrupt video file
    } catch (RuntimeException ex) {
        // Assume this is a corrupt video file.
    } finally {
        try {
            retriever.release();
        } catch (RuntimeException ex) {
            // Ignore failures while cleaning up.
        }
    }
    if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
        bitmap = ThumbnailUtils.extractThumbnail(bitmap,
                ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
                ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
    }
    return bitmap;
}

答案 2 :(得分:1)

使用此文件“mediaFile”并将其转换为URI

      Uri uri=Uri.fromFile(mediaFile);

然后在下面的方法中传递该URI。这对我来说很好。

Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(uri.getPath(), MediaStore.Video.Thumbnails.MICRO_KIND);

希望这会对你有所帮助。

答案 3 :(得分:0)

我遇到了这个问题并以这种方式解决了这个问题:

  1. 创建FileUtils类,为您找到文件的路径(我无法找到该类的引用,因此我创建了一个要点)

    String correctedUri = FileUtils.getPath(mContext, Uri.parse(localUri));
    
  2. 使用以下代码

    Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(correctedUri, MediaStore.Video.Thumbnails.MICRO_KIND);
    
  3. 已编辑: 请参阅this解决方案,它具有更好的性能和更轻松。