1package com.bumptech.glide.load.resource.bitmap;
2
3import android.graphics.Bitmap;
4import android.media.MediaMetadataRetriever;
5import android.os.ParcelFileDescriptor;
6
7import com.bumptech.glide.load.DecodeFormat;
8import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
9
10import java.io.IOException;
11
12/**
13 * An {@link com.bumptech.glide.load.resource.bitmap.BitmapDecoder} that can decode a thumbnail frame
14 * {@link Bitmap} from a {@link android.os.ParcelFileDescriptor} containing a video.
15 *
16 * @see android.media.MediaMetadataRetriever
17 */
18public class VideoBitmapDecoder implements BitmapDecoder<ParcelFileDescriptor> {
19    private static final MediaMetadataRetrieverFactory DEFAULT_FACTORY =  new MediaMetadataRetrieverFactory();
20    private MediaMetadataRetrieverFactory factory;
21
22    public VideoBitmapDecoder() {
23        this(DEFAULT_FACTORY);
24    }
25
26    VideoBitmapDecoder(MediaMetadataRetrieverFactory factory) {
27        this.factory = factory;
28    }
29
30    @Override
31    public Bitmap decode(ParcelFileDescriptor resource, BitmapPool bitmapPool, int outWidth, int outHeight,
32            DecodeFormat decodeFormat)
33            throws IOException {
34        MediaMetadataRetriever mediaMetadataRetriever = factory.build();
35        mediaMetadataRetriever.setDataSource(resource.getFileDescriptor());
36        Bitmap result = mediaMetadataRetriever.getFrameAtTime();
37        mediaMetadataRetriever.release();
38        resource.close();
39        return result;
40    }
41
42    @Override
43    public String getId() {
44        return "VideoBitmapDecoder.com.bumptech.glide.load.resource.bitmap";
45    }
46
47    // Visible for testing.
48    static class MediaMetadataRetrieverFactory {
49        public MediaMetadataRetriever build() {
50            return new MediaMetadataRetriever();
51        }
52    }
53}
54