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协议的获取


  • 2019-05-13 14:34:42

    linux系统中清理MySql的日志文件,打印日志文件

    默认情况下mysql会一直保留mysql-bin文件,这样到一定时候,磁盘可能会被撑满,这时候是否可以删除这些文件呢,是否可以安全删除,是个问题。 首先要说明一下,这些文件都是mysql的日志文件,如果不做主从复制的话,基本上是没用的,虽然没用,但是不建议使用rm命令删除,这样有可能会不安全,正确的方法是通过mysql的命令去删除。

  • 2019-05-14 16:47:27

    数据库整理碎片

    最后还是用的ALTER TABLE来修改的,不知道为什么有时候管用,有时候不管用。

  • 2019-05-17 16:27:26

    在vue项目里面使用引入公共方法

    今天早上来到公司,没事看了一下别人的博客,然后试了一下,发现的确是可以的,在此记录一下,方便自己日后查阅。 首先新建一个文件夹:commonFunction ,然后在里面建立 一个文件common.js

  • 2019-05-18 12:37:39

    Android夜间模式的实现方案

    对于一款阅读类的软件,夜间模式是不可缺少的。最初看到这个需求时候觉得无从下手,没有一点头绪。后来通过查阅资料发现Android官方在Support Library 23.2.0中已经加入了夜间主题。也就是只需要通过更换主题便可实现日间模式和夜间模式的切换。下面截取项目实现的夜间模式效果图:

  • 2019-05-18 12:38:41

    android 快速实现夜间模式

    最近项目中遇到了一个问题,夜间模式在8.0以上的手机中不起作用,查看了一下原因,是夜间模式实现方法的问题。分两种情况介绍一下

  • 2019-05-18 12:40:35

    Android夜间模式的几种实现

    通过增加一层遮光罩来实现。效果不是很理想,但是好用,毕竟很多手机都有自己的夜间模式了

  • 2019-05-19 02:25:15

    php使用TCPDF生成PDF文件教程

    orientation属性用来设置文档打印格式是“Portrait”还是“Landscape”。 Landscape为横式打印,Portrait为纵向打印

  • 2019-05-21 11:46:05

    RecyclerView 加动画的坑

    然后加到recyclerView上,我是在adapter上加的。Adapter的holder复用相信大家也都很熟悉了,这个在绘制效率的提高上很重要,也很容易发现一个问题,就是内容混乱的复用。所以常见的处理就是对view加上tag来多次判断,对于visibility之类的设置一定是if...else的写法,光有if是不可以的。

  • 2019-05-21 11:54:10

    Android中如何设置字体大小

    首先要强调一点,某些用户可能存在视力障碍甚至几近失明,他们无法顺利阅读一般尺寸下的文字内容。Android操作系统意识到了这些情况,并提供了一套显示辅助功能,使得用户可以根据自己的使用习惯随意缩放设备中文本字体的大小。 要在设备上修改字体设定,首先启用“设定”应用,然后选择“显示”项下的“字体尺寸”。用户可以在设备预置的四种文本字体尺寸中选择适合自己的方案(包含小、正常、大、超大),详见图一。