I am working on an application that ultimately cuts a video into frames of, say, 200 millisecond intervals.
The application works, you select a video, and the application will split it into raster images that are stored on the device. The problem is that FFmpegMediaMetaRetriever.getFrameAtTime () is incredibly slow. I mean, it takes longer to process the video than the length of the video itself, I see about 1.1 seconds on average per frame.
I tracked the delay before calling getFrameAtTime. Does anyone else know of a better way to get frames from a video at a specific time?
code:
new Thread(new Runnable() {
@Override
public void run() {
FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
retriever.setDataSource(getPath(EditVideo.this, mMediaUri));
String time = retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
MediaMetadataRetriever retriever1 = new MediaMetadataRetriever();
retriever1.setDataSource(getPath(EditVideo.this, mMediaUri));
int width = Integer.parseInt(retriever1.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
int height = Integer.parseInt(retriever1.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
retriever1.release();
int videoDuration = Integer.parseInt(time);
int newWidth = 1024;
int newHeight = Math.round(height * (1024f / width));
Bitmap bitmap;
for(int i=0;i<videoDuration;i+=mFrameEvery){
long startTime = System.currentTimeMillis();
bitmap = retriever.getFrameAtTime(i*1000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
long endTime = System.currentTimeMillis();
Log.d(TAG,"Took: " + ((endTime - startTime) / 1000f));
final Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
try {
File frameFile = getOutputMediaFile("IMAGEFILE",rev.size());
FileOutputStream fos = new FileOutputStream(frameFile);
scaledBitmap.compress(Bitmap.CompressFormat.PNG, 80, fos);
fos.close();
rev.add(frameFile.getAbsolutePath());
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(scaledBitmap);
totalFrames.setText("Total Frames: " + rev.size());
}
});
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.INVISIBLE);
seekBar.setEnabled(true);
}
});
}
}).start();
Log:
D/EditVideo: Took: 1.448
D/EditVideo: Took: 1.147
D/EditVideo: Took: 1.162
D/EditVideo: Took: 1.322
D/EditVideo: Took: 1.301
D/EditVideo: Took: 1.453
D/EditVideo: Took: 1.108
D/EditVideo: Took: 1.165
D/EditVideo: Took: 1.292
D/EditVideo: Took: 1.358
D/EditVideo: Took: 1.369
D/EditVideo: Took: 1.06
D/EditVideo: Took: 1.13
D/EditVideo: Took: 1.183
D/EditVideo: Took: 1.177
D/EditVideo: Took: 1.231
D/EditVideo: Took: 0.924
D/EditVideo: Took: 1.007
D/EditVideo: Took: 1.092
D/EditVideo: Took: 1.104
D/EditVideo: Took: 1.211
D/EditVideo: Took: 0.923
D/EditVideo: Took: 0.994
D/EditVideo: Took: 1.119
D/EditVideo: Took: 1.138
D/EditVideo: Took: 1.193
source
share