MediaMetadataRetriever类提供了一个统一的接口,用于从输入媒体文件中检索帧和元数据。它位于android.media包下。例如:检索歌曲名称,艺术家名称,视频的宽度或高度,视频格式/ MIME类型,媒体的持续时间,媒体修改日期等。 MediaMetadataRetriever类提供的常量/键很多。这些常量用于检索媒体信息。尽管从它们的名称可以明显看出许多常量所做的工作,但这只是对MediaMetadataRetriever类中存在的每个常量的简短描述。
MediaMetadataRetriever类的重要常量
Constant Type |
Constant Name |
Description |
---|---|---|
int | METADATA_KEY_ALBUM | The metadata key to retrieve the information about the album title of the data source. |
int | METADATA_KEY_ALBUMARTIST | The metadata key to retrieve the information about the performers or artist associated with the data source. |
int | METADATA_KEY_ARTIST | The metadata key to retrieve the information about the artist of the data source. |
int | METADATA_KEY_AUTHOR | The metadata key to retrieve the information about the author of the data source. |
int | METADATA_KEY_CD_TRACK_NUMBER | The metadata key to retrieve the numeric string describing the order of the audio data source on its original recording. |
int | METADATA_KEY_COMPILATION | The metadata key to retrieve the music album compilation status. |
int | METADATA_KEY_COMPOSER | The metadata key to retrieve the information about the composer of the data source. |
int | METADATA_KEY_DATE | The metadata key to retrieve the date when the data source was created or modified. |
int | METADATA_KEY_DISC_NUMBER | The metadata key to retrieve the numeric string that describes which part of a set the audio data source comes from. |
int | METADATA_KEY_DURATION | The metadata key to retrieve the playback duration of the data source. |
Constant Type |
Constant Name |
Description |
---|---|---|
int | METADATA_KEY_GENRE | The metadata key to retrieve the content type or genre of the data source. |
int | METADATA_KEY_MIMETYPE | The metadata key to retrieve the mime type of the data source. |
int | METADATA_KEY_NUM_TRACKS | The metadata key to retrieve the number of tracks, such as audio, video, text, in the data source, such as a mp4 or 3gpp file. |
int | METADATA_KEY_TITLE | The metadata key to retrieve the data source title. |
int | METADATA_KEY_WRITER | The metadata key to retrieve the information of the writer (such as lyricist) of the data source. |
int | METADATA_KEY_YEAR | The metadata key to retrieve the year when the data source was created or modified. |
int | OPTION_CLOSEST | This option is used with getFrameAtTime(long, int) to retrieve a frame (not necessarily a keyframe) associated with a data source that is located closest to or at the given time. |
int | OPTION_CLOSEST_SYNC | This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located closest to (in time) or at the given time. |
int | OPTION_NEXT_SYNC | This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located right after or at the given time. |
int | OPTION_PREVIOUS_SYNC | This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located right before or at the given time. |
MediaMetadataRetriever类中可用的方法
Method Type |
Methods |
---|---|
String |
extractMetadata(int keyCode) Call this method after setDataSource(). |
byte[] |
getEmbeddedPicture() Call this method after setDataSource(). |
Bitmap |
getFrameAtTime(long timeUs, int option) Call this method after setDataSource(). |
Bitmap |
getFrameAtTime(long timeUs) Call this method after setDataSource(). |
Bitmap |
getFrameAtTime() Call this method after setDataSource(). |
void |
release() Call it when one is done with the object. This method releases the memory allocated internally. |
void |
setDataSource(FileDescriptor fd, long offset, long length) Sets the data source (FileDescriptor) to use. |
void |
setDataSource(String path) Sets the data source (file pathname) to use. |
void |
setDataSource(FileDescriptor fd) Sets the data source (FileDescriptor) to use. |
void |
setDataSource(Context context, Uri uri) Sets the data source as a content Uri. |
void |
Close() Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement. |
例子
1.获取mp3持续时间
这是Java的示例代码片段,用于获取mp3持续时间。
Java
// load data file
// filePath is of type String which holds the path of file
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(filePath);
// get mp3 info
String duration = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long dur = Long.parseLong(duration);
// convert duration to minute:seconds
String seconds = String.valueOf((dur % 60000) / 1000);
String minutes = String.valueOf(dur / 60000);
String out = minutes + ":" + seconds;
if (seconds.length() == 1) {
txtTime.setText("0" + minutes + ":0" + seconds);
}
else {
txtTime.setText("0" + minutes + ":" + seconds);
}
// close object
metaRetriever.release();
Java
MediaMetadataRetriever m = new MediaMetadataRetriever();
// load data file
m.setDataSource(path);
// getting the bitmap of a frame from video
Bitmap thumbnail = m.getFrameAtTime();
if (Build.VERSION.SDK_INT >= 17) {
String s = m.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
}
// Another way of determining whether the video is Landscape or portrait
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(inputPath);
video_width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
video_height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
// close object
retriever.release();
// If the width is bigger than the height then it means that
// the video was taken in landscape mode and vice versa.
if ((video_width > video_height)) {
// landscape
}
else {
// portrait
}
Java
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(filePath);
// getting the embedded picture from media
byte[] art = retriever.getEmbeddedPicture();
if (art != null) {
// Convert the byte array to a bitmap
imgAlbum.setImageBitmap(BitmapFactory.decodeByteArray(art, 0, art.length));
}
else {
imgAlbum.setImageResource(R.drawable.no_image);
}
// close object
retriever.release();
Java
try {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, videoUri);
// Retrieve media data use microsecond
long interval = (endPosition - startPosition) / (totalThumbsCount - 1);
for (long i = 0; i < totalThumbsCount; ++i) {
long frameTime = startPosition + interval * i;
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(frameTime * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if (bitmap == null)
continue;
try {
bitmap = Bitmap.createScaledBitmap(bitmap, THUMB_WIDTH, THUMB_HEIGHT, false);
}
catch (final Throwable t) {
t.printStackTrace();
}
// add bitmaps to the recyclerview here…
}
mediaMetadataRetriever.release();
}
catch (final Throwable e) {
Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
}
2.检测视频的方向
以下是一个示例视频
这是Java的示例代码片段,用于检测视频的方向
Java
MediaMetadataRetriever m = new MediaMetadataRetriever();
// load data file
m.setDataSource(path);
// getting the bitmap of a frame from video
Bitmap thumbnail = m.getFrameAtTime();
if (Build.VERSION.SDK_INT >= 17) {
String s = m.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
}
// Another way of determining whether the video is Landscape or portrait
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(inputPath);
video_width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
video_height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
// close object
retriever.release();
// If the width is bigger than the height then it means that
// the video was taken in landscape mode and vice versa.
if ((video_width > video_height)) {
// landscape
}
else {
// portrait
}
3.在音乐应用中设置专辑封面和专辑标题
以下是示例图片
这是Java的示例代码段,用于在Music App中设置专辑封面和专辑标题。
Java
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(filePath);
// getting the embedded picture from media
byte[] art = retriever.getEmbeddedPicture();
if (art != null) {
// Convert the byte array to a bitmap
imgAlbum.setImageBitmap(BitmapFactory.decodeByteArray(art, 0, art.length));
}
else {
imgAlbum.setImageResource(R.drawable.no_image);
}
// close object
retriever.release();
4.制作像TikTok这样的CropVideo活动
以下是一个示例视频
这是Java用于制作CropVideo活动(如TikTok)的示例代码段。
Java
try {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, videoUri);
// Retrieve media data use microsecond
long interval = (endPosition - startPosition) / (totalThumbsCount - 1);
for (long i = 0; i < totalThumbsCount; ++i) {
long frameTime = startPosition + interval * i;
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(frameTime * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if (bitmap == null)
continue;
try {
bitmap = Bitmap.createScaledBitmap(bitmap, THUMB_WIDTH, THUMB_HEIGHT, false);
}
catch (final Throwable t) {
t.printStackTrace();
}
// add bitmaps to the recyclerview here…
}
mediaMetadataRetriever.release();
}
catch (final Throwable e) {
Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
}
Note:
- Always check for illegal filePath.
- Handle the null bitmap condition. There may be cases when the media doesn’t return a valid bitmap.
- The frame index must be that of a valid frame. The total number of frames available for retrieval can be queried via the METADATA_KEY_VIDEO_FRAME_COUNT key.
- When retrieving the frame at the given time position, there is no guarantee that the data source has a frame located at the position. When this happens, a frame nearby will be returned. If time is negative, time position and option will be ignored, and any frame that the implementation considers as representative may be returned.
- setDataSource(), Call this method before the rest of the methods in this class. This method may be time-consuming.
参考链接: https : //developer.android.com/reference/android/media/MediaMetadataRetriever