android capture video frame

空扰寡人 提交于 2019-11-27 00:52:23

The following works for me:

public static Bitmap getVideoFrame(FileDescriptor FD) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(FD);
            return retriever.getFrameAtTime();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (RuntimeException ex) {
            ex.printStackTrace();
        } finally {
            try {
                retriever.release();
            } catch (RuntimeException ex) {
            }
        }
        return null;
    }

Also works if you use a path instead of a filedescriptor.

Try this, I've used it and its working

public static Bitmap getVideoFrame(Context context, Uri uri) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setDataSource(uri.toString(),new HashMap<String, String>());
        return retriever.getFrameAtTime();
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    } catch (RuntimeException ex) {
        ex.printStackTrace();
    } finally {
        try {
            retriever.release();
        } catch (RuntimeException ex) {
        }
    }
    return null;
}

In place of uri you can directly pass your url .

I have the same mistake on my application. I saw on this site that

this is an unofficial way of doing it and it will only work in cupcake (and maybe later version). The Android team does not guarantee that libmedia_jni.so, which the java file uses, will be included or have the same interface in future versions.

http://osdir.com/ml/AndroidDevelopers/2009-06/msg02442.html

I have updated my phone to GingerBread and it doesn't work anymore.

Uri's are not very specific. Sometimes they refer to something in a bundle. They often need to be translated to an absolute path form. The other instance in which you used the Uri, it probably was smart enough to check what kind of Uri it was. This case that you have shown appears to be not looking very hard.

I was getting the same error using the ThumbnailUtils class http://developer.android.com/reference/android/media/ThumbnailUtils.html
It uses MediaMetadataRetriever under the hood and most of the time you can send it a filepath using this method with no problem:

public static Bitmap createVideoThumbnail (String filePath, int kind)  

However, on Android 4.0.4, I kept getting the same error @gabi was seeing. Using a file descriptor instead solved the problem and still works for non-4.0.4 devices. I actually ended up subclassing ThumbnailUtils. Here is my subclass method:

 public static Bitmap createVideoThumbnail(FileDescriptor fDescriptor, int kind) 
 {
    Bitmap bitmap = null;
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setDataSource(fDescriptor);
        bitmap = retriever.getFrameAtTime(-1);
    } 
    catch (IllegalArgumentException ex) {
        // Assume this is a corrupt video file
        Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString());
    }
    catch (RuntimeException ex) {
        // Assume this is a corrupt video file.
        Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString());
    } finally {
        try {
            retriever.release();
        } catch (RuntimeException ex) {
            // Ignore failures while cleaning up.
        }
    }

    if (bitmap == null) return null;

    if (kind == Images.Thumbnails.MINI_KIND) {
        // Scale down the bitmap if it's too large.
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int max = Math.max(width, height);
        if (max > 512) {
            float scale = 512f / max;
            int w = Math.round(scale * width);
            int h = Math.round(scale * height);
            bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
        }
    } else if (kind == Images.Thumbnails.MICRO_KIND) {
        bitmap = extractThumbnail(bitmap,
                TARGET_SIZE_MICRO_THUMBNAIL,
                TARGET_SIZE_MICRO_THUMBNAIL,
                OPTIONS_RECYCLE_INPUT);
    }
    return bitmap;
}

The exception is thrown also when the File doesn't exist. So before calling setDataSource() you'd better check if new File(url).exists().

I used this code and that is working for me. you can try this one.

if (Build.VERSION.SDK_INT >= 14) {
                ffmpegMetaDataRetriever.setDataSource(
                        videoFile.getAbsolutePath(),
                        new HashMap<String, String>());
            } else {
                ffmpegMetaDataRetriever.setDataSource(videoFile
                        .getAbsolutePath());
            }
Dhiraj Tayade

so is there a specific way to get the frame from video as

 File sdcard = Environment.getExternalStorageDirectory();
 File file = new File(sdcard, "myvideo.mp4");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!