I'm trying to get all frames from a video using MediaMetadataRetriever and getFrameAt() method.
Using FFMPEG, I've got the following information :
Video frame counts : 234 frames
Video duration in milliseconds : 90000
int counter = 0; long mVideoDuration = 9000; for (long i = 0; i < mVideoDuration * 1000; i += 1000) { Bitmap thumbnail = mMediaMetadataRetriever.getFrameAtTime(i); }
The above code does not work, it's loop for almost 8944 times, and this is too much, I don't want to get all these frames, I just want to get the 234 frames.
getFrameAtIndex() WORKS VERY WELL, but due to API level compatibility, I would like to make it work with getFrameAt() method
To get the frames with getFrameeAtTime() youd have to know the time of every frame in the video. You could roughly calculate that if u already know the frame count by getting the frametime (duration/frames), taking the math.ceil() method on that and taking that as your incrementor. however, youd have to check if the last frame gets read since u can't always get the exact frame time, bc they tend to have alot of decimal places wich can lead to wrong representation as float. A 60fps video for example would have a frame time of 16+1/3 ms. Wich has infinite deecimal places. In addition this method wouldn't even work at all if you have a video with too high fps since in that case the round up done by math.ceil() can lead to a big enough margin to skip frames. To be precise this method only works if:
(math.ceil(frameTime)-frameTime)⋅frameCount<frameTime
I hope, by now u got that it's a pretty bad idea and u should probably use another way to get the individual frames. But still, heres an implementation:
Of couse this is already assuming that,
(math.ceil(frameTime)-frameTime)⋅frameCount<frameTime
is given. And i can't guarantee that the declaframeTime will result the correct value since i dont know exactly how decimal dividing is handleed internally and its entirely possible that is causes problems due to floating point overflow