android获取mp4视频文件总时长和视频宽高,MediaMetadataRetriever类、方法以及使用详解

2019-12-19 00:35:10

android使用 MediaMetadataRetriever 获取视频文件的 总时长 和视频的分辨率。

根据该方式获取视频信息可以看出不仅仅可以获取时长和分辨率,还能获取到其他的一些视频信息,不错还是很强大的,不用自己去解析mp4文件了。此demo只是获取的mp4文件,其他的多媒体文件也可以获取到相应信息,比如mp3;

private void  getPlayTime(String mUri)
    {
        android.media.MediaMetadataRetriever mmr = new android.media.MediaMetadataRetriever();
        try {
            if (mUri != null) 
            {
                HashMap<String, String> headers = null;
                if (headers == null) 
                {
                    headers = new HashMap<String, String>();
                    headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");
                }
                mmr.setDataSource(mUri, headers);
            } else 
            {
                //mmr.setDataSource(mFD, mOffset, mLength);
            }

            String duration = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_DURATION);//时长(毫秒)
            String width = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽
            String height = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高
            
            Toast.makeText(MainActivity.this, "playtime:"+ duration+"w="+width+"h="+height, Toast.LENGTH_SHORT).show();

        } catch (Exception ex) 
        {
            Log.e("TAG", "MediaMetadataRetriever exception " + ex);
        } finally {
            mmr.release();
        }

    }


MediaMetadataRetriever类简单介绍

(1)属于在android api的那个包下:`android.media.MediaMetadataRetriever`

(2)类简单介绍:

 MediaMetadataRetriever类提供了用于从输入媒体文件检索帧和元数据的统一接口。

(3)这个是android提供的类,用来获取本地和网络media相关文件的信息

1

2

3

4

MediaMetadataRetriever常量以及属性进行简单介绍

(1)METADATA_KEY_ALBUM :检索数据源的专辑标题信息的元数据键。

(2)METADATA_KEY_ALBUMARTIST: 检索与数据源相关的表演者或艺术家的信息的元数据键。

(3)METADATA_KEY_ARTIST:检索有关数据源的艺术家的信息的元数据键。

(4)METADATA_KEY_AUTHOR:检索有关数据源作者的信息的元数据键

(5)METADATA_KEY_BITRATE:此键检索平均比特率(以比特/秒),如果可用的话。

(6)METADATA_KEY_CD_TRACK_NUMBER:元数据关键字,用于检索描述原始数据记录中音频数据源的顺序的数字字符串。

(7)METADATA_KEY_COMPILATION:检索音乐专辑编辑状态的元数据键

(8)METADATA_KEY_COMPOSER:检索有关数据源的作曲家的信息的元数据键

(9)METADATA_KEY_DATE:检索或创建数据源时的日期的元数据键

(10)METADATA_KEY_DISC_NUMBER:用于检索描述音频数据源的集合的哪一部分的数字字符串的元数据键

(11)METADATA_KEY_DURATION:检索数据源回放持续时间的元数据键

 (12) METADATA_KEY_GENRE:检索数据源的内容类型或类型的元数据键

(13) METADATA_KEY_HAS_AUDIO:如果存在此密钥,则媒体包含音频内容

(14)METADATA_KEY_HAS_VIDEO:如果存在此密钥,则媒体包含视频内容

(15)METADATA_KEY_LOCATION:此键检索位置信息,如果可用的话。该位置应根据ISO-6709标准,在MP4/3GP框“@ XYZ”下指定。例如,经度为90度和纬度为180度的位置将被检索为“-90+180”。

(16)METADATA_KEY_MIMETYPE:检索数据源MIME类型的元数据键。一些示例MIME类型包括:"video/mp4", "audio/mp4", "audio/amr-wb"

(17)METADATA_KEY_NUM_TRACKS:元数据键,用于检索数据源(如MP4或3GPP文件)中的音轨的数目,如音频、视频、文本。

(18)METADATA_KEY_TITLE:检索数据源标题的元数据键

(19) METADATA_KEY_VIDEO_HEIGHT:如果媒体包含视频,则该键检索其高度

(20)METADATA_KEY_VIDEO_ROTATION:此键检索视频旋转角度的程度,如果可用的话。视频旋转角度可以是0, 90, 180度,也可以是270度

(21)METADATA_KEY_VIDEO_WIDTH:如果媒体包含视频,则该密钥检索其宽度

(22)METADATA_KEY_WRITER:检索数据源的作者(如歌词作者)信息的元数据键

(23) METADATA_KEY_YEAR:检索创建或修改数据源的一年的元数据密钥

(24) OPTION_CLOSEST:此选项与GETFrimeTimeTime(long,int)一起使用,以检索与最接近或给定时间的数据源相关联的帧(不一定是关键帧)

(25)OPTION_CLOSEST_SYNC:(时间)或给定时间的数据源相关联的同步(或密钥)帧。

(26)OPTION_NEXT_SYNC:此选项与GETFrimeTimeTime(long,int)一起使用,以检索与数据源相关联的同步(或密钥)帧,该数据源位于或在给定的时间之后。

(27)OPTION_PREVIOUS_SYNC:此选项与GETFrimeTimeTime(long,int)一起使用,以检索与数据源相关联的同步(或密钥)帧,该数据源正好位于给定时间之前或给定时间

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

MediaMetadataRetriever 获取这个对象的方法

public MediaMetadataRetriever ()

1

MediaMetadataRetriever中的使用方法进行详细介绍

(1)public String extractMetadata (int keyCode)


方法描述:在 setDataSource()之后调用此方法。此方法检索与键值相关联的元数据值。当前支持的键代码被列为Meta DATAXXXX常量。使用任何其他值,它返回空指针



(2)public byte[] getEmbeddedPicture ()

方法描述:在 setDataSource()之后调用此方法。此方法找到与数据源相关联的可选图形或相册/封面艺术。如果有超过一张照片,(任何)其中一个被退还


(3)public Bitmap getFrameAtTime (long timeUs, int option)

方法介绍:在SETDATABORCEL()之后调用此方法。该方法通过考虑给定的选项,在给定的时间位置找到具有代表性的帧,并将其作为位图返回。这对于生成输入数据源的缩略图或在给定的时间位置获得和显示帧是有用的。

timeUs :帧将被检索的时间位置。当在给定的时间位置检索帧时,不能保证数据源具有位于该位置的帧。当这种情况发生时,附近的一个框架将被返回。如果TimeSo为负,则将忽略时间位置和选项,并且可以将实现视为代表的任何帧返回

option:关于如何找到框架的提示。如果希望检索一个具有比TimeS更早或相同的时间戳的同步帧,请使用opthyPyviousSyc。如果希望检索一个比TimeS晚于或相同的时间戳的同步帧,请使用opthyNXTySyc。如果想检索一个同步帧,它的时间戳与TimeS最接近或相同,则使用opthyLoestStSyc。如果希望检索一个可能是或可能不是同步帧但与TimeS最接近或相同的帧,则使用OpthOffice最接近。如果没有时间同步帧,OpTestIm最常用的性能开销与其他选项相比更大


(4)public Bitmap getFrameAtTime (long timeUs)

方法介绍:在SETDATABORCEL()之后调用此方法。如果可能的话,该方法找到一个接近给定时间位置的有代表性的帧,并将其作为位图返回。这对于生成输入数据源的缩略图是有用的。如果不关心帧是如何找到的,只要它接近给定的时间,调用这个方法;否则,请调用GETFrimeTimeTime

timeUs :帧将被检索的时间位置。当在给定的时间位置检索帧时,不能保证数据源具有位于该位置的帧。当这种情况发生时,附近的一个框架将被返回。如果TimeSo为负,则将忽略时间位置和选项,并且可以将实现视为代表的任何帧返回


(5)public Bitmap getFrameAtTime ()

方法介绍:在SETDATABORCEL()之后调用此方法。如果可能的话,该方法在任何时间位置找到一个有代表性的帧,并将其作为位图返回。这对于生成输入数据源的缩略图是有用的。如果不关心框架的位置,请调用此方法;否则,请调用GETFrimeTimeTime:(long)或GETFrimeTimeTime(long,int)


(6)public void release ()

方法介绍:当一个对象完成时调用它。此方法释放内存内部分配的内存


(7)public void setDataSource (FileDescriptor fd, long offset, long length)

fd 要播放的文件的文件描述符

offset 开始位置

length 结束位置


(8)public void setDataSource (String path)

 方法介绍:这个方法主要是设置media类型文件的路径,包括音视频等


(9)public void setDataSource (FileDescriptor fd)

 方法介绍:这个是是设置文件的描述符


(10)public void setDataSource (String uri, Map<String, String> headers)

方法介绍:设置网络音视频url地址,第二个参数是设置参数的请求头


(11)public void setDataSource (Context context, Uri uri)

方法介绍:设置网络media文件的url路径

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

MediaMetadataRetriever简单使用

(1)第一个案例:获取网络视频的第一帧图片


  public static Bitmap getBitmap(Context context,String url, boolean isSD) {

    Bitmap bitmap = null;

    //MediaMetadataRetriever 是android中定义好的一个类,提供了统一

    //的接口,用于从输入的媒体文件中取得帧和元数据;

    MediaMetadataRetriever retriever = new MediaMetadataRetriever();

    try {

        if (isSD){

            //()根据文件路径获取缩略图

            retriever.setDataSource(context, Uri.fromFile(new File(url)));

        }else {

            //根据网络路径获取缩略图

            retriever.setDataSource(url, new HashMap());

        }

        //获得第一帧图片

        bitmap = retriever.getFrameAtTime();

    } catch (IllegalArgumentException e) {

        e.printStackTrace();

    } finally {

        retriever.release();

    }

    return bitmap;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

(2)第二个案例:获取音频文件的时间:


` public static String getRingDuring(String mUri) {

    String duration = null;

    android.media.MediaMetadataRetriever mmr = new android.media.MediaMetadataRetriever();


    try {

        if (mUri != null) {

            HashMap<String, String> headers = null;

            if (headers == null) {

                headers = new HashMap<String, String>();

            }

            mmr.setDataSource(mUri, headers);

        }


        duration = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_DURATION);

    } catch (Exception ex) {

    } finally {

        mmr.release();

    }

    return duration;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

`

以上的这两个案例是获取网络url的信息,本地的获取方法在这里我就不做阐述了,是和上面的用法几乎一样


注意:获取网络url现在不支持https协议的获取


  • 2020-12-08 17:13:57

    nvm卸载、安装node和npm

    1、node.js、nvm、 npm (1)在cmd中输入`where node`找到node长须所在位置进行删除 (2)确保计算机-环境变量删除相关引用 (3)在cmd中输入`node -v` ,得到以下结果,删除成功

  • 2020-12-08 17:23:36

    Window下完全卸载删除Nodejs

    1.从卸载程序卸载程序和功能。 2.重新启动(或者您可能会从任务管理器中杀死所有与节点相关的进程)。 3.寻找这些文件夹并删除它们(及其内容)(如果还有)。根据您安装的版本,UAC设置和CPU架构,这些可能或可能不存在:

  • 2020-12-09 08:48:45

    nodejs版本以及其对应的npm版本

    正在寻找某个大版本的最新版? Node.js 10.x Node.js 8.x Node.js 6.x Node.js 4.x Node.js 0.12.x Node.js 0.10.x 所有版本

  • 2020-12-12 17:27:54

    手把手教你 GitLab 的安装及使用

    GitLab:是一个基于Git实现的在线代码仓库托管软件,你可以用gitlab自己搭建一个类似于Github一样的系统,一般用于在企业、学校等内部网络搭建git私服。