MediaMetadataRetrieverCompat - 获取视频信息与缩略图兼容方案

效果

     图片         音频          视频         自定义

示例APK:example-debug.apk

Gradle

1
2
3
4
5
6
7
8
9
10
11
12
//必选
implementation 'in.xiandan.mmrc:media-metadata-retriever-compat:1.2.0'

//可选,需要Exif支持时必选
implementation 'com.android.support:exifinterface:28.0.0'
//可选,需要FFmpeg支持时必选,全平台约24M
implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'

//只保留v7a,可降低至3M
ndk {
abiFilters 'armeabi-v7a'
}

数据源类型

datasource 中预设了一些DataSource,以提供不同的输入源,如果需要自定义数据源,可implements DataSource或参考其它数据源

设置数据源

设置数据源的操作建议放在子线程

1
2
3
4
5
6
7
8
MediaMetadataRetrieverCompat mmrc = new MediaMetadataRetrieverCompat();

//设置数据源
mmrc.setDataSource(source);
//设置数据源或抛出异常
mmrc.setDataSourceOrThrow(source);
//设置数据源或抛出异常 并指定检索器
mmrc.setDataSourceOrThrow(source, AndroidMediaMetadataRetrieverFactory.class);

获取Metadata信息

1
2
3
4
5
6
7
8
9
10
11
12
final String width = mmrc.extractMetadata(MediaMetadataKey.WIDTH);

//将值转换为int
final int width = mmrc.extractMetadataInt(MediaMetadataKey.WIDTH, 0);

//将值转换为float
final float width = mmrc.extractMetadataFloat(MediaMetadataKey.WIDTH, 0f);

//将值转换为long
final long width = mmrc.extractMetadataLong(MediaMetadataKey.WIDTH, 0L);

...

获取缩略图

取帧是耗时操作,需要放在子线程,视频有4种取帧方式

1
2
3
4
5
6
7
8
9
10
11
//最接近timeUs的关键帧 - 仅视频
MediaMetadataKey.OPTION_CLOSEST_SYNC

//最接近timeUs的帧,不一定是关键帧(性能开销较大) - 仅视频
MediaMetadataKey.OPTION_CLOSEST

//早于timeUs的关键帧 - 仅视频
MediaMetadataKey.OPTION_PREVIOUS_SYNC

//晚于timeUs的关键帧 - 仅视频
MediaMetadataKey.OPTION_NEXT_SYNC
1
2
3
4
5
6
7
8
9
10
11
//获取第一帧原尺寸图片
mmrc.getFrameAtTime();

//获取指定毫秒的原尺寸图片 注意这里传的毫秒不再是微秒
mmrc.getFrameAtTime(0, MediaMetadataKey.OPTION_CLOSEST_SYNC);

//获取指定毫秒的缩略图,并基于指定宽高缩放,输出的Bitmap不一定是指定宽高
mmrc.getScaledFrameAtTime(0, MediaMetadataKey.OPTION_CLOSEST_SYNC, 300, 300);

//获取指定毫秒的缩略图,并按指定宽高缩放裁剪,输出的Bitmap一定是指定宽高
mmrc.getCenterCropFrameAtTime(0, MediaMetadataKey.OPTION_CLOSEST_SYNC, 300, 300);

全局配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//创建一个新的配置构造器
MediaMetadataConfig.newBuilder()
.setCustomDataSourceCallback(new MediaMetadataConfig.CustomDataSourceCallback() {
@Override
public void setCustomDataSource(IMediaMetadataRetriever retriever, DataSource source) {
//当设置了自定义数据源时 会回调
}
})
//添加格式检查器
.addFileFormatChecker(new CustomFormatChecker())
//添加自定义检索器
.addCustomRetrieverFactory(new SVGMediaMetadataRetrieverFactory())
.addCustomRetrieverFactory(new CustomMediaMetadataRetrieverFactory())
.build()
//应用配置
.apply();

自定义检索器

custom 演示了以SVG文件为例如何自定义检索器

1
2
3
4
5
MediaMetadataConfig.newBuilder()
.addFileFormatChecker(new CustomFormatChecker())
.addCustomRetrieverFactory(new SVGMediaMetadataRetrieverFactory())
.build()
.apply();

相关资料

fresco/imageformat
FFmpegMediaMetadataRetriever
MediaMetadataRetriever
ImageDecoder
ExifInterface