2

This is the function i am using:

public Bitmap getVideoFrame(String FD, long time) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setDataSource(FD);
        return retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    } catch (RuntimeException ex) {
        ex.printStackTrace();
    } finally {
        try {
            retriever.release();
        } catch (RuntimeException ex) {
        }
    }
    return null;
}

where: FD is the path of the video time = videoview.getCurrentPosition();

The problem is that this function does not get the exact frame i need to get. on a longer video (20 min) it will be more accurate than in a short video (10-20 seconds). Is there something i am missing, if not, what could I use instead of the retriever?

rosu alin
  • 5,674
  • 11
  • 69
  • 150
  • FYI: Android 6.0 Marshmallow has known bug where exact frame is not returned by the `getFrameAtTime` API - https://code.google.com/p/android/issues/detail?id=193194 – Hossain Khan Jan 04 '17 at 16:50

5 Answers5

2

Try to use without option ...

retriever.getFrameAtTime(time * 1000);

I had same issue and after I made this modification it worked perfect.

Cristi Maris
  • 1,329
  • 22
  • 21
  • This uses OPTION_CLOSEST_SYNC instead of OPTION_CLOSEST which gives the closest sync frame which is not very accurate since it gets a sync frame. – hoffware Oct 01 '19 at 02:32
1

There is a bug in that function and it apparently won't work for small sized video's and is highly unreliable, I recently asked this question here on SO, see this post, but got no correct answers, so I did a lot of research and used FFMPEG instead, using FFMPEG I was able to extract Video Frames accurate to milliseconds, also note that the process of extracting frames on a mobile phone is slow and for a big video i.e. above 50Mb it often took me 2 mins to extract what I wanted.

Community
  • 1
  • 1
Arif Nadeem
  • 8,524
  • 7
  • 47
  • 78
  • do you now any link or something, that could help me with using FFMPEG? – rosu alin Feb 12 '13 at 08:16
  • There are a lot of FFMPEG libaries built for FFMPeg, you should type FFMPeg for Android on google and take the library you want, I used this library from GitHub, https://github.com/uday-rayala/video-trimmer – Arif Nadeem Feb 12 '13 at 08:38
  • is it free to use, does it have an Apache License or do I have to pay to use it, because I am only allowed to use free libraries. I have searched the internet for FFMPEG, but many said that this is not free to use in commercial applications – rosu alin Feb 12 '13 at 13:09
  • 1
    FFmpeg is free to incorporate as long as you using open video and audio formats, look at this similar question regarding the licencing for FFMpeg http://stackoverflow.com/a/9272100/892055 – Arif Nadeem Feb 12 '13 at 15:53
1
retriever.getFrameAtTime(second* 1000*1000);

it need microsecond but not millisecond.

wing zjq
  • 81
  • 5
  • millisecond,i forget ,lol,i used to think it need millisecond. : ) – wing zjq Sep 11 '15 at 12:12
  • Tested true. This should be the accepted answer. Actually, you can tell it from the argument name: timeUs, which means time in µs, that is, of course, microsecond. – topduo Dec 13 '15 at 02:18
  • God dammit, the whole API uses milliseconds but this method uses microseconds. Thanks a lot! – UnsafePointer Mar 20 '17 at 00:48
0

Yes, I Agree retriever.getFrameAtTime is not accurate.

An alternative solution to replace the getFrameAt method of Android MediaMetadataRetriever. AV_FrameCapture uses MediaCodec to decode the video frame and use OpenGL to convert the video frame as RGB Bitmap. As Android MediaMetadataRetriever does not guarantee to return a result when calling getFrameAtTime, this AV_FrameCapture can be used to extract a frame of video with accuracy.

https://stackoverflow.com/a/60633395/6676310

VIISHRUT MAVANII
  • 11,410
  • 7
  • 34
  • 49
-3
ImageView imageView1=(ImageView)findViewById(R.id.imageView1);

Bitmap bm=ThumbnailUtils.createVideoThumbnail(Environment.getExternalStorageDirectory() + "/videocapture.3gp",Thumbnails.MICRO_KIND);

imageView1.setImageBitmap(bm);
user4286376
  • 40
  • 1
  • 4