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?
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.