前言

  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

Android开发 多媒体提取器MediaExtractor详解_入门篇的更多相关文章

  1. Android开发 多媒体提取器MediaExtractor详解_将一个视频文件分离视频与音频

    前言 此篇博客讲解MediaExtractor将一个视频文件分离视频与音频,如果你对MediaExtractor还没有一个笼统的概念建议先了解我的另一篇入门博客:https://www.cnblogs ...

  2. Android开发:文本控件详解——TextView(一)基本属性

    一.简单实例: 新建的Android项目初始自带的Hello World!其实就是一个TextView. 在activity_main.xml中可以新建TextView,从左侧组件里拖拽到右侧预览界面 ...

  3. Android开发:文本控件详解——TextView(二)文字跑马灯效果实现

    一.需要使用的属性: 1.android:ellipsize 作用:若文字过长,控制该控件如何显示. 对于同样的文字“Android开发:文本控件详解——TextView(二)文字跑马灯效果实现”,不 ...

  4. 『动善时』JMeter基础 — 35、JMeter接口关联【JSON提取器】详解

    目录 1.JSON提取器介绍 2.JSON提取器界面详解 3.JSON提取器的使用 (1)测试计划内包含的元件 (2)HTTP Cookie管理器内容 (3)用户登陆请求界面内容 (4)JSON提取器 ...

  5. Android开发数据存储之ContentProvider详解

    转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可 ...

  6. 转: Android开发中的MVP架构详解(附加链接比较不错)

    转: http://www.codeceo.com/article/android-mvp-artch.html 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解M ...

  7. Android开发5大布局方式详解

    Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...

  8. Jmeter中正则表达式提取器使用详解

    在使用Jmeter过程中,会经常使用到正则表达式提取器提取器,虽然并不直接涉及到请求的测试,但是对于数据的传递起着很大的作用,本篇博文就是主要讲解关于正则表达式及其在Jmeter的Sampler中的调 ...

  9. 【转】three.js详解之入门篇

    原文链接:https://www.cnblogs.com/shawn-xie/archive/2012/08/16/2642553.html   开场白 webGL可以让我们在canvas上实现3D效 ...

随机推荐

  1. 在linux中的rpm -ivh 是干什么的呢?

    在linux中的rpm -ivh 是干什么的呢?   RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以了.这种软件安装包通常是一个RPM包(Redhat Linux Packet ...

  2. 关于CoreData的一个工具Mogenerator的使用

    最近看到用CoreData时使用的工具Mogenerator,发现网上介绍其具体使用的不多,特此简单整理一下, 关于CoreData这里就不具体说了,使用就用MagicalRecord,用起来真是太方 ...

  3. 牛客多校第六场 G Is Today Friday? 蔡勒公式/排列

    题意: 有一堆日期,这些日期都是星期五,但是数字被映射成了字母A~J,现在让你求逆映射,如果存在多种答案,输出字典序最小的那个. 题解: 用蔡勒公式解决关于星期几的问题. 对于映射,可以用笔者刚刚学会 ...

  4. 转-C/C++ new与malloc区别

    1.属性 new/delete是C++关键字,需要编译器支持.malloc/free是库函数,需要头文件支持. 2.参数 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计 ...

  5. RoadFlowCore 解决方案介绍及开发概述

    RoadFlow解决方案如下: RoadFlow.Business:业务层 RoadFlow.Integrate:组织机构获取层(如果你系统要使用第三方组织架构的时候修改这里面的方法即可) RoadF ...

  6. Springboot-WebSocket获取HttpSession问题

    换了新工作,第一个任务就是和这个有关,以前没接触过,没办法,各种度娘.谷哥,大部分都是只言片语,要么就是特定的配置环境还不贴配置--,踩坑无数, 遂整理成笔记 WebSocket协议 WebSocke ...

  7. mssql查询表在哪个数据库中

    mssql查询表在哪个数据库中 EXEC sp_MSforeachdb @command1='IF object_id(''?'' + ''..表名'') IS NOT NULL PRINT ''?' ...

  8. 9.ActiveMQ理论

    一.首先说下什么是消息队列? 1.消息队列是在消息的传输过程中保存消息的容器. 二.为什么要用到消息队列? 主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的inse ...

  9. vue3+node全栈项目部署到云服务器

    一.前言 最近在B站学习了一下全栈开发,使用到的技术栈是Vue+Element+Express+MongoDB,为了让自己学的第一个全栈项目落地,于是想着把该项目部署到阿里云服务器.经过网上一番搜索和 ...

  10. 笔记23 搭建Spring MVC

    搭建一个最简单的SpringMVC示例 1.配置DispatcherServlet DispatcherServlet是Spring MVC的核心.在这里请求会第一次 接触到框架,它要负责将请求路由到 ...