I'm trying to use Glide to step through frames in a video file (without running into the keyframe seeking issue that Android suffers from). I can do this in Picasso by doing something like:
picasso = new Picasso.Builder(MainActivity.this).addRequestHandler(new PicassoVideoFrameRequestHandler()).build();
picasso.load("videoframe://" + Environment.getExternalStorageDirectory().toString() +
"/source.mp4#" + frameNumber)
.placeholder(drawable)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.into(imageView);
(frameNumber is simply an int which increases by 50000 microseconds each time). I also have a PicassoVideoFrameRequestHandler like this:
public class PicassoVideoFrameRequestHandler extends RequestHandler {
public static final String SCHEME = "videoframe";
@Override public boolean canHandleRequest(Request data) {
return SCHEME.equals(data.uri.getScheme());
}
@Override
public Result load(Request data, int networkPolicy) throws IOException {
FFmpegMediaMetadataRetriever mediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(data.uri.getPath());
String offsetString = data.uri.getFragment();
long offset = Long.parseLong(offsetString);
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(offset, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
return new Result(bitmap, Picasso.LoadedFrom.DISK);
}
}
I'd like to use Glide instead, as it handles memory a little better. Is there any way to have this functionality in Glide?
Or, really, any other way to create a set of frames from a video which I can step through!
Thanks!
You'll need to pass ".override(width, height)" to make Sam Judd's method to work. Otherwise you'll get only the first frame of the video as I've tested variety of approaches for hours. Hope it saves time for someone.
You can pass in a frame time (In microseconds, see the MediaMetadataRetriever docs) to VideoBitmapDecoder. This is untested, but it should work:
Thanks, this Post help me get there. Btw if you're using Glide 4.4 they change the way you get this result. To load a specific frame from a video uri.
You just need to use the object RequestOptions like this:
Where "positionInMillis" its a long variable from the video position that you want the image.