私はGlideを使用してビデオファイル内のフレームをステップスルーしようとしています(Androidが苦しんでいるキーフレームを探すことなく)。ピカソでこれを行うには、次のようにします。
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は単に、毎回50000マイクロ秒ずつ増加するintです)。次のようなPicassoVideoFrameRequestHandlerもあります。
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);
}
}
代わりに、Glideを使用したいと思います。Glideは、メモリの処理が少し優れているからです。 Glideでこの機能を使用する方法はありますか?
または、実際に、ビデオからフレームのセットを作成する他の方法で、ステップスルーできます!
ありがとう!
Sam Juddのメソッドを機能させるには、「。override(width、height)」を渡す必要があります。それ以外の場合は、さまざまなアプローチを何時間もテストしたため、ビデオの最初のフレームのみが表示されます。それが誰かのために時間を節約することを望みます。
BitmapPool bitmapPool = Glide.get(getApplicationContext()).getBitmapPool();
int microSecond = 6000000;// 6th second as an example
VideoBitmapDecoder videoBitmapDecoder = new VideoBitmapDecoder(microSecond);
FileDescriptorBitmapDecoder fileDescriptorBitmapDecoder = new FileDescriptorBitmapDecoder(videoBitmapDecoder, bitmapPool, DecodeFormat.PREFER_ARGB_8888);
Glide.with(getApplicationContext())
.load(yourUri)
.asBitmap()
.override(50,50)// Example
.videoDecoder(fileDescriptorBitmapDecoder)
.into(yourImageView);
ありがとう、この投稿は私がそこに着くのを助けます。ところで、Glide 4.4を使用している場合、この結果を得る方法が変わります。ビデオURIから特定のフレームをロードします。
次のように、オブジェクトRequestOptionsを使用するだけです。
long interval = positionInMillis * 1000;
RequestOptions options = new RequestOptions().frame(interval);
Glide.with(context).asBitmap()
.load(videoUri)
.apply(options)
.into(viewHolder.imgPreview);
「positionInMillis」は、画像が必要なビデオ位置からの長い変数です。
フレーム時間(マイクロ秒単位、 MediaMetadataRetriever docs を参照)を VideoBitmapDecoder に渡すことができます。これはテストされていませんが、動作するはずです。
BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
FileDescriptorBitmapDecoder decoder = new FileDescriptorBitmapDecoder(
new VideoBitmapDecoder(frameTimeMicros),
bitmapPool,
DecodeFormat.PREFER_ARGB_8888);
Glide.with(fragment)
.load(uri)
.asBitmap()
.videoDecoder(decoder)
.into(imageView);