android capture video frame

Buda Gavril picture Buda Gavril · Mar 17, 2011 · Viewed 22.8k times · Source

I need to get a frame of a video file (it may be on sdcard, cache dir or app dir). I have package android.media in my application and inside I have class MediaMetadataRetriever. To get first frame into a bitmap, I use code:

public static Bitmap getVideoFrame(Context context, Uri videoUri) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
        retriever.setDataSource(context, videoUri);
        return retriever.captureFrame();
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException();
    } catch (RuntimeException ex) {
        throw new RuntimeException();
    } finally {
        retriever.release();
    }
}

But this it's not working. It throws an exception (java.lang.RuntimeException: setDataSource failed: status = 0x80000000) when I set data source. Do you know how to make this code to work? Or Do you have any similar (simple) solution without using ffmpeg or other external libraries? videoUri is a valid uri (media player can play video from that URI)

Answer

Rab Ross picture Rab Ross · Oct 7, 2011

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.