3

I'm just starting on android development.

I've been trying for some time to extract frames from video files I have on my phone like this:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(getApplicationContext(),linkToVideo); // linkToVideo is Uri
ImageView frameView = (ImageView) findViewById(R.id.video_frame);
frameView.setImageBitmap(retriever.getFrameAtTime(frameTime,MediaMetadataRetriever.OPTION_CLOSEST)); // frameTime in microseconds

This works for 640x480 .mp4 videos but not for the 1280x720 .3gp files my camera has recorded. It just takes an awfull long time and eventually the app stops responding. When I use OPTION_CLOSEST_SYNC everything runs smoothly, however I'm interested in getting more than the sync frames.

Any ideas on how I can solve this? I was trying to avoid video encoding but if there is no other option I'll resort to that.

Thanks in advance for the time you take to help me.

Pedro Leal
  • 183
  • 1
  • 10

2 Answers2

1

Try FFmpegMediaMetadataRetriever:

import wseemann.media.FFmpegMediaMetadataRetriever;

...

FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
retriever.setDataSource(getApplicationContext(),linkToVideo); // linkToVideo is  Uri
ImageView frameView = (ImageView) findViewById(R.id.video_frame);
frameView.setImageBitmap(retriever.getFrameAtTime(frameTime,MediaMetadataRetriever.OPTION_CLOSEST)); // frameTime in microseconds
William Seemann
  • 3,440
  • 10
  • 44
  • 78
  • 1
    Thank you William. It works with FFmpeg :) I was trying to stick to the android library but in this case FFmpeg is clearly the better option. Regards – Pedro Leal Apr 28 '15 at 10:44
  • I am trying the same and am getting null frames when using the Closest option. If I skip that option I get some frame but not exact. Any ideas? – Akash Gorai Mar 15 '22 at 22:55
0

Multiply the MediaPlayer.currentPosition by 1000

SNAPSHOT_DURATION_IN_MILLIS * 1000

Example

    val mediaMetadataRetriever = MediaMetadataRetriever()

    return try {

        println("mediaPlayer.currentPosition.toLong(): ${mediaPlayer?.currentPosition?.toLong()}")

        mediaMetadataRetriever.setDataSource(context, uri)

        val bitmap = mediaPlayer?.let { mediaMetadataRetriever.getFrameAtTime(it.currentPosition.toLong()*1000, MediaMetadataRetriever.OPTION_CLOSEST) }

        bitmap

    } catch (t: Throwable) {

        // TODO log

        null

    } finally {

        try {

            mediaMetadataRetriever.release()

        } catch (e: RuntimeException) {

            //

        }

    }
Michael N
  • 436
  • 5
  • 6