文档章节

Android开发 多媒体提取器MediaExtractor详解_入门篇

o
 osc_g8254g7s
发布于 2019/08/19 16:56
字数 1239
阅读 3
收藏 0

钉钉、微博极速扩容黑科技,点击观看阿里云弹性计算年度发布会!>>>

前言

  MediaExtractor字面意思是多媒体提取器,它在Android的音视频开发里主要负责提取视频或者音频中的信息和数据流(例如将视频文件,剥离出音频与视频).本章博客将讲解一些入门简单的东西.如何分别音频和视频轨道和获取视频里的一些信息.我将在其他章节里讲解其他MediaExtractor使用方法.

 

获取轨道

  在一个多媒体视频里,可以包含多个数据流(一般是视频与音频各一个,但是音频可以多个).我们需要先获取需要的数据轨道编号,才能后续的各种操作.所以使用MediaExtractor的第一步就是获取轨道.如下代码展示了获取轨道的方法.

列举所有轨道编码格式的Demo方法

private void trackDemo(){
        mFile = new File(getExternalCacheDir(),"demo.mp4");
        if (!mFile.exists()){
            Log.e(TAG, "mp4文件不存在");
            return;
        }
        MediaExtractor extractor = new MediaExtractor();//实例一个MediaExtractor
        try {
            extractor.setDataSource(mFile.getAbsolutePath());//设置添加MP4文件路径
        } catch (IOException e) {
            e.printStackTrace();
        }
        int count = extractor.getTrackCount();//获取轨道数量
        Log.e(TAG, "轨道数量 = "+count);
        for (int i = 0; i < count; i++){
            MediaFormat mediaFormat = extractor.getTrackFormat(0);
            Log.e(TAG, i+"编号通道格式 = "+mediaFormat.getString(MediaFormat.KEY_MIME));
        }

    }

上面的代码已经注释的很清楚了.注意! 实际项目里建议将这些操作放到线程中.

结果:

2019-08-19 17:08:21.197 18775-18775/demo.yt.com.demo E/测试Demo: 轨道数量 = 2
2019-08-19 17:08:21.198 18775-18775/demo.yt.com.demo E/测试Demo: 0编号通道格式 = video/avc
2019-08-19 17:08:21.198 18775-18775/demo.yt.com.demo E/测试Demo: 1编号通道格式 = audio/mp4a-latm

从结果可以看到,这个demo.mp4视频文件有2个轨道数量,一个是视频流的轨道,一个是音频流的轨道.

通过编码格式字符串对比获取指定轨道的方法

private Integer getTrackIndex(String targetTrack) {
        MediaExtractor extractor = new MediaExtractor();//实例一个MediaExtractor
        try {
            extractor.setDataSource(mFile.getAbsolutePath());//设置添加MP4文件路径
        } catch (IOException e) {
            e.printStackTrace();
        }
        Integer trackIndex = null;
        int count = extractor.getTrackCount();//获取轨道数量
        for (int i = 0; i < count; i++) {
            MediaFormat mediaFormat = extractor.getTrackFormat(i);
            String currentTrack = mediaFormat.getString(MediaFormat.KEY_MIME);
            if (currentTrack.startsWith(targetTrack)) {
                trackIndex = i;
                break;
            }
        }
        return trackIndex;

    }
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_extractor);
        mFile = new File(getExternalCacheDir(), "demo.mp4");
        int index = getTrackIndex("video/");
        Log.e(TAG, "onCreate: index = " + index);

    }

 

提取视频数据信息

从MediaFormat里获取数据信息

  在上面的获取轨道的代码里我们,可以看到使用MediaFormat可以获取当前轨道的编码格式.除了获取编码格式我们还能获取到很多其他信息.这里我们将会一一列出,但是视频里的一些数据是肯定可以获取到的,而一些其他数据是需要看视频是否携带这些这些数据,如果未携带操作获取这些数据会抛出空指针错误.

  基本可以获取到的信息

  1.获取MIME信息,上面也有已经演示过了

MediaFormat mediaFormat = extractor.getTrackFormat(0);//获取多媒体格式,因为是demo已经确定自己的视频文件没问题,所以直接获取0位轨道
String mimeFormat = mediaFormat.getString(MediaFormat.KEY_MIME);//获取MIME格式内容
Log.e(TAG, "mediaExtractor: 获取MIME格式内容="+mimeFormat);

  2.获取语言格式(大多数情况是获取到空的字符串,但是至少不会报null)

MediaFormat mediaFormat = extractor.getTrackFormat(0);
String language = mediaFormat.getString(MediaFormat.KEY_LANGUAGE);//获取语言格式内容
Log.e(TAG, "mediaExtractor: 获取语言格式内容="+language);

   3.视频的高度与宽度

MediaFormat mediaFormat = extractor.getTrackFormat(0);
int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);//获取高度
int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);//获取高度

  4.播放总时长

long durationTime = mediaFormat.getLong(MediaFormat.KEY_DURATION);//总时间

  5.获取MediaFormat描述的数据缓冲区的最大字节数的键

int maxByteCount = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);//获取视频缓存输出的最大大小

  

不确定可以获取到的信息

  1.获取采样率

int sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);//获取采样率

  2.获取比特率

int bitRate = mediaFormat.getInteger(MediaFormat.KEY_BIT_RATE);//获取比特

  3.获取声道数量

int channelCount = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);//获取声道数量

  4.获取最大高度与最大宽度

int maxWidth = mediaFormat.getInteger(MediaFormat.KEY_MAX_WIDTH);//最大宽度
int maxHeight = mediaFormat.getInteger(MediaFormat.KEY_MAX_HEIGHT);//最大高度

  5.获取颜色格式

int colorFormat = mediaFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);//颜色格式

  6.获取帧率

int frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE);//帧率

  7.获取图块的高度与宽度

int tileWidth = mediaFormat.getInteger(MediaFormat.KEY_TILE_WIDTH);//图块分辨率
int tileHeight = mediaFormat.getInteger(MediaFormat.KEY_TILE_HEIGHT);//图块分辨率

  8.获取网格行

int gridRows = mediaFormat.getInteger(MediaFormat.KEY_GRID_ROWS);//网格行

  9.获取网格列

int gridColumns = mediaFormat.getInteger(MediaFormat.KEY_GRID_COLUMNS);//网格列

  10.PCM-编码 模拟信号编码

int pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);//PCM-编码 模拟信号编码

  11.捕获率

float captureRate = mediaFormat.getFloat(MediaFormat.KEY_CAPTURE_RATE);//捕获率

  12.是否是AAS

int isAdts = mediaFormat.getInteger(MediaFormat.KEY_IS_ADTS);

 

API列表

  • setDataSource(String path):即可以设置本地文件又可以设置网络文件
  • getTrackCount():得到源文件通道数
  • getTrackFormat(int index):获取指定(index)的通道格式
  • getSampleTime():返回当前的时间戳
  • readSampleData(ByteBuffer byteBuf, int offset):把指定通道中的数据按偏移量读取到ByteBuffer中;
  • advance():读取下一帧数据
  • release(): 读取结束后释放资源
 
end
上一篇: jvm(n):JVM面试
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

SO_REUSEADDR和SO_REUSEPORT有何不同? - How do SO_REUSEADDR and SO_REUSEPORT differ?

问题: The man pages and programmer documentations for the socket options SO_REUSEADDR and SO_REUSEPORT are different for different operating systems and often highly confusing.......

法国红酒甜
25分钟前
28
0
asp.net core之SignalR

SignalR 是什么? ASP.NET Core SignalR 是一个开源的实时框架,它简化了向应用中添加实时 Web 功能的过程。 实时 Web 功能是服务器端能够即时的将数据推送到客户端,而无需让服务器等待客户端...

一介草民Coder
56分钟前
24
0
如何通过日期属性对数组进行排序 - How to sort an array by a date property

问题: Say I have an array of a few objects: 说我有一些对象的数组: var array = [{id: 1, date: Mar 12 2012 10:00:00 AM}, {id: 2, date: Mar 8 2012 08:00:00 AM}]; How can I sort......

javail
今天
22
0
技术教程| 百度鹰眼历史轨迹查询:轨迹抽稀功能

本文作者:用****9 本篇教程中,我们将详细地说明鹰眼历史轨迹查询(gettrack接口)中,如何通过vacuate_grade选项对轨迹进行抽稀,以及不同的抽稀力度对轨迹产生的影响。 上一篇教程中,我们...

百度开发者中心
前天
24
0
Quartz的Misfire处理规则 错过任务执行时间的处理机制

调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 CronTrigger withMisfireHandlingInstructionDoNothing ——不触发立即执行 ——等待下次Cron触发频率...

独钓渔
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部