MediaMetadataRetriever.getFrameAtTime() returns only first frame

Chaitanya Chandurkar picture Chaitanya Chandurkar · Oct 7, 2012 · Viewed 20.6k times · Source

I have extracted frames from a video using MetadataRetriever, and have stored all images in an ArrayList<Bitmap>. I want to store all of them on an SD card (just for testing purposes).

But when I pull out a folder from the emulator and look at the saved images, all images were of the video's first frame only.

This is how I extract the frames from the video:

File videoFile=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/videos","sample_mpeg4.mp4");

Uri videoFileUri=Uri.parse(videoFile.toString());

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(videoFile.getAbsolutePath());
ArrayList<Bitmap> rev=new ArrayList<Bitmap>();

//Create a new Media Player
MediaPlayer mp = MediaPlayer.create(getBaseContext(), videoFileUri);

int millis = mp.getDuration();
for(int i=0;i<millis;i+=100){
   Bitmap bitmap=retriever.getFrameAtTime(i,OPTION_CLOSEST_SYNC);
   rev.add(bitmap);
}

And this is how I'm saving them (I'm calling this method and passing the bitmap ArrayList):

public void saveFrames(ArrayList<Bitmap> saveBitmapList) throws IOException{
    Random r = new Random();
    int folder_id = r.nextInt(1000) + 1;

    String folder = Environment.getExternalStorageDirectory()+"/videos/frames/"+folder_id+"/";
    File saveFolder=new File(folder);
    if(!saveFolder.exists()){
       saveFolder.mkdirs();
    }

    int i=1;
    for (Bitmap b : saveBitmapList){
       ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

        File f = new File(saveFolder,("frame"+i+".jpg"));

        f.createNewFile();

        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());

           fo.flush();
           fo.close();

        i++;
    }
    Toast.makeText(getApplicationContext(),"Folder id : "+folder_id, Toast.LENGTH_LONG).show();

}

When I pull out a folder to see all frames, all of the images were of the first frame of video. Can someone please explain to me what is happening?

UPDATE:

I've tried with another video. I've found that I'm not getting blank images, but it's always returning the first frame only.

MediaMetadataRetriever.getFrameAtTime(long timeUS) is returning only the first frame, but I want to retrieve all frames. What changes should I make?

How do I tackle this?

Answer

breenger picture breenger · Nov 27, 2012

MediaMetadataRetriever's getFrameAt method takes in microseconds (1/1000000th of a second) instead of milliseconds, so in your case it is always rounding down to the 1st frame.